internal void Refine(IBooleanAlgebra <TPredicate> solver, TPredicate other) { if (!StackHelper.TryEnsureSufficientExecutionStack()) { StackHelper.CallOnEmptyStack(Refine, solver, other); return; } TPredicate thisAndOther = solver.And(_pred, other); if (solver.IsSatisfiable(thisAndOther)) { // The predicates overlap, now check if this is contained in other TPredicate thisMinusOther = solver.And(_pred, solver.Not(other)); if (solver.IsSatisfiable(thisMinusOther)) { // This is not contained in other, minterms may need to be split if (_left is null) { Debug.Assert(_right is null); _left = new PartitionTree(thisAndOther); _right = new PartitionTree(thisMinusOther); } else { Debug.Assert(_right is not null); _left.Refine(solver, other); _right.Refine(solver, other); } } } }
/// <summary> /// Constructs the automaton assuming the given list fvs of free variables. /// </summary> /// <param name="alg">label algebra</param> /// <param name="nrOfLabelBits">nr of labels bits, only relevant if alg is not CharSetSolver but is BDDAlgebra</param> /// <param name="singletonSetSemantics">if true uses singleton-set-semantics for f-o variables else uses min-nonempty-set-semantics</param> /// <param name="fvs">free variables, if null uses this.FreeVariables</param> /// <returns></returns> public Automaton <T> GetAutomaton(IBooleanAlgebra <T> alg, int nrOfLabelBits = 0, bool singletonSetSemantics = false, Variable[] fvs = null) { if (fvs == null) { fvs = this.FreeVariables; } Automaton <T> res; var A = alg as CharSetSolver; if (A != null) { res = this.GetAutomatonBDD1(fvs, A, (int)A.Encoding, singletonSetSemantics) as Automaton <T>; } else { var B = alg as BDDAlgebra; if (B != null) { if (nrOfLabelBits == 0 && this.ExistsSubformula(f => f.Kind == MSOFormulaKind.Predicate)) { throw new ArgumentException("BDD predicates are not allowed without any reserved label bits"); } res = this.GetAutomatonBDD1(fvs, B, nrOfLabelBits, singletonSetSemantics) as Automaton <T>; } else { //create temporary cartesian product algebra var C = new CartesianAlgebraBDD <T>(alg); //keep only the original algebra res = Automaton <T> .ProjectSecond <BDD>(this.GetAutomatonX1(fvs, C, singletonSetSemantics)).Determinize().Minimize(); } } return(res); }
Automaton<T> CreateAutomaton3<T>(Func<int, T> f, int bitWidth, IBooleanAlgebra<T> Z) { Func<int, Variable, MSOPredicate<T>> pred = (i, s) => new MSOPredicate<T>(f(i), s); MSOFormula<T> phi = new MSOTrue<T>(); // x1<x2<x3<x4... for (int index = 1; index < bitWidth; index++) { MSOFormula<T> phi1 = new MSOLt<T>(V1("x" + (index - 1)), V1("x" + index)); phi = new MSOAnd<T>(phi, phi1); } // bi(xi) for (int index = 0; index < bitWidth; index++) { MSOFormula<T> phi1 = pred(index, V1("x" + index)); phi = new MSOAnd<T>(phi, phi1); } // exists forall... for (int index = 0; index < bitWidth; index++) { if (index % 2 == 0) phi = new MSOExists<T>(V1("x" + index), phi); else phi = new MSOForall<T>(V1("x" + index), phi); } var aut = phi.GetAutomaton(Z); return aut; }
internal void Refine(IBooleanAlgebra <S> solver, S newSet) { var set_cap_newSet = solver.MkAnd(set, newSet); if (!solver.IsSatisfiable(set_cap_newSet)) { return; //set is disjoint from newSet } if (solver.AreEquivalent(set, set_cap_newSet)) { return; //set is a subset of newSet } var set_minus_newSet = solver.MkAnd(set, solver.MkNot(newSet)); if (left == null) //leaf { left = new PartTree(set_cap_newSet, null, null); right = new PartTree(set_minus_newSet, null, null); } else { left.Refine(solver, newSet); right.Refine(solver, newSet); } }
/// <summary>Constructs a minterm generator for a given Boolean Algebra.</summary> /// <param name="algebra">given Boolean Algebra</param> public MintermGenerator(IBooleanAlgebra <TPredicate> algebra) { // check that we can rely on equivalent predicates having the same hashcode, which EquivClass assumes Debug.Assert(algebra.HashCodesRespectEquivalence); _algebra = algebra; }
private PartitionTree(IBooleanAlgebra <TPredicate> solver, TPredicate pred, PartitionTree?left, PartitionTree?right) { _solver = solver; _pred = pred; _left = left; _right = right; }
/// <summary> /// Return the approx of the min SFA accepting only the strings accepted by the 3SFA /// </summary> /// <returns></returns> public Automaton <S> GetApproxMinimalConsistentSFA(IBooleanAlgebra <S> solver, int numAttempts) { var min = this.Minimize(solver); Automaton <S> minDfa = min.GetBiggestLanguageSFA().Minimize(); var minSt = minDfa.StateCount; Automaton <S> tmp = min.GetSmallestLanguageSFA().Minimize(); if (tmp.StateCount < minSt) { minDfa = tmp; } Random r = new Random(); for (int i = 0; i < numAttempts; i++) { var fin = new HashSet <int>(min.acceptingStateSet); foreach (var st in min.dontCareStateSet) { if (r.Next() % 2 == 0) { fin.Add(st); } } tmp = Automaton <S> .Create(solver, min.initialState, fin, min.GetMoves()); if (tmp.StateCount < minSt) { minDfa = tmp; } } return(minDfa); }
/// <summary> /// Assumes that the automaton is clean: has no unsatisfiable moves, no dead states, and no unreachable states /// </summary> public PushdownAutomaton(IBooleanAlgebra <T> terminalAlgebra, Automaton <PushdownLabel <S, T> > automaton, List <S> stackSymbols, S initialStackSymbol) { this.automaton = automaton; this.stackSymbols = stackSymbols; this.initialStackSymbol = initialStackSymbol; this.terminalAlgebra = terminalAlgebra; }
internal StateDistinguisher_Moore(Automaton <T> aut, Func <T, char> concretize = null) { this.aut = aut; this.solver = aut.Algebra; this.concretize = concretize; Initialize(); }
public bool IsComplete(Automaton <S> l1, Automaton <S> l2, IBooleanAlgebra <S> solver) { if (!GetSmallestLanguageSFA().Minus(l1).IsEmpty) { return(false); } return(l2.Complement().Minus(GetBiggestLanguageSFA()).IsEmpty); }
/// <summary> /// Constructs a pair of Boolean algebras that itself is a Boolean algebra over the disjoint union of the domains. /// </summary> /// <param name="first">first algebra</param> /// <param name="second">second algebra</param> public DisjointUnionAlgebra(IBooleanAlgebra <S> first, IBooleanAlgebra <T> second) { this.first = first; this.second = second; this.mintermgenerator = new MintermGenerator <Tuple <S, T> >(this); this.tt = new Tuple <S, T>(first.True, second.True); this.ff = new Tuple <S, T>(first.False, second.False); }
internal static TrieTree MkInitialTree(IBooleanAlgebra <T> algebra) { var t0 = new TrieTree(1, algebra.False, null, null); var t1 = new TrieTree(1, algebra.True, null, null); var tree = new TrieTree(0, default(T), t0, t1); // any element implies True and does not imply False return(tree); }
/// <summary> /// Constructs a pair of Boolean algebras that itself is a Boolean algebra over the disjoint union of the domains. /// </summary> /// <param name="first">first algebra</param> /// <param name="second">second algebra</param> public PairBoolAlg(IBooleanAlgebra <S> first, IBooleanAlgebra <T> second) { this.first = first; this.second = second; this.mintermgenerator = new MintermGenerator <Pair <S, T> >(this); this.tt = new Pair <S, T>(first.True, second.True); this.ff = new Pair <S, T>(first.False, second.False); }
/// <summary> /// Construct the automata algebra for the character solver for the predicate automata. /// </summary> /// <param name="solver"></param> public AutomataAlgebra(IBooleanAlgebra <S> solver) { this.solver = solver; mtg = new MintermGenerator <Automaton <S> >(this); this.empty = Automaton <S> .MkEmpty(solver); this.full = Automaton <S> .MkFull(solver); }
PartitonTree(IBooleanAlgebra <PRED> solver, int depth, PartitonTree <PRED> parent, PRED phi, PartitonTree <PRED> left, PartitonTree <PRED> right) { this.solver = solver; this.parent = parent; this.nr = depth; this.phi = phi; this.left = left; this.right = right; }
/// <summary> /// Creates internally an empty trie of atoms to distinguish predicates. Throws AutomataException if algebra.IsAtomic is false. /// </summary> /// <param name="algebra">given atomic Boolean algebra</param> public PredicateTrie(IBooleanAlgebra <T> algebra) { if (!algebra.IsAtomic) { throw new AutomataException(AutomataExceptionKind.BooleanAlgebraIsNotAtomic); } this.algebra = algebra; }
PartitonTree <PRED> right; //complement internal PartitonTree(IBooleanAlgebra <PRED> solver) { this.solver = solver; nr = -1; parent = null; this.phi = solver.True; this.left = null; this.right = null; }
/// <summary> /// Create a new incremental automata builder. /// </summary> /// <param name="solver">Effective Boolean algebra over S.</param> /// <param name="callback">The callback function is assumed to map regex nodes to corresponding methods of this builder.</param> public RegexToAutomatonBuilder(IBooleanAlgebra <S> solver, Func <T, Automaton <S> > callback) { this.nodeId = 0; this.solver = solver; this.Callback = callback; this.epsilon = Automaton <S> .MkEpsilon(solver); this.empty = Automaton <S> .MkEmpty(solver); }
internal LazyProductAutomaton(IMinimalAutomaton <T>[] nfas) { this.nfas = nfas; this.solver = nfas[0].Algebra; initialProductState = 0; initialProductStateSeq = new Sequence <int>(Array.ConvertAll(nfas, nfa => nfa.InitialState)); stateSeqs.Add(initialProductStateSeq); stateLookup[initialProductStateSeq] = initialProductState; K = nfas.Length; }
private S MkComplementCondition(IEnumerable <Move <S> > list, IBooleanAlgebra <S> solver) { List <S> conds = new List <S>(); foreach (var t in list) { conds.Add(solver.MkNot(t.Label)); } return(solver.MkAnd(conds.ToArray())); }
/// <summary> /// All deadends and unreachable states are eliminated from the states and moves if cleanup is set to true /// </summary> public PushdownAutomaton(IBooleanAlgebra <T> terminalAlgebra, int initialState, List <int> states, List <int> finalstates, S initialStackSymbol, List <S> stackSymbols, List <Move <PushdownLabel <S, T> > > moves, bool cleanup = false) : base() { this.automaton = Automaton <PushdownLabel <S, T> > .Create(null, initialState, finalstates, moves, cleanup, cleanup); this.stackSymbols = new List <S>(stackSymbols); this.initialStackSymbol = initialStackSymbol; this.terminalAlgebra = terminalAlgebra; }
/// <summary>Enumerates all the paths in this transition excluding paths to dead-ends (and unexplored states if any)</summary> internal IEnumerable <(S, SymbolicRegexNode <S>?, int)> EnumeratePaths(IBooleanAlgebra <S> solver, S pathCondition) { switch (_kind) { case TransitionRegexKind.Leaf: // Omit any path that leads to a deadend or is unexplored if (_leaf >= 0) { yield return(pathCondition, null, _leaf); } break; case TransitionRegexKind.Union: case TransitionRegexKind.OrderedUnion: Debug.Assert(_first is not null && _second is not null); foreach ((S, SymbolicRegexNode <S>?, int)path in _first.EnumeratePaths(solver, pathCondition)) { yield return(path); } foreach ((S, SymbolicRegexNode <S>?, int)path in _second.EnumeratePaths(solver, pathCondition)) { yield return(path); } break; case TransitionRegexKind.Conditional: Debug.Assert(_test is not null && _first is not null && _second is not null); foreach ((S, SymbolicRegexNode <S>?, int)path in _first.EnumeratePaths(solver, solver.And(pathCondition, _test))) { yield return(path); } foreach ((S, SymbolicRegexNode <S>?, int)path in _second.EnumeratePaths(solver, solver.And(pathCondition, solver.Not(_test)))) { yield return(path); } break; default: Debug.Assert(_kind is TransitionRegexKind.Lookaround && _look is not null && _first is not null && _second is not null); foreach ((S, SymbolicRegexNode <S>?, int)path in _first.EnumeratePaths(solver, pathCondition)) { SymbolicRegexNode <S> nullabilityTest = path.Item2 is null ? _look : _look._builder.MkAnd(path.Item2, _look); yield return(path.Item1, nullabilityTest, path.Item3); } foreach ((S, SymbolicRegexNode <S>?, int)path in _second.EnumeratePaths(solver, pathCondition)) { // Complement the nullability test SymbolicRegexNode <S> nullabilityTest = path.Item2 is null?_look._builder.MkNot(_look) : _look._builder.MkAnd(path.Item2, _look._builder.MkNot(_look)); yield return(path.Item1, nullabilityTest, path.Item3); } break; } }
public CsAlgebra(IBooleanAlgebra <T> leafAlgebra, ICounter[] counters) { this.counters = counters; this.LeafAlgebra = leafAlgebra; this.NodeAlgebra = new BDDAlgebra <T>(leafAlgebra); __false = new CsPred <T>(this, (BDD <T>)NodeAlgebra.False); __true = new CsPred <T>(this, (BDD <T>)NodeAlgebra.True); this.K = counters.Length; TrueCsConditionSeq = CsConditionSeq.MkTrue(counters.Length); FalseCsConditionSeq = CsConditionSeq.MkFalse(counters.Length); }
public IteBagBuilder(IBooleanAlgebra <T> algebra) { this.algebra = algebra; leafCache[0] = new IteBag <T>(this, 0, default(T), null, null); leafCache[1] = new IteBag <T>(this, 1, default(T), null, null); foreach (BagOpertion op in Enum.GetValues(typeof(BagOpertion))) { count[op] = 0; stopwatch[op] = new System.Diagnostics.Stopwatch(); } }
private SymbolicNFA(IBooleanAlgebra <S> solver, Transition[] transitionFunction, HashSet <int> unexplored, SymbolicRegexNode <S>[] nodes) { Debug.Assert(transitionFunction.Length > 0 && nodes.Length == transitionFunction.Length); _solver = solver; _transitionFunction = transitionFunction; _finalCondition = new SymbolicRegexNode <S> [nodes.Length]; for (int i = 0; i < nodes.Length; i++) { _finalCondition[i] = nodes[i].ExtractNullabilityTest(); } _unexplored = unexplored; _nodes = nodes; }
public CartesianAlgebra(IBooleanAlgebra <T> leafAlg, IBooleanAlgebra <S> nodeAlg) { this.leafAlgebra = leafAlg; this.nodeAlgebra = nodeAlg; this._True = new BDG <T, S>(this, default(S), leafAlg.True, null, null); this._False = new BDG <T, S>(this, default(S), leafAlg.False, null, null); MkLeafCache1[leafAlg.True] = _True; MkLeafCache2[leafAlg.True] = _True; MkLeafCache1[leafAlg.False] = _False; MkLeafCache2[leafAlg.False] = _False; MkNotCache[_True] = _False; MkNotCache[_False] = _True; this.mintermGenerator = new MintermGenerator <IMonadicPredicate <T, S> >(this); }
/// <summary> /// Creates an instance of state distinguisher for the given dfa. /// </summary> /// <param name="dfa">deterministic automaton</param> /// <param name="choice">choice function for selecting characters from satisfiable predicates</param> /// <param name="optimize">if true then optimizes the computed distinguishing sequences</param> public StateDistinguisher(Automaton <T> dfa, Func <T, char> choice = null, bool optimize = true, bool preferLongest = false) { this.preferLongest = preferLongest; this.concretize = choice; solver = dfa.Algebra; this.autom = dfa.MakeTotal(); //this.sinkStateWasAdded = (this.autom.StateCount > dfa.StateCount); ComputeSplitHistory(); ComputeFinalAndNonfinalBlocks(); if (optimize) { PreCompute__GetDistinguishingSeq(); } }
protected TERM Not(IBooleanAlgebra <TERM> solver, TERM pred) { if (pred.Equals(solver.True)) { return(solver.False); } else if (pred.Equals(solver.False)) { return(solver.True); } else { return(solver.MkNot(pred)); } }
/// <summary> /// Returns true iff this automaton and another automaton B are equivalent /// </summary> /// <param name="B">another autonmaton</param> public bool IsEquivalentWith(ThreeAutomaton <S> B, IBooleanAlgebra <S> solver) { Automaton <S> accA = Automaton <S> .Create(algebra, this.initialState, this.acceptingStateSet, this.GetMoves()); Automaton <S> accB = Automaton <S> .Create(algebra, B.initialState, B.acceptingStateSet, B.GetMoves()); if (!accA.IsEquivalentWith(accB)) { return(false); } Automaton <S> rejA = Automaton <S> .Create(algebra, this.initialState, this.rejectingStateSet, this.GetMoves()); Automaton <S> rejB = Automaton <S> .Create(algebra, B.initialState, B.rejectingStateSet, B.GetMoves()); return(rejA.IsEquivalentWith(rejB)); }
/// <summary> /// Constructs the automaton. The formula must be closed. /// </summary> public Automaton <T> GetAutomaton(IBooleanAlgebra <T> elementAlgebra) { var css = elementAlgebra as CharSetSolver; if (css != null) { var ws1s = this.ToWS1S(); var aut = ws1s.GetAutomatonBDD(css, (int)css.Encoding) as Automaton <T>; return(aut); } else { var ws1s = this.ToWS1S(); var aut = ws1s.GetAutomaton(new BDDAlgebra <T>(elementAlgebra)); return(BasicAutomata.Restrict(aut)); } }