def lattice_to_dfa(lattice: pynini.Fst, optimal_only: bool, state_multiplier: int = 4) -> pynini.Fst: """Constructs a (possibly pruned) weighted DFA of output strings. Given an epsilon-free lattice of output strings (such as produced by rewrite_lattice), attempts to determinize it, pruning non-optimal paths if optimal_only is true. This is valid only in a semiring with the path property. To prevent unexpected blowup during determinization, a state threshold is also used and a warning is logged if this exact threshold is reached. The threshold is a multiplier of the size of input lattice (by default, 4), plus a small constant factor. This is intended by a sensible default and is not an inherently meaningful value in and of itself. Args: lattice: Epsilon-free non-deterministic finite acceptor. optimal_only: Should we only preserve optimal paths? state_multiplier: Max ratio for the number of states in the DFA lattice to the NFA lattice; if exceeded, a warning is logged. Returns: Epsilon-free deterministic finite acceptor. """ weight_type = lattice.weight_type() weight_threshold = ( pynini.Weight.one(weight_type) if optimal_only else pynini.Weight.zero(weight_type)) state_threshold = 256 + state_multiplier * lattice.num_states() lattice = pynini.determinize( lattice, nstate=state_threshold, weight=weight_threshold) if lattice.num_states() == state_threshold: logging.warning("Unexpected hit state threshold; consider a higher value " "for state_multiplier") return lattice
def threshold_lattice_to_dfa(lattice: pynini.Fst, threshold: float = 1.0, state_multiplier: int = 2) -> pynini.Fst: """Constructs a (possibly pruned) weighted DFA of output strings. Given an epsilon-free lattice of output strings (such as produced by rewrite_lattice), attempts to determinize it, pruning non-optimal paths if optimal_only is true. This is valid only in a semiring with the path property. To prevent unexpected blowup during determinization, a state threshold is also used and a warning is logged if this exact threshold is reached. The threshold is a multiplier of the size of input lattice (by default, 4), plus a small constant factor. This is intended by a sensible default and is not an inherently meaningful value in and of itself. Parameters ---------- lattice: :class:`~pynini.Fst` Epsilon-free non-deterministic finite acceptor. threshold: float Threshold for weights, 1.0 is optimal only, 0 is for all paths, greater than 1 prunes the lattice to include paths with costs less than the optimal path's score times the threshold state_multiplier: int Max ratio for the number of states in the DFA lattice to the NFA lattice; if exceeded, a warning is logged. Returns ------- :class:`~pynini.Fst` Epsilon-free deterministic finite acceptor. """ weight_type = lattice.weight_type() weight_threshold = pynini.Weight(weight_type, threshold) state_threshold = 256 + state_multiplier * lattice.num_states() lattice = pynini.determinize(lattice, nstate=state_threshold, weight=weight_threshold) return lattice
def all_suffixes(self, fsa: pynini.Fst) -> pynini.Fst: fsa = fsa.copy() start_state = fsa.start() for s in fsa.states(): fsa.add_arc( start_state, pynini.Arc(0, 0, pynini.Weight.one(fsa.weight_type()), s)) return fsa.optimize()