/* Generate the transition relation R */
        private FormulaNode GenTransition(SymbolicState from, SymbolicState to)
        {
            List <FormulaNode> terms = new List <FormulaNode>();

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

                // if e = EX(g), generate the term "e(from) | ~g(to)"
                FormulaNode body    = e[0]; // the formula inside the EX
                FormulaNode notBody = CTLUtils.nnfNegate(body);
                FormulaNode left    = from.ValueOf(e);
                FormulaNode right   = to.ValueOf(notBody);
                terms.Add(new FormulaNode(LogicOperator.OR, left, right));
            }

            return(JoinTerms(LogicOperator.AND, terms));
        }
        public bool Check()
        {
            SymbolicState v = new SymbolicState(elementary, "v");

            // initially, all possible states belong to the structure
            FormulaNode states = new FormulaNode(FormulaNode.TRUE_LITERAL);
            FormulaNode oldStates;

            while (true)
            {
                iterations++;
#if DEBUG
                Console.WriteLine("Iteration " + iterations.ToString());
#endif
                oldStates = states;
                FormulaNode succ = GenSucc(states, v);
                FormulaNode lc1  = GenLC1(states, v);
                FormulaNode e    = GenE(states, v);
                FormulaNode a    = GenA(states, v);

                states = new FormulaNode(LogicOperator.AND, states, succ);
                states = new FormulaNode(LogicOperator.AND, states, lc1);
                states = new FormulaNode(LogicOperator.AND, states, e);
                states = new FormulaNode(LogicOperator.AND, states, a);
                if (IsFixpoint(oldStates, states, v))
                {
                    break;
                }
            }
#if DEBUG
            Console.WriteLine("Reached fixpoint. Checking for satisfying state");
#endif
            FormulaNode formulaValue    = v.ValueOf(normalized);
            FormulaNode formulaAndValid = new FormulaNode(LogicOperator.AND, states, formulaValue);
            FormulaNode sat             = v.Quantify(LogicOperator.EXISTS, formulaAndValid);
            return(FormulaCNF.QBFSAT(sat));
        }