コード例 #1
0
            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);
                }
            }
コード例 #2
0
 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
     }
 }
コード例 #3
0
ファイル: IteBag.cs プロジェクト: teodorov/Automata-1
        /// <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);
        }
コード例 #4
0
ファイル: PushdownAutomaton.cs プロジェクト: michkot/Automata
            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);
                            }
                        }
                    }
                }
            }
コード例 #5
0
ファイル: PairBoolAlg.cs プロジェクト: OlliSaarikivi/Automata
        /// <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));
            }
        }
コード例 #6
0
ファイル: ThreeAutomaton.cs プロジェクト: teodorov/Automata-1
        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()));
        }
コード例 #7
0
ファイル: Rule.cs プロジェクト: teodorov/Automata-1
 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));
     }
 }
コード例 #8
0
ファイル: ThreeAutomaton.cs プロジェクト: teodorov/Automata-1
        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)));
        }
コード例 #9
0
        /// <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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
コード例 #10
0
        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);
        }