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); } }
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> /// 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); }
private IEnumerable <Move <T> > GetMovesFrom_(int p, int i, T pred, SimpleList <int> stateList) { Sequence <int> stateSeq = stateSeqs[p]; foreach (var move in nfas[i].GetMovesFrom(stateSeq[i])) { var psi = solver.MkAnd(pred, move.Label); if (solver.IsSatisfiable(psi)) { var extendedStateList = stateList.Append(move.TargetState); if (i == K - 1) { //this was the final element of the state sequence var qSeq = new Sequence <int>(extendedStateList); int q; if (!stateLookup.TryGetValue(qSeq, out q)) { q = stateSeqs.Count; stateLookup[qSeq] = q; stateSeqs.Add(qSeq); } yield return(Move <T> .Create(p, q, psi)); } else { //continue in the rest of the state sequence foreach (var res in GetMovesFrom_(p, i + 1, psi, extendedStateList)) { yield return(res); } } } } }
/// <summary> /// Returns the pairwise intersection (conjunction) of the enumerated pairs. /// </summary> /// <param name="predicates">given enumeration of predicate pairs</param> public Pair <S, T> MkAnd(IEnumerable <Pair <S, T> > predicates) { var one = first.MkAnd(EnumerateFirstComponents(predicates)); var two = second.MkAnd(EnumerateSecondComponents(predicates)); if (one.Equals(first.False) && second.Equals(second.False)) { return(ff); } else if (one.Equals(first.True) && second.Equals(second.True)) { return(tt); } else { return(new Pair <S, T>(one, two)); } }
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 And(IBooleanAlgebra <TERM> solver, TERM a, TERM b) { if (a.Equals(solver.True)) { return(b); } else if (b.Equals(solver.True)) { return(a); } else if (b.Equals(a)) { return(a); } else { return(solver.MkAnd(a, b)); } }
public static ThreeAutomaton <S> MkProduct(ThreeAutomaton <S> aut1, ThreeAutomaton <S> aut2, IBooleanAlgebra <S> solver, bool inters) { var a = aut1.MakeTotal(); var b = aut2.MakeTotal(); var stateIdMap = new Dictionary <Tuple <int, int>, int>(); var initPair = new Tuple <int, int>(a.InitialState, b.InitialState); var frontier = new Stack <Tuple <int, int> >(); frontier.Push(initPair); stateIdMap[initPair] = 0; var delta = new Dictionary <int, List <Move <S> > >(); delta[0] = new List <Move <S> >(); var states = new List <int>(); states.Add(0); var accStates = new List <int>(); var rejStates = new List <int>(); if (inters) { if (a.IsFinalState(a.InitialState) && b.IsFinalState(b.InitialState)) { accStates.Add(0); } else if (a.IsRejectingState(a.InitialState) || b.IsRejectingState(b.InitialState)) { rejStates.Add(0); } } else { if (a.IsRejectingState(a.InitialState) && b.IsRejectingState(b.InitialState)) { rejStates.Add(0); } else if (a.IsFinalState(a.InitialState) || b.IsFinalState(b.InitialState)) { accStates.Add(0); } } int n = 1; while (frontier.Count > 0) { var currPair = frontier.Pop(); int source = stateIdMap[currPair]; var outTransitions = delta[source]; foreach (var t1 in a.GetMovesFrom(currPair.Item1)) { foreach (var t2 in b.GetMovesFrom(currPair.Item2)) { var cond = solver.MkAnd(t1.Label, t2.Label); if (!solver.IsSatisfiable(cond)) { continue; //ignore the unsatisfiable move } Tuple <int, int> targetPair = new Tuple <int, int>(t1.TargetState, t2.TargetState); int target; if (!stateIdMap.TryGetValue(targetPair, out target)) { //state has not yet been found target = n; n += 1; stateIdMap[targetPair] = target; states.Add(target); delta[target] = new List <Move <S> >(); frontier.Push(targetPair); if (inters) { if (a.IsFinalState(t1.TargetState) && b.IsFinalState(t2.TargetState)) { accStates.Add(target); } else if (a.IsRejectingState(t1.TargetState) || b.IsRejectingState(t2.TargetState)) { rejStates.Add(target); } } else { if (a.IsRejectingState(t1.TargetState) && b.IsRejectingState(t2.TargetState)) { rejStates.Add(target); } else if (a.IsFinalState(t1.TargetState) || b.IsFinalState(t2.TargetState)) { accStates.Add(target); } } } outTransitions.Add(Move <S> .Create(source, target, cond)); } } } var incomingTransitions = new Dictionary <int, List <Move <S> > >(); foreach (int state in states) { incomingTransitions[state] = new List <Move <S> >(); } foreach (int state in states) { foreach (Move <S> t in delta[state]) { incomingTransitions[t.TargetState].Add(t); } } return(ThreeAutomaton <S> .Create(aut1.algebra, 0, rejStates, accStates, EnumerateMoves(delta))); }
/// <summary> /// Based on MinimizeMoore method/technique. /// </summary> void Initialize() { var fa = aut; var currLayer = new SimpleStack <Tuple <int, int> >(); var nextLayer = new SimpleStack <Tuple <int, int> >(); //any pair of states (p,q) where one state is final and the other is not are distinguished by //the empty list represented by null, this set of distinguishing sequences is trivially suffix-closed foreach (var p in fa.GetStates()) { if (!fa.IsFinalState(p)) { foreach (var q in fa.GetFinalStates()) { var pair = MkPair(p, q); if (!distinguisher.ContainsKey(pair)) { //the empty sequence distinguishes the states distinguisherConcrete[pair] = ""; //List<Pair> pairs; //if (!distinguishingStringsMap.TryGetValue("", out pairs)) //{ // pairs = new List<Tuple<int, int>>(); // distinguishingStringsMap[""] = pairs; // distinguishingStringsSeq.Add(""); //} //pairs.Add(pair); distinguisher[pair] = null; nextLayer.Push(pair); } } } } //if a target pair of states is distinguished by some sequence //then any pair entering those states is also distinguished by extending that sequence //work breadth-first to maintain shortest witnesses while (nextLayer.IsNonempty) { var tmp = currLayer; currLayer = nextLayer; nextLayer = new SimpleStack <Tuple <int, int> >(); while (currLayer.IsNonempty) { var targetpair = currLayer.Pop(); foreach (var m1 in fa.GetMovesTo(targetpair.Item1)) { foreach (var m2 in fa.GetMovesTo(targetpair.Item2)) { if (m1.SourceState != m2.SourceState) { var psi = solver.MkAnd(m1.Label, m2.Label); if (solver.IsSatisfiable(psi)) { var sourcepair = MkPair(m1.SourceState, m2.SourceState); if (!distinguisher.ContainsKey(sourcepair)) { //add a new distinguishing sequence for the source pair //it extends a sequence of the target pair //thus the sequences remain suffix-closed if (concretize != null) { #region when concretization function is given precompute concrete distinguishers char c; if (!selectedCharacterMap.TryGetValue(psi, out c)) { c = concretize(psi); selectedCharacterMap[psi] = c; } var s = c + distinguisherConcrete[targetpair]; distinguisherConcrete[sourcepair] = s; //List<Pair> pairs; //if (!distinguishingStringsMap.TryGetValue(s, out pairs)) //{ // pairs = new List<Tuple<int, int>>(); // distinguishingStringsMap[s] = pairs; // distinguishingStringsSeq.Add(s); //} //pairs.Add(sourcepair); #endregion } var list = new ConsList <T>(psi, distinguisher[targetpair]); distinguisher[sourcepair] = list; nextLayer.Push(sourcepair); } } } } } } } }
private Automaton <S> AlternateSFAs(int start, List <Automaton <S> > sfas, bool addEmptyWord, bool noWordBoundaries) { if (!noWordBoundaries) { var res0 = Automaton <S> .Create(solver, start, EnumFinStates(sfas), EnumMoves(start, sfas)); res0.AddWordBoundaries(EnumWordBounbdaries(sfas)); return(res0); } #region special cases for sfas.Count == 0 or sfas.Count == 1 if (sfas.Count == 0) { if (addEmptyWord) { return(this.epsilon); } else { return(this.empty); } } if (sfas.Count == 1) { if (addEmptyWord && !sfas[0].IsFinalState(sfas[0].InitialState)) { if (sfas[0].InitialStateIsSource) { sfas[0].MakeInitialStateFinal(); } else { sfas[0].AddNewInitialStateThatIsFinal(start); } } return(sfas[0]); } #endregion //special cases for sfas.Count == 0 or sfas.Count == 1 bool allSingleSource = true; #region check if all sfas have a single source foreach (var sfa in sfas) { if (!sfa.InitialStateIsSource) { allSingleSource = false; break; } } #endregion //check if all sfas have a single source bool isDeterministic = !sfas.Exists(IsNonDeterministic); bool isEpsilonFree = !sfas.Exists(HasEpsilons); bool allFinalSink = true; int sinkId; #region check if all sfas have a single final sink and calulate a representative sinkId as the maximum of the ids sinkId = int.MinValue; foreach (var sfa in sfas) { if (!sfa.HasSingleFinalSink) { allFinalSink = false; break; } else { sinkId = Math.Max(sfa.FinalState, sinkId); } } #endregion var finalStates = new List <int>(); if (addEmptyWord) { finalStates.Add(start); //epsilon is accepted so initial state is also final } var conditionMap = new Dictionary <Pair <int, int>, S>(); //for normalization of move conditions var eMoves = new HashSet <Pair <int, int> >(); if (!allSingleSource) { isDeterministic = false; isEpsilonFree = false; foreach (var sfa in sfas) //add initial epsilon transitions { eMoves.Add(new Pair <int, int>(start, sfa.InitialState)); } } else if (isDeterministic) { //check if determinism is preserved for (int i = 0; i < sfas.Count - 1; i++) { for (int j = i + 1; j < sfas.Count; j++) { S cond1 = solver.False; foreach (var move in sfas[i].GetMovesFrom(sfas[i].InitialState)) { cond1 = solver.MkOr(cond1, move.Label); } S cond2 = solver.False; foreach (var move in sfas[j].GetMovesFrom(sfas[j].InitialState)) { cond2 = solver.MkOr(cond2, move.Label); } S checkCond = solver.MkAnd(cond1, cond2); isDeterministic = (checkCond.Equals(solver.False)); if (!isDeterministic) { break; } } if (!isDeterministic) { break; } } } if (allFinalSink) { finalStates.Add(sinkId); //this will be the final state } Dictionary <int, int> stateRenamingMap = new Dictionary <int, int>(); foreach (var sfa in sfas) { foreach (var move in sfa.GetMoves()) { int source = (allSingleSource && sfa.InitialState == move.SourceState ? start : move.SourceState); int target = (allFinalSink && sfa.FinalState == move.TargetState ? sinkId : move.TargetState); var p = new Pair <int, int>(source, target); stateRenamingMap[move.SourceState] = source; stateRenamingMap[move.TargetState] = target; if (move.IsEpsilon) { if (source != target) { eMoves.Add(new Pair <int, int>(source, target)); } continue; } S cond; if (conditionMap.TryGetValue(p, out cond)) { conditionMap[p] = solver.MkOr(cond, move.Label); //join the conditions into a disjunction } else { conditionMap[p] = move.Label; } } if (!allFinalSink) { foreach (int s in sfa.GetFinalStates()) { int s1 = stateRenamingMap[s]; if (!finalStates.Contains(s1)) { finalStates.Add(s1); } } } } Automaton <S> res = Automaton <S> .Create(solver, start, finalStates, GenerateMoves(conditionMap, eMoves)); res.isDeterministic = isDeterministic; return(res); }