public static int GetSMTVariables(PDLPred phi, IEnumerable<char> alphabet)
        {
            CPDLPred choiceTree = phi.GetCPDL();
            HashSet<char> alphabetHashSet = new HashSet<char>(alphabet);

            Context z3Context = new Context();
            Solver z3Solver = z3Context.MkSolver();

            VariableCache variableGenerator = VariableCache.Create(VariableCache.ConstraintMode.BOTH);
            choiceTree.ToSMTConstraints(z3Context, z3Solver, alphabetHashSet.Count, variableGenerator);
            variableGenerator.GenerateAdditionalConstraints(z3Context, z3Solver);

            return variableGenerator.GetNumVariables();
        }
        public static IEnumerable<PDLPred> GeneratePDLWithEDn(PDLPred phi, IEnumerable<char> alphabet, VariableCache.ConstraintMode constConst, PdlFilter.Filtermode filtermode)
        {
            CPDLPred choiceTree = phi.GetCPDL();
            HashSet<char> alphabetHashSet = new HashSet<char>(alphabet);

            PdlFilter filter = PdlFilter.Create(filtermode, phi, alphabetHashSet);

            // Concretize yields all feasible concretizations of the choiceTree
            foreach(PDLPred candidate in Concretize(choiceTree, alphabetHashSet, constConst)) {
                if (filter.KeepPredicate(candidate) == true)
                {
                    yield return candidate;
                }
            }
        }