private FormulaNode GenLC1(FormulaNode stateSet, SymbolicState state)
        {
            List <FormulaNode> terms = new List <FormulaNode>();

            foreach (var e in elementary)
            {
                if (e.GetLogicOperator() != LogicOperator.EX)
                {
                    continue;
                }

                string        nextName         = "succ" + uniqueId.GetTicket().ToString();
                SymbolicState next             = new SymbolicState(elementary, nextName);
                FormulaNode   existsInState    = state.ValueOf(e);
                FormulaNode   notExistsInState = new FormulaNode(LogicOperator.NOT, existsInState, null);
                FormulaNode   nextValid        = SymbolicState.Substitute(stateSet, state, next);
                FormulaNode   transition       = GenTransition(state, next);
                FormulaNode   body             = e[0];
                FormulaNode   occursNext       = next.ValueOf(body);
                FormulaNode   hasSucc          = new FormulaNode(LogicOperator.AND, nextValid, transition);
                hasSucc = new FormulaNode(LogicOperator.AND, hasSucc, occursNext);
                hasSucc = next.Quantify(LogicOperator.EXISTS, hasSucc);
                terms.Add(new FormulaNode(LogicOperator.OR, notExistsInState, hasSucc));
            }
            return(JoinTerms(LogicOperator.AND, terms));
        }
        /*
         * <au> is an elementary formula of the form EX(ER(p,q))
         */
        private FormulaNode ComputeAUFragment(FormulaNode au, FormulaNode stateSet, SymbolicState state)
        {
#if DEBUG
            Console.WriteLine("Computing fragment for " + au);
#endif
            FormulaNode frag     = FormulaParser.Parse("~TRUE");
            FormulaNode notLeft  = new FormulaNode(LogicOperator.NOT, au[0][0], null);
            FormulaNode notRight = new FormulaNode(LogicOperator.NOT, au[0][1], null);
            while (true)
            {
                string        nextName   = "succ" + uniqueId.GetTicket().ToString();
                SymbolicState next       = new SymbolicState(elementary, nextName);
                FormulaNode   transition = GenTransition(state, next);
                FormulaNode   memberOf   = SymbolicState.Substitute(stateSet, state, next);
                FormulaNode   nextFrag   = SymbolicState.Substitute(frag, state, next);
                FormulaNode   newFrag    = new FormulaNode(LogicOperator.AND, transition, memberOf);
                newFrag = new FormulaNode(LogicOperator.AND, newFrag, nextFrag);
                newFrag = next.Quantify(LogicOperator.EXISTS, newFrag);

                newFrag = new FormulaNode(LogicOperator.AND, state.ValueOf(notLeft.NNF()), newFrag);

                // Add the big conjunction needed for fragAU
                List <FormulaNode> fragTerms = new List <FormulaNode>();

                foreach (FormulaNode el in elementary)
                {
                    if (el.GetLogicOperator() != LogicOperator.EX)
                    {
                        continue;
                    }

                    nextName   = "succ" + uniqueId.GetTicket().ToString();
                    next       = new SymbolicState(elementary, nextName);
                    transition = GenTransition(state, next);
                    memberOf   = SymbolicState.Substitute(stateSet, state, next);
                    nextFrag   = SymbolicState.Substitute(frag, state, next);


                    FormulaNode lhs = state.ValueOf(el);
                    FormulaNode rhs = new FormulaNode(LogicOperator.AND, transition, memberOf);
                    rhs = new FormulaNode(LogicOperator.AND, rhs, nextFrag);
                    rhs = new FormulaNode(LogicOperator.AND, rhs, next.ValueOf(SymbolicState.Substitute(el[0], state, next)));
                    rhs = next.Quantify(LogicOperator.EXISTS, rhs);

                    fragTerms.Add(new FormulaNode(LogicOperator.IMP, lhs, rhs));
                }

                newFrag = new FormulaNode(LogicOperator.AND, newFrag, JoinTerms(LogicOperator.AND, fragTerms));
                newFrag = new FormulaNode(LogicOperator.OR, state.ValueOf(notRight.NNF()), newFrag);

                if (IsFixpoint(newFrag, frag, state))
                {
                    return(frag);
                }

                frag = newFrag;
            }
        }
        /* Generates a formula representing the fact that <state> has a
         * successor in <stateSet>. Does not guarantee that <state> itself
         * belongs to the set.
         */
        private FormulaNode GenSucc(FormulaNode stateSet, SymbolicState state)
        {
            string        nextName   = "succ" + uniqueId.GetTicket().ToString();
            SymbolicState next       = new SymbolicState(elementary, nextName);
            FormulaNode   transition = GenTransition(state, next);
            FormulaNode   memberOf   = SymbolicState.Substitute(stateSet, state, next);
            FormulaNode   result     = new FormulaNode(LogicOperator.AND, transition, memberOf);

            result = next.Quantify(LogicOperator.EXISTS, result);
            return(result);
        }
        private void ComputeEUFragments(FormulaNode stateSet, SymbolicState state)
        {
            #if DEBUG
            Console.WriteLine("Compute fragments");
#endif
            foreach (var e in elementary)
            {
                if (e.GetLogicOperator() != LogicOperator.EX)
                {
                    continue;
                }
                if (e[0].GetLogicOperator() != LogicOperator.EU)
                {
                    continue;
                }
#if DEBUG
                Console.WriteLine("Computing fragment for " + e);
#endif
                FormulaNode frag = FormulaParser.Parse("~TRUE");
                while (true)
                {
                    string        nextName   = "succ" + uniqueId.GetTicket().ToString();
                    SymbolicState next       = new SymbolicState(elementary, nextName);
                    FormulaNode   transition = GenTransition(state, next);
                    FormulaNode   memberOf   = SymbolicState.Substitute(stateSet, state, next);
                    FormulaNode   nextFrag   = SymbolicState.Substitute(frag, state, next);
                    FormulaNode   newFrag    = new FormulaNode(LogicOperator.AND, transition, memberOf);
                    newFrag = new FormulaNode(LogicOperator.AND, newFrag, nextFrag);
                    newFrag = next.Quantify(LogicOperator.EXISTS, newFrag);

                    newFrag = new FormulaNode(LogicOperator.AND, state.ValueOf(e[0][0]), newFrag);
                    newFrag = new FormulaNode(LogicOperator.OR, state.ValueOf(e[0][1]), newFrag);

                    if (IsFixpoint(newFrag, frag, state))
                    {
                        break;
                    }

                    frag = newFrag;
                }
                fragEU[e[0]] = frag;
            }
        }