/// <summary> /// Invariant: algebra.IsSatisfiable(context), assumes that bag1 has no dead branches /// </summary> private IteBag <T> OpInContext(BagOpertion op, T context, IteBag <T> bag1, IteBag <T> bag2) { IteBag <T> bag; var key = new Tuple <BagOpertion, T, IteBag <T>, IteBag <T> >(op, context, bag1, bag2); if (opCache.TryGetValue(key, out bag)) { return(bag); } if (bag1.IsLeaf) { return(OpInContext2(op, context, bag1, bag2)); } var context1 = algebra.MkAnd(context, bag1.Predicate); var context2 = algebra.MkAnd(context, algebra.MkNot(bag1.Predicate)); var t = OpInContext(op, context1, bag1.TrueCase, bag2); var f = OpInContext(op, context2, bag1.FalseCase, bag2); bag = MkNode(bag1.Predicate, t, f); opCache[key] = bag; return(bag); }
internal void Refine(PRED psi) { if (left == null && right == null) { #region leaf var phi_and_psi = solver.MkAnd(phi, psi); if (solver.IsSatisfiable(phi_and_psi)) { var phi_min_psi = solver.MkAnd(phi, solver.MkNot(psi)); if (solver.IsSatisfiable(phi_min_psi)) { left = new PartitonTree <PRED>(solver, nr + 1, this, phi_and_psi, null, null); right = new PartitonTree <PRED>(solver, nr + 1, this, phi_min_psi, null, null); } else // [[phi]] subset of [[psi]] { left = new PartitonTree <PRED>(solver, nr + 1, this, phi, null, null); //psi must true } } else // [[phi]] subset of [[not(psi)]] { right = new PartitonTree <PRED>(solver, nr + 1, this, phi, null, null); //psi must be false } #endregion } else if (left == null) { right.Refine(psi); } else if (right == null) { left.Refine(psi); } else { #region nonleaf var phi_and_psi = solver.MkAnd(phi, psi); if (solver.IsSatisfiable(phi_and_psi)) { var phi_min_psi = solver.MkAnd(phi, solver.MkNot(psi)); if (solver.IsSatisfiable(phi_min_psi)) { left.Refine(psi); right.Refine(psi); } else // [[phi]] subset of [[psi]] { left.ExtendLeft(); //psi is true right.ExtendLeft(); } } else // [[phi]] subset of [[not(psi)]] { left.ExtendRight(); right.ExtendRight(); //psi is false } #endregion } }
/// <summary> /// The sink state will be the state with the largest id. /// </summary> public ThreeAutomaton <S> MakeTotal() { var aut = this; int deadState = aut.maxState + 1; var newMoves = new List <Move <S> >(); foreach (int state in aut.States) { var cond = algebra.MkNot(algebra.MkOr(aut.EnumerateConditions(state))); if (algebra.IsSatisfiable(cond)) { newMoves.Add(Move <S> .Create(state, deadState, cond)); } } if (newMoves.Count == 0) { return(this); } newMoves.Add(Move <S> .Create(deadState, deadState, algebra.True)); newMoves.AddRange(GetMoves()); return(ThreeAutomaton <S> .Create(algebra, aut.initialState, aut.rejectingStateSet, aut.acceptingStateSet, newMoves)); }
/// <summary> /// Builds a start of line anchor automaton (^ in multiline mode) /// </summary> /// <param name="newLineCond">condition that is true only for a newline character</param> public Automaton <S> MkBol(S newLineCond) { if (!isBeg) { throw new AutomataException(AutomataExceptionKind.MisplacedStartAnchor); } if (isEnd) { return(MkFull()); } var st = this.MkStateId(); var st1 = this.MkStateId(); var notNewLineCond = solver.MkNot(newLineCond); Automaton <S> fa = Automaton <S> .Create(this.solver, st, new int[] { st }, new Move <S>[] { Move <S> .Create(st, st, newLineCond), Move <S> .Create(st, st1, notNewLineCond), Move <S> .Create(st1, st1, notNewLineCond), Move <S> .Create(st1, st, newLineCond) }); return(fa); }
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> /// Creates a leaf with LeafCondition pred. /// If simplify=true, checks if pred is unsat (returns False) or valid (returns True). /// Assumes that if simplify=false then pred is neither unsat nor valid. /// </summary> public BDG <T, S> MkLeaf(T pred, bool simplify = false) { BDG <T, S> val; if (simplify) { if (!MkLeafCache1.TryGetValue(pred, out val)) { if (!leafAlgebra.IsSatisfiable(pred)) { val = _False; } else if (!leafAlgebra.IsSatisfiable(leafAlgebra.MkNot(pred))) { val = _True; } else { val = new BDG <T, S>(this, default(S), pred, null, null); } MkLeafCache1[pred] = val; } } else { if (!MkLeafCache2.TryGetValue(pred, out val)) { val = new BDG <T, S>(this, default(S), pred, null, null); MkLeafCache2[pred] = val; } } return(val); }
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())); }
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> /// Complement the pair predicate by complementing its components. /// </summary> public Pair <S, T> MkNot(Pair <S, T> predicate) { return(new Pair <S, T>(first.MkNot(predicate.First), second.MkNot(predicate.Second))); }
/// <summary> /// Complement the pair predicate by complementing its components. /// </summary> public Tuple <S, T> MkNot(Tuple <S, T> predicate) { return(new Tuple <S, T>(first.MkNot(predicate.Item1), second.MkNot(predicate.Item2))); }