//////////////////////////////////////////////////////////////////////////// public override VCExpr Visit(VCExprQuantifier node, VariableBindings oldBindings) { Contract.Requires(oldBindings != null); Contract.Requires(node != null); Contract.Ensures(Contract.Result <VCExpr>() != null); VariableBindings /*!*/ bindings = oldBindings.Clone(); // bound term variables are replaced with bound term variables // typed in a simpler way List <VCExprVar /*!*/> /*!*/ newBoundVars = BoundVarsAfterErasure(node.BoundVars, bindings); // type variables are replaced with ordinary quantified variables GenBoundVarsForTypeParams(node.TypeParameters, newBoundVars, bindings); VCExpr /*!*/ newNode = HandleQuantifier(node, newBoundVars, bindings); Contract.Assert(newNode != null); if (!(newNode is VCExprQuantifier) || !IsUniversalQuantifier(node)) { return(newNode); } VariableBindings /*!*/ bindings2; if (!RedoQuantifier(node, (VCExprQuantifier)newNode, node.BoundVars, oldBindings, out bindings2, out newBoundVars)) { return(newNode); } GenBoundVarsForTypeParams(node.TypeParameters, newBoundVars, bindings2); return(HandleQuantifier(node, newBoundVars, bindings2)); }
protected IEnumerable <TInst> Initialize(ref int annIndex, Register <TOffset>[,] registers, IList <TagMapCommand> cmds, ISet <int> initAnns) { var insts = new List <TInst>(); TOffset offset = _annotations[annIndex].Range.GetStart(_fst.Direction); if (_startAnchor) { for (int i = annIndex; i < _annotations.Count && _annotations[i].Range.GetStart(_fst.Direction).Equals(offset); i++) { if (_annotations[i].Optional) { int nextIndex = GetNextNonoverlappingAnnotationIndex(i); if (nextIndex != _annotations.Count) { insts.AddRange(Initialize(ref nextIndex, (Register <TOffset> [, ])registers.Clone(), cmds, initAnns)); } } } } ExecuteCommands(registers, cmds, new Register <TOffset>(offset, true), new Register <TOffset>()); for (; annIndex < _annotations.Count && _annotations[annIndex].Range.GetStart(_fst.Direction).Equals(offset); annIndex++) { if (!initAnns.Contains(annIndex)) { TInst inst = GetCachedInstance(); inst.State = _fst.StartState; inst.AnnotationIndex = annIndex; Array.Copy(registers, inst.Registers, registers.Length); if (!_fst.IgnoreVariables) { inst.VariableBindings = _varBindings != null?_varBindings.Clone() : new VariableBindings(); } insts.Add(inst); initAnns.Add(annIndex); } } return(insts); }
//////////////////////////////////////////////////////////////////////////// public override VCExpr Visit(VCExprQuantifier node, VariableBindings oldBindings) { Contract.Requires(oldBindings != null); Contract.Requires(node != null); Contract.Ensures(Contract.Result<VCExpr>() != null); VariableBindings bindings = oldBindings.Clone(); // determine the bound vars that actually occur in the body or // in any of the triggers (if some variables do not occur, we // need to take special care of type parameters that only occur // in the types of such variables) FreeVariableCollector coll = new FreeVariableCollector(); coll.Collect(node.Body); foreach (VCTrigger trigger in node.Triggers) { if (trigger.Pos) foreach (VCExpr/*!*/ e in trigger.Exprs) { Contract.Assert(e != null); coll.Collect(e); } } List<VCExprVar/*!*/> occurringVars = new List<VCExprVar/*!*/>(node.BoundVars.Count); foreach (VCExprVar var in node.BoundVars) if (coll.FreeTermVars.ContainsKey(var)) occurringVars.Add(var); occurringVars.TrimExcess(); // bound term variables are replaced with bound term variables typed in // a simpler way List<VCExprVar/*!*/>/*!*/ newBoundVars = BoundVarsAfterErasure(occurringVars, bindings); Contract.Assert(cce.NonNullElements(newBoundVars)); VCExpr/*!*/ newNode = HandleQuantifier(node, occurringVars, newBoundVars, bindings); Contract.Assert(newNode != null); if (!(newNode is VCExprQuantifier) || !IsUniversalQuantifier(node)) return newNode; VariableBindings bindings2; if (!RedoQuantifier(node, (VCExprQuantifier)newNode, occurringVars, oldBindings, out bindings2, out newBoundVars)) return newNode; return HandleQuantifier(node, occurringVars, newBoundVars, bindings2); }
//////////////////////////////////////////////////////////////////////////// public override VCExpr Visit(VCExprQuantifier node, VariableBindings oldBindings) { Contract.Requires(oldBindings != null); Contract.Requires(node != null); Contract.Ensures(Contract.Result<VCExpr>() != null); VariableBindings/*!*/ bindings = oldBindings.Clone(); // bound term variables are replaced with bound term variables // typed in a simpler way List<VCExprVar/*!*/>/*!*/ newBoundVars = BoundVarsAfterErasure(node.BoundVars, bindings); // type variables are replaced with ordinary quantified variables GenBoundVarsForTypeParams(node.TypeParameters, newBoundVars, bindings); VCExpr/*!*/ newNode = HandleQuantifier(node, newBoundVars, bindings); Contract.Assert(newNode != null); if (!(newNode is VCExprQuantifier) || !IsUniversalQuantifier(node)) return newNode; VariableBindings/*!*/ bindings2; if (!RedoQuantifier(node, (VCExprQuantifier)newNode, node.BoundVars, oldBindings, out bindings2, out newBoundVars)) return newNode; GenBoundVarsForTypeParams(node.TypeParameters, newBoundVars, bindings2); return HandleQuantifier(node, newBoundVars, bindings2); }
protected IEnumerable <TInst> Advance(TInst inst, VariableBindings varBindings, Arc <TData, TOffset> arc, ICollection <FstResult <TData, TOffset> > curResults, bool optional = false) { if (inst.Priorities != null) { inst.Priorities.Add(arc.Priority); } int nextIndex = GetNextNonoverlappingAnnotationIndex(inst.AnnotationIndex); TOffset nextOffset; bool nextStart; if (nextIndex < _annotations.Count) { nextOffset = _annotations[nextIndex].Range.GetStart(_fst.Direction); nextStart = true; } else { nextOffset = _data.Annotations.GetLast(_fst.Direction, _fst.Filter).Range.GetEnd(_fst.Direction); nextStart = false; } TOffset end = _annotations[inst.AnnotationIndex].Range.GetEnd(_fst.Direction); if (nextIndex < _annotations.Count) { var anns = new List <int>(); bool cloneOutputs = false; for (int i = nextIndex; i < _annotations.Count && _annotations[i].Range.GetStart(_fst.Direction).Equals(nextOffset); i++) { if (_annotations[i].Optional) { TInst ti = CopyInstance(inst); ti.AnnotationIndex = i; foreach (TInst ni in Advance(ti, varBindings, arc, curResults, true)) { yield return(ni); cloneOutputs = true; } } anns.Add(i); } ExecuteCommands(inst.Registers, arc.Commands, new Register <TOffset>(nextOffset, nextStart), new Register <TOffset>(end, false)); if (!optional || _endAnchor) { CheckAccepting(nextIndex, inst.Registers, inst.Output, varBindings, arc, curResults, inst.Priorities); } inst.State = arc.Target; bool first = true; foreach (int curIndex in anns) { TInst ni = first ? inst : CopyInstance(inst); ni.AnnotationIndex = curIndex; if (varBindings != null) { inst.VariableBindings = cloneOutputs ? varBindings.Clone() : varBindings; } yield return(ni); cloneOutputs = true; first = false; } } else { ExecuteCommands(inst.Registers, arc.Commands, new Register <TOffset>(nextOffset, nextStart), new Register <TOffset>(end, false)); CheckAccepting(nextIndex, inst.Registers, inst.Output, varBindings, arc, curResults, inst.Priorities); inst.State = arc.Target; inst.AnnotationIndex = nextIndex; inst.VariableBindings = varBindings; yield return(inst); } }
private void CheckAccepting(int annIndex, Register <TOffset>[,] registers, TData output, VariableBindings varBindings, Arc <TData, TOffset> arc, ICollection <FstResult <TData, TOffset> > curResults, IList <int> priorities) { if (arc.Target.IsAccepting && (!_endAnchor || annIndex == _annotations.Count)) { Annotation <TOffset> ann = annIndex < _annotations.Count ? _annotations[annIndex] : _data.Annotations.GetEnd(_fst.Direction); var matchRegisters = (Register <TOffset> [, ])registers.Clone(); ExecuteCommands(matchRegisters, arc.Target.Finishers, new Register <TOffset>(), new Register <TOffset>()); if (arc.Target.AcceptInfos.Count > 0) { foreach (AcceptInfo <TData, TOffset> acceptInfo in arc.Target.AcceptInfos) { TData resOutput = output; var cloneable = resOutput as ICloneable <TData>; if (cloneable != null) { resOutput = cloneable.Clone(); } var candidate = new FstResult <TData, TOffset>(_fst.RegistersEqualityComparer, acceptInfo.ID, matchRegisters, resOutput, varBindings == null ? null : varBindings.Clone(), acceptInfo.Priority, arc.Target.IsLazy, ann, priorities == null ? null : priorities.ToArray(), curResults.Count); if (acceptInfo.Acceptable == null || acceptInfo.Acceptable(_data, candidate)) { curResults.Add(candidate); } } } else { TData resOutput = output; var cloneable = resOutput as ICloneable <TData>; if (cloneable != null) { resOutput = cloneable.Clone(); } curResults.Add(new FstResult <TData, TOffset>(_fst.RegistersEqualityComparer, null, matchRegisters, resOutput, varBindings == null ? null : varBindings.Clone(), -1, arc.Target.IsLazy, ann, priorities == null ? null : priorities.ToArray(), curResults.Count)); } } }