Exemplo n.º 1
0
 private bool AreDistinguishable(ThreeAutomaton <S> fa, Equivalence E, Tuple <int, int> pq, IBooleanAlgebraPositive <S> solver)
 {
     foreach (Move <S> from_p in fa.GetMovesFrom(pq.Item1))
     {
         foreach (Move <S> from_q in fa.GetMovesFrom(pq.Item2))
         {
             if (from_p.TargetState != from_q.TargetState &&
                 !E.AreEquiv(from_p.TargetState, from_q.TargetState))
             {
                 if (solver.IsSatisfiable(solver.MkAnd(from_p.Label, from_q.Label)))
                 {
                     return(true);
                 }
             }
         }
     }
     return(false);
 }
Exemplo n.º 2
0
        /// <summary>
        /// Checks that for all states q, if q has two or more outgoing
        /// moves then the conditions of the moves are pairwise disjoint, i.e.,
        /// their conjunction is unsatisfiable.
        /// If the check succeeds, sets IsDeterministic to true.
        /// Throws AutomataException if the FSA is not epsilon-free.
        /// </summary>
        /// <param name="solver">used to make conjunctions and to check satisfiability of resulting conditions</param>
        public void CheckDeterminism(IBooleanAlgebraPositive <S> solver, bool resetIsDeterministicToFalse = false)
        {
            if (resetIsDeterministicToFalse)
            {
                isDeterministic = false;
            }

            if (isDeterministic) //already known to be deterministic
            {
                return;
            }

            foreach (int state in States)
            {
                //Normal Moves
                var moves = delta[state];
                int k     = moves.Count;
                if (k > 1)
                {
                    S sofar = moves[0].action.guard;
                    for (int i = 1; i < k; i++)
                    {
                        var sofar_and_i = solver.MkAnd(sofar, moves[i].action.guard);
                        if (solver.IsSatisfiable(sofar_and_i))
                        {
                            isDeterministic = false;
                            return; //nondeterministic
                        }

                        if (i < k - 1)
                        {
                            sofar = solver.MkOr(sofar, moves[i].action.guard);
                        }
                    }
                }

                //Final moves
                var finmoves = deltaFinal[state];
                k = finmoves.Count;
                if (k > 1)
                {
                    S sofar = finmoves[0].action.guard;
                    for (int i = 1; i < k; i++)
                    {
                        var sofar_and_i = solver.MkAnd(sofar, finmoves[i].action.guard);
                        if (solver.IsSatisfiable(sofar_and_i))
                        {
                            isDeterministic = false;
                            return; //nondeterministic
                        }

                        if (i < k - 1)
                        {
                            sofar = solver.MkOr(sofar, finmoves[i].action.guard);
                        }
                    }
                }

                //Fin vs nonfin
                foreach (var move in delta[state])
                {
                    foreach (var finalMove in deltaFinal[state])
                    {
                        if (move.action.lookahead <= finalMove.action.lookahead) //Move does not have longer lookahead than fin move
                        {
                            if (solver.IsSatisfiable(solver.MkAnd(move.action.guard, finalMove.action.guard)))
                            {
                                isDeterministic = false;
                                return; //nondeterministic
                            }
                        }
                    }
                }
            }
            isDeterministic = true; //deterministic
        }