/// <summary> /// Computes the ratio of two dfas /// </summary> /// <returns>size of dfa2/ size of dfa1</returns> internal static double GetDFARatio(Automaton<BDD> dfa1, Automaton<BDD> dfa2, HashSet<char> al, CharSetSolver solver, bool isSolDense) { var n = dfa1.StateCount; double multiplier = 3; int k = Math.Min(13, (int)(n * multiplier)); int finalDivider = k; double[] paths1 = GetPathsUpToN(dfa1, al, solver, k); double[] paths2 = GetPathsUpToN(dfa2, al, solver, k); double sum = 0; for (int i = 0; i <= k; i++) { //TODO check grading still works double divider = Math.Min(paths1[i], Math.Pow(al.Count, i) - paths1[i]); if (divider != 0) sum += (paths2[i] / divider); else { sum += paths2[i]; if (paths2[i] == 0) finalDivider--; } } return sum / (finalDivider + 1); }
public State(State[] states, string regexPattern, bool isAcceptedState, Automaton automaton) { this.automaton = automaton; this.states = states == null ? null : new List<State>(states); this.pattern = regexPattern; this.isAcceptedState = isAcceptedState; }
public void PlaySound(Automaton owner) { if (template.UseSFX > 0) { owner.PlaySound(template.UseSFX); } }
/// <summary> /// Create a new AutomatonQuery from an <seealso cref="Automaton"/>. /// </summary> /// <param name="term"> Term containing field and possibly some pattern structure. The /// term text is ignored. </param> /// <param name="automaton"> Automaton to run, terms that are accepted are considered a /// match. </param> public AutomatonQuery(Term term, Automaton automaton) : base(term.Field) { this.Term = term; this.Automaton_Renamed = automaton; this.Compiled = new CompiledAutomaton(automaton); }
public CommandSet(Automaton owner, int capacity, bool autoFire, CommandSet pipe) { this.owner = owner; this.capacity = capacity; this.queue = new List<Command>(); this.pipe = pipe; }
public MoveSequence(string regex) { solver = new CharSetSolver(BitWidth.BV7); moveAutomaton = solver.Convert("^(" + regex + ")$").Determinize(solver).Minimize(solver); currentState = 0; //solver.ShowGraph(moveAutomaton, "D"); //ComputeDeadStates(); }
public readonly long elapsedTime; // in milliseconds //public readonly double densityDiffAverage, densityDifferenceDeviation; //public readonly double editDistanceAverage, editDistanceDeviation; public MeasurementResultSet(PDLPred originalFormula, IEnumerable<PDLPred> generatedFormulas, long time, VariableCache.ConstraintMode constraintmode, PdlFilter.Filtermode filtermode, HashSet<char> alphabet, IDictionary<PDLPred, SingleMeasurementResult> cache, IDictionary<Automaton<BDD>, SingleMeasurementResult> automatonCache) { this.originalFormula = originalFormula; this.alphabet = alphabet; this.originalAutomaton = originalFormula.GetDFA(alphabet, new CharSetSolver()); this.constraintmode = constraintmode; this.filtermode = filtermode; this.elapsedTime = time; this.results = new List<SingleMeasurementResult>(); foreach (PDLPred generatedFormula in generatedFormulas) { SingleMeasurementResult result; if (cache.ContainsKey(generatedFormula)) { result = cache[generatedFormula]; } else { result = SingleMeasurementResult.Create(this.originalAutomaton, generatedFormula, this.alphabet, automatonCache); cache[generatedFormula] = result; } this.results.Add(result); } // Compute statistics /* double densityDiffSum = 0; int editDistanceSum = 0; foreach (SingleMeasurementResult result in this.results) { densityDiffSum += result.densityDiff; editDistanceSum += result.editDistance; } this.densityDiffAverage = ((double)densityDiffSum) / ((double)this.results.Count); this.editDistanceAverage = ((double)editDistanceSum) / ((double)this.results.Count); double densityDiffDeviation = 0; double editDistanceDeviation = 0; foreach (SingleMeasurementResult result in this.results) { densityDiffDeviation += Math.Pow(result.densityDiff - this.densityDiffAverage, 2.0); editDistanceDeviation += Math.Pow(((double)result.editDistance) - this.editDistanceAverage, 2.0); } densityDiffDeviation /= this.results.Count; densityDiffDeviation = Math.Sqrt(densityDiffDeviation); editDistanceDeviation /= this.results.Count; editDistanceDeviation = Math.Sqrt(editDistanceDeviation); */ }
public CSharpGenerator(Automaton<BDD> automaton, CharSetSolver solver, string classname, string namespacename, bool OptimzeForAsciiInput = true) { this.solver = solver; this.automaton = automaton; this.namespacename = namespacename; this.classname = classname; ASCII = solver.MkCharSetFromRange('\0', '\x7F'); helper_predicates = new HelperPredicates(solver, OptimzeForAsciiInput); }
static bool IsPuzzleReady(Automaton firer) { if (firer is HeroCharacter) { PuzzlePanel puzzle = (firer as HeroCharacter).puzzlePanel; return puzzle.IsReadyToBlockTrans(); } return true; }
private static void PrintDFA(Automaton<BDD> dfa, string name, HashSet<char> al) { var sb = new StringBuilder(); DFAUtilities.printDFA(dfa, al, sb); System.IO.StreamWriter file = new System.IO.StreamWriter(@"../../../TestPDL/DFAs/" + name + ".txt"); file.WriteLine(sb); file.Close(); }
/// <summary> /// /// </summary> /// <returns></returns> public NFAEditScript GetNFAOptimalEdit(Automaton<BDD> nfa2) { NFAEditScript editScript = new NFAEditScript(); //Start timer sw.Start(); //Normalize NFAs var normNfaPair = DFAUtilities.normalizeDFA(nfa2); var normNfa2 = normNfaPair.First; var stateNamesMapping = normNfaPair.Second; NFAEditScript bestScript = new NFAEditScript(); bestScript.script = null; // increase depth up to maxMoves for (int depth = 1; true; depth++) { var editList = new List<NFAEdit>(); if(GetNFAEditScriptTimeout( depth, -1, normNfa2, editScript.script, editScript.GetCost(), bestScript)) { // if hits timeout break and return null break; } if (bestScript.script != null) { bestScript.script.Reverse(); sw.Stop(); var mappedEditList = new List<NFAEdit>(); //fix states name because of normalization foreach (var edit in bestScript.script) { NFAEdit mappedEdit = null; if(edit is NFAEditState){ var castEdit = edit as NFAEditState; mappedEdit = new NFAEditState(stateNamesMapping[castEdit.state], castEdit.makeFinal); } if(edit is NFAEditMove){ var castEdit = edit as NFAEditMove; mappedEdit = new NFAEditMove( stateNamesMapping[castEdit.sourceState], stateNamesMapping[castEdit.newTargetState], castEdit.ch); } mappedEditList.Add(mappedEdit); } return bestScript; } } return null; }
/// <summary> /// Returns the minimum PDL edit distance ratio between all the PDL A1 and A2 inferred for dfa1 and dfa2 /// in less than timeout. For every min_ij(d(A1i,A2j)/|A1i) /// </summary> /// <param name="dfa1"></param> /// <param name="dfa2"></param> /// <param name="al"></param> /// <param name="solver"></param> /// <param name="timeout"></param> /// <returns></returns> public static double GetMinimalFormulaEditDistanceRatio(Automaton<BDD> dfa1, Automaton<BDD> dfa2, HashSet<char> al, CharSetSolver solver, long timeout, PDLEnumerator pdlEnumerator) { var v = GetMinimalFormulaEditDistanceTransformation(dfa1, dfa2, al, solver, timeout, pdlEnumerator); if(v!=null){ var transformation = v.First; var scaling = 1.0; return transformation.totalCost / (transformation.minSizeForTreeA * scaling); } return 10; }
public MainForm() { InitializeComponent(); this.Size = Properties.Settings.Default.MainFormSize; this.Location = Properties.Settings.Default.MainFormLocation; // Load all known color on textBoxColorName's AutoComplete Collection Automaton c = new Automaton(); this.textBoxColorName.AutoCompleteCustomSource = c.GetAllKnownColors(); }
public override bool IsFirable(Automaton firer) { if (pattern != null) { if (base.IsFirable(firer)) { return pattern.HasTarget(firer.FindTarget); } } return false; }
public void OnSight(RaycastHit[] hits, Automaton au) { if(au.CurrentTarget == null){ foreach(RaycastHit hit in hits){ if(hit.transform.gameObject.tag.Equals("Fireteam")){ au.CurrentTarget = hit.transform.gameObject; break; } } } }
public bool HasFirableTarget(Automaton firer) { if (pattern != null) { if (base.IsFirable(firer)) { return pattern.HasApplicableTarget(firer.FindTarget); } } return false; }
public bool HasFirable(Automaton owner) { foreach (var entity in queue) { if (entity.IsFirable(owner)) { return true; } } return false; }
protected override bool Fire(Automaton owner, Command command) { if (base.Fire(owner, command)) { if (consumable) { Remove(command); } return true; } return false; }
/// <summary> /// Computes the ratio of the symmetric difference to the size of dfa1 enumerating paths up to length n (uses the complement if density is high) /// </summary> /// <returns>size of ((dfa2-dfa1)+(dfa1-dfa2))/dfa1</returns> public static double GetDFADifferenceRatio(Automaton<BDD> dfa1, Automaton<BDD> dfa2, HashSet<char> al, CharSetSolver solver) { var solutionDensity = DFADensity.GetDFADensity(dfa1, al, solver); //Symmetric difference var dfadiff1 = dfa1.Minus(dfa2, solver); var dfadiff2 = dfa2.Minus(dfa1, solver); var dfatrue = Automaton<BDD>.Create(0, new int[] { 0 }, new Move<BDD>[] { new Move<BDD>(0, 0, solver.True) }); var dfadiff = dfatrue.Minus(dfatrue.Minus(dfadiff1, solver).Intersect(dfatrue.Minus(dfadiff2, solver), solver), solver).Determinize(solver).Minimize(solver); //Use smallest of |dfa1| and complement of |dfa1| for cardinality base return GetDFARatio(dfa1.Determinize(solver).Minimize(solver), dfadiff, al, solver, solutionDensity > 0.5); }
public void OnHear(GameObject source, Automaton au) { if(au.CurrentTarget==null && !au.IsChecking){ if(!au.agresive){ au.transform.LookAt(new Vector3 (source.transform.position.x, au.transform.position.y,source.transform.position.z)); au.IsChecking = true; au.StartCoroutine("CheckNoise"); }else{ au.SaveIndex(); au.ClearQue(source.transform.position); au.StartCoroutine("Going"); } } }
static YieldTypeChecker() { yieldTypeCheckerAutomatonSolver = new CharSetSolver(BitWidth.BV7); yieldTypeCheckerAutomaton = Automaton<BvSet>.MkProduct(yieldTypeCheckerAutomatonSolver.Convert(yieldTypeCheckerRegex), yieldTypeCheckerAutomatonSolver.Convert(@"^[1-9A-D]*$"), // result of product with this Automaton provides us //an automaton that has (*) existence alphanum chars in our property automaton yieldTypeCheckerAutomatonSolver); minimizedTypeCheckerAutomaton = yieldTypeCheckerAutomaton.Determinize(yieldTypeCheckerAutomatonSolver).Minimize(yieldTypeCheckerAutomatonSolver); #if DEBUG && !DEBUG_DETAIL yieldTypeCheckerAutomatonSolver.ShowGraph(minimizedTypeCheckerAutomaton, "minimizedPropertyAutomaton.dgml"); #endif }
public virtual bool IsFirable(Automaton firer) { if (priority > 0 && firer.IsInMotion()) { return false; } if (condition != null && !condition(firer)) { return false; } if (remainCooltime > 0) { return false; } return true; }
static void Main(string[] args) { var word = ""; var gotEnd = false; var machine = new Automaton( new[] { new Final(state => gotEnd = word.Length == state.Position, "F", "E", "S") }, rules); machine.Run(word); Console.WriteLine(gotEnd); if (Debugger.IsAttached) { Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } }
/// <summary> /// Computes the approximate denstity of dfa /// </summary> /// <returns>size of dfa2/ size of dfa1</returns> internal static double GetDFADensity(Automaton<BDD> dfa, HashSet<char> al, CharSetSolver solver) { var n = dfa.StateCount; double multiplier = 3; int k = Math.Min(13, (int)(n * multiplier)); double[] paths1 = GetPathsUpToN(dfa, al, solver, k); double sum = 0; for (int i = 0; i <= k; i++) { double divider = Math.Pow(al.Count, i); sum += (paths1[i] / divider); } return sum / (k+1); }
/// <summary> /// create new instance of NFAEdit distance and assigns a number to each character /// </summary> /// <param name="nfa1"></param> /// <param name="nfa2"></param> /// <param name="al"></param> /// <param name="solver"></param> /// <param name="timeout"></param> public NFAEditDistanceProvider(Automaton<BDD> nfa1, HashSet<char> al, CharSetSolver solver, long timeout) { this.nfa1 = nfa1; this.al = al; this.solver = solver; this.timeout = timeout; this.alphabetMap = new Dictionary<char, int>(); int index = 0; foreach(var c in al){ this.alphabetMap[c] = index; index++; } this.sw = new Stopwatch(); this.tests = NFAUtilities.MyHillTestGeneration(al, nfa1.Determinize(solver), solver); var dfa1 = nfa1.RemoveEpsilons(solver.MkOr).Determinize(solver).Minimize(solver); this.nfa1density = DFADensity.GetDFADensity(dfa1, al, solver); }
protected override bool Fire(Automaton owner, Command command) { if (base.Fire(owner, command)) { if (onChargedAttack != null) { if (command is BlockCommand) { BlockCommand blockCommand = command as BlockCommand; if (blockCommand.isChargedAttack) { onChargedAttack(blockCommand.matchGeneration); } } } return true; } return false; }
static void Main(string[] args) { int count53150 = 0, count53555 = 0, count5510 = 0, count0001 = 0; var machine = new Automaton( new[] { // final states new Final(_ => count53150++, "A6"), new Final(_ => count53555++, "B6"), new Final(_ => count5510++, "C4"), new Final(_ => count0001++, "D4"), }, rules); machine.Run("0001531505355510001"); var @out = new[] { $"53150: {count53150}", $"53555: {count53555}", $"5510: {count5510}", $"0001: {count0001}" }; Console.WriteLine(string.Join("\n", @out)); if (Debugger.IsAttached) { Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } }
/* * Constructor. * * The number of the inadequate state. * The first conflicting grammar rule. * The second conflicting grammar rule. * The conflicting lookahead. * The faulty automaton. */ public ReduceReduceConflictException(int state, Rule firstRule, Rule secondRule, string lookahead, Automaton automaton) : base(GetMessage(state, firstRule, secondRule, lookahead), state, automaton) { this.FirstRule = firstRule; this.SecondRule = secondRule; this.Lookahead = lookahead; }
private void textBoxHSL_MouseClick(object sender, MouseEventArgs e) { Automaton.SelectAll(textBoxHSL); }
/// <summary> /// Used by subclass to change the lookup automaton, if /// necessary. /// </summary> protected virtual Automaton ConvertAutomaton(Automaton a) { return(a); }
public static Automaton <BDD> MkFalse(IBDDAlgebra alg) { var moves = new Move <BDD>[] { }; return(Automaton <BDD> .Create(alg, 0, new int[] {}, moves, false, false, true)); }
public virtual void TestIntersectEmptyString() { Directory dir = NewDirectory(); IndexWriterConfig iwc = NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random)); iwc.SetMergePolicy(new LogDocMergePolicy()); RandomIndexWriter w = new RandomIndexWriter(Random, dir, iwc); Document doc = new Document(); doc.Add(NewStringField("field", "", Field.Store.NO)); doc.Add(NewStringField("field", "abc", Field.Store.NO)); w.AddDocument(doc); doc = new Document(); // add empty string to both documents, so that singletonDocID == -1. // For a FST-based term dict, we'll expect to see the first arc is // flaged with HAS_FINAL_OUTPUT doc.Add(NewStringField("field", "abc", Field.Store.NO)); doc.Add(NewStringField("field", "", Field.Store.NO)); w.AddDocument(doc); w.ForceMerge(1); DirectoryReader r = w.GetReader(); w.Dispose(); AtomicReader sub = GetOnlySegmentReader(r); Terms terms = sub.Fields.GetTerms("field"); Automaton automaton = (new RegExp(".*", RegExpSyntax.NONE)).ToAutomaton(); // accept ALL CompiledAutomaton ca = new CompiledAutomaton(automaton, false, false); TermsEnum te = terms.Intersect(ca, null); DocsEnum de; Assert.IsTrue(te.MoveNext()); Assert.AreEqual("", te.Term.Utf8ToString()); de = te.Docs(null, null, DocsFlags.NONE); Assert.AreEqual(0, de.NextDoc()); Assert.AreEqual(1, de.NextDoc()); Assert.IsTrue(te.MoveNext()); Assert.AreEqual("abc", te.Term.Utf8ToString()); de = te.Docs(null, null, DocsFlags.NONE); Assert.AreEqual(0, de.NextDoc()); Assert.AreEqual(1, de.NextDoc()); Assert.IsFalse(te.MoveNext()); // pass empty string te = terms.Intersect(ca, new BytesRef("")); Assert.IsTrue(te.MoveNext()); Assert.AreEqual("abc", te.Term.Utf8ToString()); de = te.Docs(null, null, DocsFlags.NONE); Assert.AreEqual(0, de.NextDoc()); Assert.AreEqual(1, de.NextDoc()); Assert.IsFalse(te.MoveNext()); r.Dispose(); dir.Dispose(); }
public DensityFeedback(FeedbackLevel level, HashSet <char> alphabet, Automaton <BDD> dfaGoal, Automaton <BDD> dfaAttempt, double utility, CharSetSolver solver) : base(level, alphabet, utility, solver) { BDD pred = solver.False; foreach (var el in alphabet) { pred = solver.MkOr(pred, solver.MkCharConstraint(false, el)); } var dfaAll = Automaton <BDD> .Create(0, new int[] { 0 }, new Move <BDD>[] { new Move <BDD>(0, 0, pred) }); this.type = FeedbackType.Density; this.positiveDifference = dfaGoal.Minus(dfaAttempt, solver).Determinize(solver).Minimize(solver); this.negativeDifference = dfaAttempt.Minus(dfaGoal, solver).Determinize(solver).Minimize(solver); this.symmetricDifference = dfaAll.Minus(dfaAll.Minus(positiveDifference, solver).Intersect(dfaAll.Minus(negativeDifference, solver), solver), solver).Determinize(solver).Minimize(solver); this.solver = solver; }
// returns an array where a[n] is the number of paths of length n private static double[] GetPathsUpToN(Automaton <BDD> dfa, HashSet <char> al, CharSetSolver solver, int n) { var normDfa1 = DFAUtilities.normalizeDFA(dfa).First; int length = 0; double[] totPaths = new double[n + 1]; var finalStates = normDfa1.GetFinalStates(); double[] pathNum = new double[normDfa1.StateCount]; pathNum[0] = 1; totPaths[0] = finalStates.Contains(0) ? 1 : 0; for (int i = 1; i < pathNum.Length; i++) { pathNum[i] = 0; } while (length < n) { double[] oldPathNum = pathNum.ToArray(); for (int i = 0; i < pathNum.Length; i++) { pathNum[i] = 0; } length++; foreach (var state in normDfa1.States) { if (oldPathNum[state] > 0) { foreach (var move in normDfa1.GetMovesFrom(state)) { int size = 0; //Check if epsilon transition if (move.Label == null) { size = 1; } else { foreach (var v in solver.GenerateAllCharacters(move.Label, false)) { size++; } } pathNum[move.TargetState] += oldPathNum[state] * size; } } } //totPaths[length] = totPaths[length - 1]; foreach (var state in finalStates) { totPaths[length] += pathNum[state]; } } return(totPaths); }
/// <summary> /// Returns all prefix paths to initialize the search. /// </summary> protected internal virtual IList <FSTUtil.Path <PairOutputs <long?, BytesRef> .Pair> > GetFullPrefixPaths( IList <FSTUtil.Path <PairOutputs <long?, BytesRef> .Pair> > prefixPaths, Automaton lookupAutomaton, FST <PairOutputs <long?, BytesRef> .Pair> fst) { return(prefixPaths); }
/// <summary> /// Checks if L(this) is a subset of L(M). If not, produces witness. /// </summary> public bool IsSubsetOf(SSA <SYMBOL> m, out List <Predicate <SYMBOL> > witness) { return(!(Automaton <Predicate <SYMBOL> > .CheckDifference(this.automaton, m.automaton, 0, out witness))); }
/// <summary> /// Checks if the intersection of L(M1) and L(M2) is an empty language. If not, produces witness. /// </summary> public static bool ProductIsEmpty(SSA <SYMBOL> m1, SSA <SYMBOL> m2, out List <Predicate <SYMBOL> > witness) { return(!Automaton <Predicate <SYMBOL> > .CheckProduct(m1.automaton, m2.automaton, 0, out witness)); }
/// <summary> /// Extracts all <see cref="MultiTermQuery"/>s for <paramref name="field"/>, and returns equivalent /// automata that will match terms. /// </summary> internal static CharacterRunAutomaton[] ExtractAutomata(Query query, string field) { List <CharacterRunAutomaton> list = new List <CharacterRunAutomaton>(); if (query is BooleanQuery booleanQuery) { foreach (BooleanClause clause in booleanQuery.GetClauses()) { if (!clause.IsProhibited) { list.AddRange(ExtractAutomata(clause.Query, field)); } } } else if (query is DisjunctionMaxQuery disjunctionMaxQuery) { foreach (Query sub in disjunctionMaxQuery.Disjuncts) { list.AddRange(ExtractAutomata(sub, field)); } } else if (query is SpanOrQuery spanOrQuery) { foreach (Query sub in spanOrQuery.GetClauses()) { list.AddRange(ExtractAutomata(sub, field)); } } else if (query is SpanNearQuery spanNearQuery) { foreach (Query sub in spanNearQuery.GetClauses()) { list.AddRange(ExtractAutomata(sub, field)); } } else if (query is SpanNotQuery spanNotQuery) { list.AddRange(ExtractAutomata(spanNotQuery.Include, field)); } else if (query is SpanPositionCheckQuery spanPositionCheckQuery) { list.AddRange(ExtractAutomata(spanPositionCheckQuery.Match, field)); } else if (query is ISpanMultiTermQueryWrapper spanMultiTermQueryWrapper) { list.AddRange(ExtractAutomata(spanMultiTermQueryWrapper.WrappedQuery, field)); } else if (query is AutomatonQuery aq) { if (aq.Field.Equals(field, StringComparison.Ordinal)) { list.Add(new CharacterRunAutomatonToStringAnonymousClass(aq.Automaton, () => aq.ToString())); } } else if (query is PrefixQuery pq) { Term prefix = pq.Prefix; if (prefix.Field.Equals(field, StringComparison.Ordinal)) { list.Add(new CharacterRunAutomatonToStringAnonymousClass( BasicOperations.Concatenate(BasicAutomata.MakeString(prefix.Text()), BasicAutomata.MakeAnyString()), () => pq.ToString())); } } else if (query is FuzzyQuery fq) { if (fq.Field.Equals(field, StringComparison.Ordinal)) { string utf16 = fq.Term.Text(); int[] termText = new int[utf16.CodePointCount(0, utf16.Length)]; for (int cp, i = 0, j = 0; i < utf16.Length; i += Character.CharCount(cp)) { termText[j++] = cp = utf16.CodePointAt(i); } int termLength = termText.Length; int prefixLength = Math.Min(fq.PrefixLength, termLength); string suffix = UnicodeUtil.NewString(termText, prefixLength, termText.Length - prefixLength); LevenshteinAutomata builder = new LevenshteinAutomata(suffix, fq.Transpositions); Automaton automaton = builder.ToAutomaton(fq.MaxEdits); if (prefixLength > 0) { Automaton prefix = BasicAutomata.MakeString(UnicodeUtil.NewString(termText, 0, prefixLength)); automaton = BasicOperations.Concatenate(prefix, automaton); } list.Add(new CharacterRunAutomatonToStringAnonymousClass(automaton, () => fq.ToString())); } } else if (query is TermRangeQuery tq) { if (tq.Field.Equals(field, StringComparison.Ordinal)) { // this is *not* an automaton, but its very simple list.Add(new SimpleCharacterRunAutomatonAnonymousClass(BasicAutomata.MakeEmpty(), tq)); } } return(list.ToArray(/*new CharacterRunAutomaton[list.size()]*/)); }
private void textBoxHSL_Enter(object sender, EventArgs e) { Automaton.SelectAll(textBoxHSL); }
/// <summary> /// Based on paper /// Order-n correction for regular langauges, http://dl.acm.org/citation.cfm?id=360995 /// </summary> /// <param name="str">input string</param> /// <param name="automaton">dfa for which you want to compute the distance</param> /// <param name="solver">character solver</param> /// <param name="bound">depth of search for max string insertion</param> /// <param name="distance">outputs the distance</param> /// <returns>the closest string to str in automaton</returns> public static string GetClosestElement(string str, Automaton<BDD> automaton, CharSetSolver solver, int bound, out int distance, bool checkDeterminism = true) { //bound = Math.Min(bound, str.Length); var input = str.ToCharArray(); var chars = new HashSet<char>(input); var maxl = input.Length+1; if(automaton.IsEmpty) throw new AutomataException("automaton must be nonempty"); if (checkDeterminism && !automaton.IsDeterministic) throw new AutomataException("automaton must be deterministic"); //Compute P(T,S) L(T,S,c) var lstates= automaton.States.ToList(); lstates.Sort(); var states = lstates.ToArray(); var stToInd = new Dictionary<int, int>(states.Length+1); for (int i = 0; i < states.Length; i++) stToInd[states[i]] = i; var Pold = new int[states.Length, states.Length]; var P1 = new bool[states.Length, states.Length]; //Records the transition relation var Pnew = new int[states.Length, states.Length]; var Lold=new Dictionary<char,bool[,]>(); var Lnew = new Dictionary<char, bool[ ,]>(); #region Initialize P L foreach (var c in chars) { Lold[c] = new bool[states.Length, states.Length]; Lnew[c] = new bool[states.Length, states.Length]; } foreach (var stT in automaton.States) { var T = stToInd[stT]; foreach (var stS in automaton.States) { var S = stToInd[stS]; if (T == S) { Pold[S, T] = 0; char wit; P1[S, T] = MoveFromStoT(stS, stT, automaton, solver, out wit); foreach (var c in chars) if (P1[S, T] && MoveFromStoTContainsC(c, stS, stT, automaton, solver)) Lold[c][S, T] = true; else Lold[c][S, T] = false; } else { char wit; if (MoveFromStoT(stS, stT, automaton, solver, out wit)) { Pold[S, T] = 1; P1[S, T] = true; foreach (var c in chars) if (MoveFromStoTContainsC(c, stS, stT, automaton, solver)) Lold[c][S, T] = true; else Lold[c][S, T] = false; } else { Pold[S, T] = int.MaxValue; P1[S, T] = false; foreach (var c in chars) Lold[c][S, T] = false; } } } } #endregion //solver.ShowGraph(automaton,"as"); //Inductive step for(int k=1;k<=bound;k++){ foreach (var stT in automaton.States) { var T = stToInd[stT]; foreach (var stS in automaton.States) { var S = stToInd[stS]; if (Pold[S, T] == int.MaxValue) { bool found=false; foreach (var move in automaton.GetMovesFrom(stS)) { var stk = move.TargetState; var K = stToInd[stk]; if (Pold[K, T] != int.MaxValue) if (P1[S, K]) { found = true; Pnew[S, T] = Pold[K, T] + 1; foreach (var c in chars) Lnew[c][S, T] = Lold[c][K, T] || solver.IsSatisfiable(solver.MkAnd(move.Label,solver.MkCharConstraint(c))); } } if (!found) { Pnew[S, T] = Pold[S, T]; foreach (var c in chars) Lnew[c][S, T] = Lold[c][S, T]; } } else { Pnew[S, T] = Pold[S, T]; foreach (var c in chars) Lnew[c][S, T] = Lold[c][S, T]; } } } Pold = Pnew; Pnew=new int[states.Length, states.Length]; foreach (var c in chars) Lold[c] = Lnew[c]; Lnew = new Dictionary<char, bool[,]>(); foreach (var c in chars) Lnew[c] = new bool[states.Length, states.Length]; } //Initialize table for value 0 Pair<int, int>[,] F = new Pair<int, int>[maxl, automaton.StateCount]; foreach (var st in automaton.States) { var T = stToInd[st]; if (st == automaton.InitialState) F[0, T] = new Pair<int, int>(0, -1); else F[0, T] = new Pair<int, int>(int.MaxValue, -1); } //solver.ShowGraph(automaton,"aa"); //Dynamic programming loop List<int> stateList = new List<int>(); for (int j = 1; j < maxl; j++) { var aj = input[j - 1]; foreach (var stT in automaton.States) { var T = stToInd[stT]; int min = int.MaxValue; int minSt = -1; foreach (var stS in automaton.States) { var S = stToInd[stS]; var pts = Pold[S, T]; if (pts != int.MaxValue) { var ltsc = Lold[aj][S, T] ? 1 : 0; int vts = pts == 0 ? 1 - ltsc : pts - ltsc; var fjm1t = F[j - 1, S]; int expr = fjm1t.First + vts; if (fjm1t.First == int.MaxValue || vts == int.MaxValue) expr = int.MaxValue; else if (expr <= min) { min = expr; minSt = S; if (min == 0) break; } } } F[j, T] = new Pair<int, int>(min, minSt); } } //Iteration over final states int minAcc = int.MaxValue; int minState = -1; foreach (var st in automaton.GetFinalStates()) { var S = stToInd[st]; if (F[input.Length, S].First < minAcc) { minAcc = F[input.Length, S].First; minState = F[input.Length, S].Second; minState = S; } } var minString =""; int curr = minState; int strindex = input.Length; while (strindex > 0) { var f = F[strindex, curr]; var aj = input[strindex-1]; var pts = Pold[f.Second,curr]; var ltsc = Lold[aj][f.Second,curr] ? 1 : 0; string vts = pts == 0 ? ((ltsc == 1)? aj.ToString():"") : ((ltsc == 1) ? ShortStringStoTwithC(aj, states[f.Second], states[curr], automaton, bound, solver) : ShortStringStoT(states[f.Second], states[curr], automaton, bound, solver)); minString = vts + minString; curr = f.Second; strindex--; } distance=minAcc; return minString; }
public void TestParsing2() { //this test set tests parsing with spaces at odd locations. // I'm alternating the location of spaces only on the e-line, in every categorical distinct location Automaton a = AutomatonParser.ParseAutomaton(@" E ={a|O,b|O},true O={a|E,b|E},false".Trim()); Assert.IsTrue(GenerateExpectedAutomaton1().ValueEquals(a)); a = AutomatonParser.ParseAutomaton(@" E= {a|O,b|O},true O={a|E,b|E},false".Trim()); Assert.IsTrue(GenerateExpectedAutomaton1().ValueEquals(a)); a = AutomatonParser.ParseAutomaton(@" E={ a|O,b|O},true O={a|E,b|E},false".Trim()); Assert.IsTrue(GenerateExpectedAutomaton1().ValueEquals(a)); a = AutomatonParser.ParseAutomaton(@" E={a |O,b|O},true O={a|E,b|E},false".Trim()); Assert.IsTrue(GenerateExpectedAutomaton1().ValueEquals(a)); a = AutomatonParser.ParseAutomaton(@" E={a| O,b|O},true O={a|E,b|E},false".Trim()); Assert.IsTrue(GenerateExpectedAutomaton1().ValueEquals(a)); a = AutomatonParser.ParseAutomaton(@" E={a|O ,b|O},true O={a|E,b|E},false".Trim()); Assert.IsTrue(GenerateExpectedAutomaton1().ValueEquals(a)); a = AutomatonParser.ParseAutomaton(@" E={a|O, b|O},true O={a|E,b|E},false".Trim()); Assert.IsTrue(GenerateExpectedAutomaton1().ValueEquals(a)); a = AutomatonParser.ParseAutomaton(@" E={a|O,b|O },true O={a|E,b|E},false".Trim()); Assert.IsTrue(GenerateExpectedAutomaton1().ValueEquals(a)); a = AutomatonParser.ParseAutomaton(@" E={a|O,b|O} ,true O={a|E,b|E},false".Trim()); Assert.IsTrue(GenerateExpectedAutomaton1().ValueEquals(a)); a = AutomatonParser.ParseAutomaton(@" E= {a|O,b|O}, true O={a|E,b|E},false".Trim()); Assert.IsTrue(GenerateExpectedAutomaton1().ValueEquals(a)); a = AutomatonParser.ParseAutomaton(@" E={a|O,b|O},true O={a|E,b|E},false".Trim()); // There is a space after the end of true on the first line. Assert.IsTrue(GenerateExpectedAutomaton1().ValueEquals(a)); }
/// <summary> /// Computes the grade for attempt using all the possible metrics /// </summary> /// <param name="solution">correct dfa</param> /// <param name="attempt">dfa to be graded</param> /// <param name="alpahbet">input alphabet</param> /// <param name="solver">SMT solver for char set</param> /// <param name="timeout">timeout for the PDL enumeration (suggested > 1000)</param> /// <param name="maxGrade">Max grade for the homework</param> /// <param name="level">Feedback level</param> /// <returns>Grade for dfa2</returns> public static Pair <int, IEnumerable <DFAFeedback> > GetGrade( Automaton <BDD> solution, Automaton <BDD> attempt, HashSet <char> alpahbet, CharSetSolver solver, long timeout, int maxGrade, FeedbackLevel level) { return(GetGrade(solution, attempt, alpahbet, solver, timeout, maxGrade, level, true, true, true)); }
/// <summary> /// Computes the strongly connected components of the automaton /// </summary> /// <typeparam name="T"></typeparam> /// <param name="automaton"></param> /// <param name="solver"></param> /// <returns></returns> public static IEnumerable <HashSet <int> > GetStronglyConnectedComponents <T>(Automaton <T> automaton) { var output = new List <HashSet <int> >(); Pair <List <int>, List <int> > dfs = Dfs(automaton.InitialState, automaton); List <int> startTimes = dfs.First; List <int> endTimes = dfs.Second; endTimes.Reverse(); HashSet <int> visited = new HashSet <int>(); foreach (var v in endTimes) { if (!visited.Contains(v)) { var start = new List <int>(); var end = new List <int>(); Dfs(v, automaton, visited, start, end, true); var scc = new HashSet <int>(start); foreach (var s in start) { visited.Add(s); } output.Add(scc); } } return(output); }
/// <summary> /// Computes the grade for attempt using all the possible metrics /// </summary> /// <param name="dfaGoal">minimal correct dfa</param> /// <param name="dfaAttempt">dfa to be graded</param> /// <param name="al">input alphabet</param> /// <param name="solver">SMT solver for char set</param> /// <param name="timeout">timeout for the PDL enumeration (suggested > 1000)</param> /// <param name="maxGrade">Max grade for the homework</param> /// <param name="enableDFAED">true to enable DFA edit distance</param> /// <param name="enablePDLED">true to enable PDL edit distance</param> /// <param name="enableDensity">true to enable density distance</param> /// <returns>Grade for dfa2</returns> public static Pair <int, IEnumerable <DFAFeedback> > GetGrade( Automaton <BDD> dfaGoal, Automaton <BDD> dfaAttempt, HashSet <char> al, CharSetSolver solver, long timeout, int maxGrade, FeedbackLevel level, bool enableDFAED, bool enablePDLED, bool enableDensity) { PDLEnumerator pdlEnumerator = new PDLEnumerator(); var feedList = new List <DFAFeedback>(); DFAFeedback defaultFeedback = new StringFeedback(level, StringFeedbackType.Wrong, al, solver); #region Accessory and initial vars //Compute minimized version of DFAs var dfaGoalMin = dfaGoal.Determinize(solver).Minimize(solver); var dfaAttemptMin = dfaAttempt.Determinize(solver).Minimize(solver); //Initialize distances at high values in case they are not used // they only produce positive grade if between 0 and 1 double pdlEditDistanceScaled = 2; double densityRatio = 2; double dfaED = 2; #endregion #region deductions on the grade based on the size of the dfa //Deduction if DFA is smaller than it should be: used only for PDL ed and for density var smallerDFADeduction = 0.2 * Math.Sqrt( Math.Max(0.0, dfaGoalMin.StateCount - dfaAttemptMin.StateCount) / ((double)dfaGoalMin.StateCount)); #endregion #region check whether the attempt is equivalent to the solution if (dfaGoal.IsEquivalentWith(dfaAttempt, solver)) { Console.WriteLine("Correct"); feedList.Add(new StringFeedback(level, StringFeedbackType.Correct, al, solver)); return(new Pair <int, IEnumerable <DFAFeedback> >(maxGrade, feedList)); } #endregion #region metrics computation Stopwatch swPDLed = new Stopwatch(); swPDLed.Start(); #region PDL edit distance Transformation feedbackTransformation = null; if (enablePDLED) { var trpair = PDLEditDistance.GetMinimalFormulaEditDistanceTransformation(dfaGoalMin, dfaAttemptMin, al, solver, timeout, pdlEnumerator); if (trpair != null) { var transformationGrade = trpair.First; feedbackTransformation = trpair.Second; var scaling = 1.0; pdlEditDistanceScaled = transformationGrade.totalCost / (transformationGrade.minSizeForTreeA * scaling) + smallerDFADeduction; } } #endregion swPDLed.Stop(); Stopwatch swDensity = new Stopwatch(); swDensity.Start(); #region density distance if (enableDensity) { densityRatio = DFADensity.GetDFADifferenceRatio(dfaGoalMin, dfaAttemptMin, al, solver); densityRatio += smallerDFADeduction; } #endregion swDensity.Stop(); Stopwatch swDFAed = new Stopwatch(); swDFAed.Start(); #region DFA edit distance DFAEditScript dfaEditScript = null; if (enableDFAED) { //limit the depth of the DFA edit distance search var maxMoves = Math.Max(1, 6 - (int)Math.Sqrt(dfaAttempt.MoveCount + dfaAttempt.StateCount)); dfaEditScript = DFAEditDistance.GetDFAOptimalEdit(dfaGoal, dfaAttempt, al, solver, timeout, new StringBuilder()); if (dfaEditScript != null) { dfaED = ((double)(dfaEditScript.GetCost())) / ((double)((dfaGoalMin.StateCount + 1) * al.Count)); } } #endregion swDFAed.Stop(); #endregion #region metrics scaling var scalingSquarePDLED = 1.005; var scalingSquareDensity = 1; var multv2 = 0.5; var scalingSquareDFAED = 1.03; var scaledPdlED = (0.9 * (scalingSquarePDLED + pdlEditDistanceScaled) * (scalingSquarePDLED + pdlEditDistanceScaled)) - scalingSquarePDLED * scalingSquarePDLED; var scaledDensityRatio = (scalingSquareDensity + (multv2 * densityRatio)) * (scalingSquareDensity + (multv2 * densityRatio)) - scalingSquareDensity * scalingSquareDensity; var scaledDfaED = (scalingSquareDFAED + dfaED) * (scalingSquareDFAED + dfaED) - scalingSquareDFAED * scalingSquareDFAED; //Select dominating Feedback based on grade double unscaledGrade = Math.Min(Math.Min(scaledPdlED, scaledDensityRatio), scaledDfaED); var pdledwins = scaledPdlED <= Math.Min(scaledDensityRatio, scaledDfaED); var dfaedwins = scaledDfaED <= Math.Min(scaledDensityRatio, scaledPdlED); var densitywins = scaledDensityRatio <= Math.Min(scaledDfaED, scaledPdlED); #endregion #region Feedback Selection if (pdledwins && feedbackTransformation != null && feedbackTransformation.pdlB.GetFormulaSize() < 10) { feedList.Add(new PDLEDFeedback(level, al, feedbackTransformation, scaledPdlED, solver)); } if ((dfaedwins || feedList.Count == 0) && dfaEditScript != null && !dfaEditScript.IsComplex()) { feedList = new List <DFAFeedback>(); feedList.Add(new DFAEDFeedback(dfaGoal, dfaAttempt, level, al, dfaEditScript, scaledDfaED, solver)); } if (densitywins || feedList.Count == 0) { feedList = new List <DFAFeedback>(); feedList.Add(new DensityFeedback(level, al, dfaGoal, dfaAttempt, scaledDensityRatio, solver)); } if (feedList.Count == 0) { Console.WriteLine("Why no feedback!!"); feedList.Add(defaultFeedback); } #endregion #region normalize grade var scaledGrade = maxGrade - (int)Math.Round(unscaledGrade * (double)(maxGrade)); //If rounding yields maxgrade deduct 1 point by default if (scaledGrade == maxGrade) { scaledGrade = maxGrade - 1; } //Remove possible deduction scaledGrade = scaledGrade < 0 ? 0 : scaledGrade; return(new Pair <int, IEnumerable <DFAFeedback> >(scaledGrade, feedList)); #endregion }
public AutomatonTextTemplate(BREXManager manager, BDDHelperPredicates helperPredicates, string name, Automaton <BDD> automaton) { this.manager = manager; this.helperPredicates = helperPredicates; this.name = name; this.automaton = automaton; }
public CharacterRunAutomatonToStringAnonymousClass(Automaton a, Func <string> toStringMethod) : base(a) { this.toStringMethod = toStringMethod; }
public virtual void TestIntersectStartTerm() { Directory dir = NewDirectory(); IndexWriterConfig iwc = NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random)); iwc.SetMergePolicy(new LogDocMergePolicy()); RandomIndexWriter w = new RandomIndexWriter(Random, dir, iwc); Document doc = new Document(); doc.Add(NewStringField("field", "abc", Field.Store.NO)); w.AddDocument(doc); doc = new Document(); doc.Add(NewStringField("field", "abd", Field.Store.NO)); w.AddDocument(doc); doc = new Document(); doc.Add(NewStringField("field", "acd", Field.Store.NO)); w.AddDocument(doc); doc = new Document(); doc.Add(NewStringField("field", "bcd", Field.Store.NO)); w.AddDocument(doc); w.ForceMerge(1); DirectoryReader r = w.GetReader(); w.Dispose(); AtomicReader sub = GetOnlySegmentReader(r); Terms terms = sub.Fields.GetTerms("field"); Automaton automaton = (new RegExp(".*d", RegExpSyntax.NONE)).ToAutomaton(); CompiledAutomaton ca = new CompiledAutomaton(automaton, false, false); TermsEnum te; // should seek to startTerm te = terms.Intersect(ca, new BytesRef("aad")); Assert.IsTrue(te.MoveNext()); Assert.AreEqual("abd", te.Term.Utf8ToString()); Assert.AreEqual(1, te.Docs(null, null, DocsFlags.NONE).NextDoc()); Assert.IsTrue(te.MoveNext()); Assert.AreEqual("acd", te.Term.Utf8ToString()); Assert.AreEqual(2, te.Docs(null, null, DocsFlags.NONE).NextDoc()); Assert.IsTrue(te.MoveNext()); Assert.AreEqual("bcd", te.Term.Utf8ToString()); Assert.AreEqual(3, te.Docs(null, null, DocsFlags.NONE).NextDoc()); Assert.IsFalse(te.MoveNext()); // should fail to find ceil label on second arc, rewind te = terms.Intersect(ca, new BytesRef("add")); Assert.IsTrue(te.MoveNext()); Assert.AreEqual("bcd", te.Term.Utf8ToString()); Assert.AreEqual(3, te.Docs(null, null, DocsFlags.NONE).NextDoc()); Assert.IsFalse(te.MoveNext()); // should reach end te = terms.Intersect(ca, new BytesRef("bcd")); Assert.IsFalse(te.MoveNext()); te = terms.Intersect(ca, new BytesRef("ddd")); Assert.IsFalse(te.MoveNext()); r.Dispose(); dir.Dispose(); }
public virtual void TestSortOrder() { Automaton a = (new RegExp("((\uD866\uDF05)|\uFB94).*")).ToAutomaton(); AssertAutomatonHits(2, a); }
public override IList <LookupResult> DoLookup(string key, HashSet <BytesRef> contexts, bool onlyMorePopular, int num) { Debug.Assert(num > 0); if (onlyMorePopular) { throw new System.ArgumentException("this suggester only works with onlyMorePopular=false"); } if (contexts != null) { throw new System.ArgumentException("this suggester doesn't support contexts"); } if (fst == null) { return(Collections.EmptyList <LookupResult>()); } //System.out.println("lookup key=" + key + " num=" + num); for (var i = 0; i < key.Length; i++) { if (key[i] == 0x1E) { throw new ArgumentException( "lookup key cannot contain HOLE character U+001E; this character is reserved"); } if (key[i] == 0x1F) { throw new ArgumentException( "lookup key cannot contain unit separator character U+001F; this character is reserved"); } } var utf8Key = new BytesRef(key); try { Automaton lookupAutomaton = ToLookupAutomaton(key); var spare = new CharsRef(); //System.out.println(" now intersect exactFirst=" + exactFirst); // Intersect automaton w/ suggest wFST and get all // prefix starting nodes & their outputs: //final PathIntersector intersector = getPathIntersector(lookupAutomaton, fst); //System.out.println(" prefixPaths: " + prefixPaths.size()); FST.BytesReader bytesReader = fst.BytesReader; var scratchArc = new FST.Arc <PairOutputs <long?, BytesRef> .Pair>(); IList <LookupResult> results = new List <LookupResult>(); IList <FSTUtil.Path <PairOutputs <long?, BytesRef> .Pair> > prefixPaths = FSTUtil.IntersectPrefixPaths(ConvertAutomaton(lookupAutomaton), fst); if (exactFirst) { int count = 0; foreach (FSTUtil.Path <PairOutputs <long?, BytesRef> .Pair> path in prefixPaths) { if (fst.FindTargetArc(END_BYTE, path.fstNode, scratchArc, bytesReader) != null) { // This node has END_BYTE arc leaving, meaning it's an // "exact" match: count++; } } // Searcher just to find the single exact only // match, if present: Util.Fst.Util.TopNSearcher <PairOutputs <long?, BytesRef> .Pair> searcher; searcher = new Util.Fst.Util.TopNSearcher <PairOutputs <long?, BytesRef> .Pair>(fst, count * maxSurfaceFormsPerAnalyzedForm, count * maxSurfaceFormsPerAnalyzedForm, weightComparator); // NOTE: we could almost get away with only using // the first start node. The only catch is if // maxSurfaceFormsPerAnalyzedForm had kicked in and // pruned our exact match from one of these nodes // ...: foreach (var path in prefixPaths) { if (fst.FindTargetArc(END_BYTE, path.fstNode, scratchArc, bytesReader) != null) { // This node has END_BYTE arc leaving, meaning it's an // "exact" match: searcher.AddStartPaths(scratchArc, fst.Outputs.Add(path.output, scratchArc.Output), false, path.input); } } var completions = searcher.Search(); Debug.Assert(completions.IsComplete); // NOTE: this is rather inefficient: we enumerate // every matching "exactly the same analyzed form" // path, and then do linear scan to see if one of // these exactly matches the input. It should be // possible (though hairy) to do something similar // to getByOutput, since the surface form is encoded // into the FST output, so we more efficiently hone // in on the exact surface-form match. Still, I // suspect very little time is spent in this linear // seach: it's bounded by how many prefix start // nodes we have and the // maxSurfaceFormsPerAnalyzedForm: foreach (var completion in completions) { BytesRef output2 = completion.Output.Output2; if (SameSurfaceForm(utf8Key, output2)) { results.Add(GetLookupResult(completion.Output.Output1, output2, spare)); break; } } if (results.Count == num) { // That was quick: return(results); } } Util.Fst.Util.TopNSearcher <PairOutputs <long?, BytesRef> .Pair> searcher; searcher = new TopNSearcherAnonymousInnerClassHelper(this, fst, num - results.Count, num * maxAnalyzedPathsForOneInput, weightComparator, utf8Key, results); prefixPaths = GetFullPrefixPaths(prefixPaths, lookupAutomaton, fst); foreach (FSTUtil.Path <PairOutputs <long?, BytesRef> .Pair> path in prefixPaths) { searcher.AddStartPaths(path.fstNode, path.output, true, path.input); } var completions = searcher.Search(); Debug.Assert(completions.IsComplete); foreach (Util.Fst.Util.Result <PairOutputs <long?, BytesRef> .Pair> completion in completions) { LookupResult result = GetLookupResult(completion.Output.Output1, completion.Output.Output2, spare); // TODO: for fuzzy case would be nice to return // how many edits were required //System.out.println(" result=" + result); results.Add(result); if (results.Count == num) { // In the exactFirst=true case the search may // produce one extra path break; } } return(results); } catch (IOException bogus) { throw; } }
/// <summary> /// ButtonClickEvent to parse the <see cref="Automaton"/>. /// </summary> /// <param name="sender">The sender for the event.</param> /// <param name="e">The <see cref="EventArgs"/> for the event.</param> private void BtnParse_Click(object sender, EventArgs e) { Automaton a = AutomatonParser.ParseAutomaton(this.rtbxAutomaton.Text); MessageBox.Show("Automaton parsed successfully."); }
public static Automaton <IMonadicPredicate <BDD, T> > MkFalse <T>(ICartesianAlgebraBDD <T> ca) { var moves = new Move <IMonadicPredicate <BDD, T> >[] { }; return(Automaton <IMonadicPredicate <BDD, T> > .Create(ca, 0, new int[] {}, moves, false, false, true)); }
public virtual void TestKeep() { CharacterRunAutomaton keepWords = new CharacterRunAutomaton(BasicOperations.Complement(Automaton.Union(new Automaton[] { BasicAutomata.MakeString("foo"), BasicAutomata.MakeString("bar") }))); Analyzer a = new MockAnalyzer(Random, MockTokenizer.SIMPLE, true, keepWords); AssertAnalyzesTo(a, "quick foo brown bar bar fox foo", new string[] { "foo", "bar", "bar", "foo" }, new int[] { 2, 2, 1, 2 }); }
STModel ConvertReplace(replace repl) { //create a disjunction of all the regexes //each case terminated by the identifier int K = 0; //max pattern length //HashSet<int> finalReplacers = new HashSet<int>(); //for efficieny keep lookup tables of character predicates to sets Dictionary <Expr, BDD> predLookup = new Dictionary <Expr, BDD>(); Automaton <BDD> previouspatterns = Automaton <BDD> .MkEmpty(css); Automaton <BV2> N = Automaton <BV2> .MkFull(css2); var hasNoEndAnchor = new HashSet <int>(); for (int i = 0; i < repl.CaseCount; i++) { replacecase rcase = repl.GetCase(i); var pat = "^" + rcase.Pattern.val; var M = css.Convert("^" + rcase.Pattern.val, System.Text.RegularExpressions.RegexOptions.Singleline).Determinize(css).Minimize(css); #region check that the pattern is a feasible nonempty sequence if (M.IsEmpty) { throw new BekParseException(string.Format("Semantic error: pattern {0} is infeasible.", rcase.Pattern.ToString())); } int _K; if (!M.CheckIfSequence(out _K)) { throw new BekParseException(string.Format("Semantic error: pattern {0} is not a sequence.", rcase.Pattern.ToString())); } if (_K == 0) { throw new BekParseException(string.Format("Semantic error: empty pattern {0} is not allowed.", rcase.Pattern.ToString())); } K = Math.Max(_K, K); #endregion var liftedMoves = new List <Move <BV2> >(); var st = M.InitialState; var newFinalState = M.MaxState + 1; var endAnchor = css.MkCharConstraint((char)i); //lift the moves to BV2 moves, adding end-markers while (!M.IsFinalState(st)) { var mv = M.GetMoveFrom(st); var pair_cond = new BV2(mv.Label, css.False); var liftedMove = new Move <BV2>(mv.SourceState, mv.TargetState, pair_cond); liftedMoves.Add(liftedMove); if (M.IsFinalState(mv.TargetState)) { var end_cond = new BV2(css.False, endAnchor); if (M.IsLoopState(mv.TargetState)) { hasNoEndAnchor.Add(i); //var loop_cond = css2.MkNot(end_cond); //var loopMove = new Move<BV2>(mv.TargetState, mv.TargetState, loop_cond); //liftedMoves.Add(loopMove); } var endMove = new Move <BV2>(mv.TargetState, newFinalState, end_cond); liftedMoves.Add(endMove); } st = mv.TargetState; } var N_i = Automaton <BV2> .Create(css2, M.InitialState, new int[] { newFinalState }, liftedMoves); //Microsoft.Automata.Visualizer.ToDot(N_i, "N" + i , "C:\\Automata\\Docs\\Papers\\Bex\\N" + i +".dot", x => "(" + css.PrettyPrint(x.First) + "," + css.PrettyPrint(x.Second) + ")"); N = N.Intersect(N_i.Complement(css2), css2); #region other approach: disallow overlapping patterns //Visualizer.ShowGraph(M2.Complement(css2), "M2", lab => { return "<" + css.PrettyPrint(lab.First) + "," + css.PrettyPrint(lab.Second) + ">"; }); //note: keep here the original pattern, add only the start anchor to synchronize prefixes //var thispattern = css.Convert("^" + rcase.Pattern.val, System.Text.RegularExpressions.RegexOptions.Singleline).Determinize(css).Minimize(css); //var thispattern1 = thispattern.Minus(previouspatterns, css); //Visualizer.ShowGraph(thispattern1, "test", css.PrettyPrint); //#region check that thispattern does not overlap with any previous pattern //var common = thispattern.Intersect(previouspatterns, css); //if (!(common.IsEmpty)) //{ // int j = 0; // while ((j < i) && css.Convert("^" + repl.GetCase(j).Pattern.val, // System.Text.RegularExpressions.RegexOptions.Singleline).Determinize(css).Intersect(thispattern, css).IsEmpty) // j++; // throw new BekParseException(rcase.id.line, rcase.id.pos, string.Format("Semantic error: pattern {0} overlaps pattern {1}.", // rcase.Pattern.ToString(), repl.GetCase(j).Pattern.ToString())); //} //previouspatterns = previouspatterns.Union(thispattern).RemoveEpsilons(css.MkOr); //TBD: better union //#endregion #endregion } N = N.Complement(css2).Minimize(css2); //Microsoft.Automata.Visualizer.ShowGraph(N, "N", x => "<" + css.PrettyPrint(x.First) + "," + css.PrettyPrint(x.Second) + ">"); //Microsoft.Automata.Visualizer.ToDot(N, "N","C:\\Automata\\Docs\\Papers\\Bex\\N.dot", x => "(" + css.PrettyPrint(x.First) + "," + css.PrettyPrint(x.Second) + ")"); var D = new Dictionary <int, int>(); var G = new Dictionary <int, BDD>(); #region compute distance from initial state and compute guard unions var S = new Stack <int>(); D[N.InitialState] = 0; G[N.InitialState] = css.False; S.Push(N.InitialState); while (S.Count > 0) { var q = S.Pop(); foreach (var move in N.GetMovesFrom(q)) { G[q] = css.MkOr(G[q], move.Label.First); var p = move.TargetState; var d = D[q] + 1; if (!(N.IsFinalState(p)) && !D.ContainsKey(p)) { D[p] = d; G[p] = css.False; S.Push(p); } if (!(N.IsFinalState(p)) && D[p] != d) { throw new BekException(string.Format("Unexpected error, inconsitent distances {0} and {1} to state {2}", D[p], d, p)); } } } #endregion #region check that outputs do not have out of bound variables foreach (var fs in N.GetFinalStates()) { foreach (var move in N.GetMovesTo(fs)) { if (move.Label.Second.IsEmpty) { throw new BekException("Internal error: missing end anchor"); } //if (!css.IsSingleton(move.Condition.Second)) //{ // var one = (int)css.GetMin(move.Condition.Second); // var two = (int)css.GetMax(move.Condition.Second); // throw new BekParseException(repl.GetCase(two).id.line, repl.GetCase(two).id.pos, string.Format("Ambiguous replacement patterns {0} and {1}.", repl.GetCase(one).Pattern, repl.GetCase(two).Pattern)); //} //pick the minimum case identifer when there are several, essentially pick the earliest case int id = (int)css.GetMin(move.Label.Second); int distFromRoot = D[move.SourceState]; var e = repl.GetCase(id).Output; HashSet <int> vars = new HashSet <int>(); foreach (var v in e.GetBoundVars()) { if (v.GetVarId() >= distFromRoot) { throw new BekParseException(v.line, v.pos, string.Format("Syntax error: pattern variable '{0}' is out ouf bounds, valid range is from '#0' to '#{1}']", v.name, distFromRoot - 1)); } } } } #endregion int finalState = N.FinalState; K = K - 1; //this many registers are needed var zeroChar = stb.Solver.MkCharExpr('\0'); var STmoves = new List <Move <Rule <Expr> > >(); var STstates = new HashSet <int>(); var STdelta = new Dictionary <int, List <Move <Rule <Expr> > > >(); var STdeltaInv = new Dictionary <int, List <Move <Rule <Expr> > > >(); var FinalSTstates = new HashSet <int>(); var STdeletedMoves = new HashSet <Move <Rule <Expr> > >(); Action <Move <Rule <Expr> > > STmovesAdd = r => { var p = r.SourceState; var q = r.TargetState; STmoves.Add(r); if (STstates.Add(p)) { STdelta[p] = new List <Move <Rule <Expr> > >(); STdeltaInv[p] = new List <Move <Rule <Expr> > >(); } if (STstates.Add(q)) { STdelta[q] = new List <Move <Rule <Expr> > >(); STdeltaInv[q] = new List <Move <Rule <Expr> > >(); } if (r.Label.IsFinal) { FinalSTstates.Add(p); } STdelta[p].Add(r); STdeltaInv[q].Add(r); }; var regsorts = new Sort[K]; for (int j = 0; j < K; j++) { regsorts[j] = stb.Solver.CharSort; } var regsort = stb.Solver.MkTupleSort(regsorts); var regvar = stb.MkRegister(regsort); var initialRegisterValues = new Expr[K]; for (int j = 0; j < K; j++) { initialRegisterValues[j] = zeroChar; } var initialRegister = stb.Solver.MkTuple(initialRegisterValues); Predicate <int> IsCaseEndState = s => { return(N.OutDegree(s) == 1 && N.GetMoveFrom(s).Label.First.IsEmpty); }; #region compute the forward moves and the completion moves var V = new HashSet <int>(); S.Push(N.InitialState); while (S.Count > 0) { var p = S.Pop(); #region forward moves foreach (var move in N.GetMovesFrom(p)) { var q = move.TargetState; //this move occurs if p has both an end-move and a non-end-move //note that if p is an case-end-state then it is never pushed to S if (N.IsFinalState(q)) { continue; } var distance = D[p]; Expr chExpr; Expr chPred; MkExprPred(move.Label.First, out chExpr, out chPred); predLookup[chPred] = move.Label.First; Expr[] regUpds = new Expr[K]; for (int i = 0; i < K; i++) { if (i == distance) { regUpds[i] = chExpr; } else //if (i < distance) { regUpds[i] = stb.Solver.MkProj(i, regvar); } //else // regUpds[i] = zeroChar; } Expr regExpr = stb.Solver.MkTuple(regUpds); var moveST = stb.MkRule(p, q, chPred, regExpr); //there are no yields STmovesAdd(moveST); if (V.Add(q) && !IsCaseEndState(q)) { S.Push(q); } } #endregion #region completion is only enabled if there exists an else case if (repl.HasElseCase) { var guards = G[p]; var guards0 = G[N.InitialState]; #region nonmatching cases to the initial state var nomatch = css.MkNot(css.MkOr(guards, guards0)); if (!nomatch.IsEmpty) { Expr chExpr; Expr nomatchPred; MkExprPred(nomatch, out chExpr, out nomatchPred); predLookup[nomatchPred] = nomatch; var else_yields_list = new List <Expr>(); for (int i = 0; i < D[p]; i++) { else_yields_list.AddRange(GetElseYieldInstance(repl.ElseOutput, stb.Solver.MkProj(i, regvar))); } else_yields_list.AddRange(GetElseYieldInstance(repl.ElseOutput, stb.MkInputVariable(stb.Solver.CharSort))); var else_yields = else_yields_list.ToArray(); var resetMove = stb.MkRule(p, N.InitialState, nomatchPred, initialRegister, else_yields); STmovesAdd(resetMove); } #endregion #region matching cases via the initial state foreach (var move0 in N.GetMovesFrom(N.InitialState)) { var g0 = move0.Label.First; var match = css.MkAnd(css.MkNot(guards), g0); if (!match.IsEmpty) { Expr chExpr; Expr matchPred; MkExprPred(match, out chExpr, out matchPred); predLookup[matchPred] = match; var resetYieldsList = new List <Expr>(); //for all unprocessed inputs produce the output yield according to the else case for (int i = 0; i < D[p]; i++) { resetYieldsList.AddRange(GetElseYieldInstance(repl.ElseOutput, stb.Solver.MkProj(i, regvar))); } var resetYields = resetYieldsList.ToArray(); Expr[] regupd = new Expr[K]; regupd[0] = chExpr; for (int j = 1; j < K; j++) { regupd[j] = zeroChar; } var regupdExpr = stb.Solver.MkTuple(regupd); var resetMove = stb.MkRule(p, move0.TargetState, matchPred, regupdExpr, resetYields); STmovesAdd(resetMove); } } #endregion } #endregion } #endregion foreach (var last_move in N.GetMovesTo(N.FinalState)) { //i is the case identifier int i = (int)css.GetMin(last_move.Label.Second); if (hasNoEndAnchor.Contains(i)) { #region this corresponds to looping back to the initial state on the given input //the final outputs produced after a successful pattern match #region compute the output terms int distFromRoot = D[last_move.SourceState]; Func <ident, Expr> registerMap = id => { // --- already checked I think --- if (!id.IsVar || id.GetVarId() >= distFromRoot) { throw new BekParseException(id.Line, id.Pos, string.Format("illeagal variable '{0}' in output", id.name)); } if (id.GetVarId() == distFromRoot - 1) //the last reg update refers to the current variable { return(stb.MkInputVariable(stb.Solver.CharSort)); } else { return(stb.Solver.MkProj(id.GetVarId(), regvar)); } }; Expr[] yields; var outp = repl.GetCase(i).Output; if (outp is strconst) { var s = ((strconst)outp).val; yields = Array.ConvertAll(s.ToCharArray(), c => this.str_handler.iter_handler.expr_handler.Convert(new charconst("'" + StringUtility.Escape(c) + "'"), registerMap)); } else //must be an explicit list construct { if (!(outp is functioncall) || !((functioncall)outp).id.name.Equals("string")) { throw new BekParseException("Invalid pattern output."); } var s = ((functioncall)outp).args; yields = Array.ConvertAll(s.ToArray(), e => this.str_handler.iter_handler.expr_handler.Convert(e, registerMap)); } #endregion //shortcut all the incoming transitions to the initial state foreach (var move in STdeltaInv[last_move.SourceState]) { //go to the initial state, i.e. the matching raps around int p = move.SourceState; int q0 = N.InitialState; List <Expr> yields1 = new List <Expr>(move.Label.Yields); //incoming yields are yields1.AddRange(yields); var rule = stb.MkRule(p, q0, move.Label.Guard, initialRegister, yields1.ToArray()); STmovesAdd(rule); //STdeletedMoves.Add(move); STmoves.Remove(move); //the move has been replaced } #endregion } else { #region this is the end of the input stream case #region compute the output terms int distFromRoot = D[last_move.SourceState]; Func <ident, Expr> registerMap = id => { if (!id.IsVar || id.GetVarId() >= distFromRoot) { throw new BekParseException(id.Line, id.Pos, string.Format("illeagal variable '{0}' in output", id.name)); } return(stb.Solver.MkProj(id.GetVarId(), regvar)); }; Expr[] yields; var outp = repl.GetCase(i).Output; if (outp is strconst) { var s = ((strconst)outp).val; yields = Array.ConvertAll(s.ToCharArray(), c => this.str_handler.iter_handler.expr_handler.Convert(new charconst("'" + c.ToString() + "'"), registerMap)); } else //must be an explicit list construct { if (!(outp is functioncall) || !((functioncall)outp).id.name.Equals("string")) { throw new BekParseException("Invalid pattern output."); } var s = ((functioncall)outp).args; yields = Array.ConvertAll(s.ToArray(), e => this.str_handler.iter_handler.expr_handler.Convert(e, registerMap)); } #endregion int p = last_move.SourceState; var rule = stb.MkFinalOutput(p, stb.Solver.True, yields); STmovesAdd(rule); #endregion } } if (repl.HasElseCase) { #region final completion (upon end of input) for all non-final states foreach (var p in STstates) { if (!FinalSTstates.Contains(p) && !IsCaseEndState(p)) //there is no final rule for p, so add the default one { Expr[] finalYields; finalYields = new Expr[D[p]]; for (int i = 0; i < finalYields.Length; i++) { finalYields[i] = stb.Solver.MkProj(i, regvar); } var p_finalMove = stb.MkFinalOutput(p, stb.Solver.True, finalYields); STmovesAdd(p_finalMove); } } #endregion } else { //in this case there is a final rule from the initial state var q0_finalMove = stb.MkFinalOutput(N.InitialState, stb.Solver.True); STmovesAdd(q0_finalMove); } var resST = stb.MkST(name, initialRegister, stb.Solver.CharSort, stb.Solver.CharSort, regsort, N.InitialState, STmoves); var resSTb = new STModel(stb.Solver, name, stb.Solver.CharSort, stb.Solver.CharSort, regsort, initialRegister, N.InitialState); //create STb from the moves, we use here the knowledge that the ST is deterministic //we also use the lookuptable of conditions to eliminate dead code //resST.ShowGraph(); //resST.ToDot("C:\\Automata\\Docs\\Papers\\Bex\\B.dot"); #region compute the rules of the resulting STb //V.Clear(); //S.Push(resST.InitialState); //V.Add(resST.InitialState); foreach (var st in resST.GetStates()) { var condUnion = css.False; var st_moves = new List <Move <Rule <Expr> > >(); foreach (var move in resST.GetNonFinalMovesFrom(st)) { condUnion = css.MkOr(condUnion, predLookup[move.Label.Guard]); st_moves.Add(move); } STbRule <Expr> st_rule; if (st_moves.Count > 0) { //collect all rules with singleton guards and put them into a switch statement var st_rules1 = new List <KeyValuePair <Expr, STbRule <Expr> > >(); var st_moves2 = new List <Move <Rule <Expr> > >(); foreach (var move in st_moves) { if (css.ComputeDomainSize(predLookup[move.Label.Guard]) == 1) { var v = stb.Solver.MkNumeral(css.Choose(predLookup[move.Label.Guard]), stb.Solver.CharSort); var r = new BaseRule <Expr>(new Sequence <Expr>(move.Label.Yields), move.Label.Update, move.TargetState); st_rules1.Add(new KeyValuePair <Expr, STbRule <Expr> >(v, r)); } else { st_moves2.Add(move); } } STbRule <Expr> defaultcase = new UndefRule <Expr>("reject"); //make st_moves2 into an ite rule if (st_moves2.Count > 0) { for (int j = st_moves2.Count - 1; j >= 0; j--) { var r = new BaseRule <Expr>(new Sequence <Expr>(st_moves2[j].Label.Yields), st_moves2[j].Label.Update, st_moves2[j].TargetState); if (j == (st_moves2.Count - 1) && condUnion.IsFull) { defaultcase = r; } else { defaultcase = new IteRule <Expr>(st_moves2[j].Label.Guard, r, defaultcase); } } } else if (condUnion.IsFull) { defaultcase = st_rules1[st_rules1.Count - 1].Value; st_rules1.RemoveAt(st_rules1.Count - 1); } if (st_rules1.Count == 0) { st_rule = defaultcase; } else { st_rule = new SwitchRule <Expr>(stb.MkInputVariable(stb.Solver.CharSort), defaultcase, st_rules1.ToArray()); } } else { st_rule = new UndefRule <Expr>("reject"); } resSTb.AssignRule(st, st_rule); var st_finalrules = new List <Rule <Expr> >(resST.GetFinalRules(st)); if (st_finalrules.Count > 1) { throw new BekException("Unexpected error: multiple final rules per state."); } if (st_finalrules.Count > 0) { resSTb.AssignFinalRule(st, new BaseRule <Expr>(new Sequence <Expr>(st_finalrules[0].Yields), initialRegister, st)); } } resSTb.ST = resST; resST.STb = resSTb; #endregion return(resSTb); }
/// <summary> /// Must be called if aut was created with keepBoundaryStates=true. /// </summary> public void EliminateBoundaryStates(Automaton <S> aut) { Func <bool, S> getWordLetterCondition = (b => categorizer.WordLetterCondition); aut.EliminateWordBoundaries(getWordLetterCondition); }
/// <summary> /// Constructs SSA accepting union of L(M1) and L(M2). /// </summary> public static SSA <SYMBOL> Sum(SSA <SYMBOL> m1, SSA <SYMBOL> m2) { return(new SSA <SYMBOL>(Automaton <Predicate <SYMBOL> > .MkSum(m1.automaton, m2.automaton))); }
/* * Constructor. * * The conflicting grammar rule. * The conflicting lookahead to shift. * The faulty automaton. */ public ShiftReduceConflictException(int state, Rule rule, string lookahead, Automaton automaton) : base(GetMessage(rule, state, lookahead), state, automaton) { this.Rule = rule; this.Lookahead = lookahead; }
//check if delta(S,T,c) exists static bool MoveFromStoTContainsC(char c, int S, int T, Automaton<BDD> aut, CharSetSolver solver, out char witness) { var ccond = solver.MkCharConstraint(c); foreach (var move in aut.GetMovesFrom(S)) if (move.TargetState == T) { if (solver.IsSatisfiable(solver.MkAnd(move.Label, ccond))) { witness = c; return true; } else foreach (var w in solver.GenerateAllCharacters(move.Label, false)) { witness = w; return true; } } witness = c; return false; }
/// <summary> /// Return the SFA accepting only the strings accepted by the 3SFA /// </summary> /// <returns></returns> public Automaton <S> GetSmallestLanguageSFA() { return(Automaton <S> .Create(this.algebra, initialState, acceptingStateSet, GetMoves())); }
//check if delta(S,T,c) exists static string ShortStringStoTwithC(char c, int S, int T, Automaton<BDD> aut, int limit, CharSetSolver solver) { var pair = new Pair<int, int>(S, T); if (S == T) return ""; var aut1 = Automaton<BDD>.Create(solver, S, new int[] { T }, aut.GetMoves()); var autR = solver.Convert(System.Text.RegularExpressions.Regex.Escape(c.ToString())); var contst = aut1.Intersect(autR).Determinize().Minimize(); var finst= contst.GetFinalStates(); var strings = new Dictionary<int, string>(); strings[contst.InitialState] = ""; Dictionary<int,int> dist = new Dictionary<int,int>(); HashSet<int> visited = new HashSet<int>(); List<int> toVisit = new List<int>(); visited.Add(contst.InitialState); toVisit.Add(contst.InitialState); dist[contst.InitialState] = 0; while (toVisit.Count > 0) { var curr = toVisit[0]; toVisit.RemoveAt(0); if(dist[curr]<=limit) foreach (var move in contst.GetMovesFrom(curr)) if (!visited.Contains(move.TargetState)) { dist[move.TargetState] = dist[move.SourceState] + 1; visited.Add(move.TargetState); toVisit.Add(move.TargetState); char wit='a'; foreach(var w in solver.GenerateAllCharacters(move.Label,false)){ wit=w; break; } strings[move.TargetState] = strings[move.SourceState] + wit; if (finst.Contains(move.TargetState)) { return strings[move.TargetState]; } } } throw new AutomataException("this code shouldn't be reachable"); }
private SSA(Automaton <Predicate <SYMBOL> > automaton) { this.automaton = automaton; }