private bool IsInstanceReuseable(FstInstance inst) { return(inst.State.Arcs.All(a => !a.Input.IsEpsilon)); }
public override IEnumerable <FstResult <TData, TOffset> > Traverse(ref Annotation <TOffset> ann, NullableValue <TOffset>[,] initRegisters, IList <TagMapCommand> initCmds, ISet <Annotation <TOffset> > initAnns) { Stack <FstInstance> instStack = InitializeStack(ref ann, initRegisters, initCmds, initAnns); var curResults = new List <FstResult <TData, TOffset> >(); while (instStack.Count != 0) { FstInstance inst = instStack.Pop(); if (inst.Annotation != null) { VariableBindings varBindings = null; foreach (Arc <TData, TOffset> arc in inst.State.Arcs) { if (arc.Input.IsEpsilon) { TData output = inst.Output; IDictionary <Annotation <TOffset>, Annotation <TOffset> > mappings = inst.Mappings; Queue <Annotation <TOffset> > queue = inst.Queue; NullableValue <TOffset>[,] registers = inst.Registers; if (IsInstanceReuseable(inst)) { if (varBindings == null) { varBindings = inst.VariableBindings; } } else { registers = (NullableValue <TOffset> [, ])inst.Registers.Clone(); output = inst.Output.DeepClone(); Dictionary <Annotation <TOffset>, Annotation <TOffset> > outputMappings = inst.Output.Annotations.SelectMany(a => a.GetNodesBreadthFirst()) .Zip(output.Annotations.SelectMany(a => a.GetNodesBreadthFirst())).ToDictionary(t => t.Item1, t => t.Item2); mappings = inst.Mappings.ToDictionary(kvp => kvp.Key, kvp => outputMappings[kvp.Value]); queue = new Queue <Annotation <TOffset> >(inst.Queue); if (varBindings == null) { varBindings = inst.VariableBindings.DeepClone(); } } ExecuteOutputs(arc.Outputs, output, mappings, queue); instStack.Push(EpsilonAdvanceFst(inst.Annotation, registers, output, mappings, queue, varBindings, arc, curResults)); varBindings = null; } else { if (varBindings == null) { varBindings = IsInstanceReuseable(inst) ? inst.VariableBindings : inst.VariableBindings.DeepClone(); } if (CheckInputMatch(arc, inst.Annotation, varBindings)) { TData output = inst.Output; IDictionary <Annotation <TOffset>, Annotation <TOffset> > mappings = inst.Mappings; Queue <Annotation <TOffset> > queue = inst.Queue; if (!IsInstanceReuseable(inst)) { output = inst.Output.DeepClone(); Dictionary <Annotation <TOffset>, Annotation <TOffset> > outputMappings = inst.Output.Annotations.SelectMany(a => a.GetNodesBreadthFirst()) .Zip(output.Annotations.SelectMany(a => a.GetNodesBreadthFirst())).ToDictionary(t => t.Item1, t => t.Item2); mappings = inst.Mappings.ToDictionary(kvp => kvp.Key, kvp => outputMappings[kvp.Value]); queue = new Queue <Annotation <TOffset> >(inst.Queue); } for (int i = 0; i < arc.Input.EnqueueCount; i++) { queue.Enqueue(inst.Annotation); } ExecuteOutputs(arc.Outputs, output, mappings, queue); foreach (FstInstance ni in AdvanceFst(inst.Annotation, inst.Registers, output, mappings, queue, varBindings, arc, curResults)) { instStack.Push(ni); } break; } } } } } return(curResults); }
private bool IsInstanceReuseable(FstInstance inst) { return(inst.State.Arcs.Count <= 1); }