public CNF2State(CNF2State c1, CNF2State c2)
 {
     pClauses = new Dictionary <string, Clause>();
     foreach (var c in c1.clauses)
     {
         pClauses[c.ToString()] = c;
     }
     foreach (var c in c2.clauses)
     {
         pClauses[c.ToString()] = c;
     }
     pDefinitions = new Dictionary <string, Clause>();
     foreach (var c in c1.definitions.Union(c2.definitions))
     {
         pDefinitions[c.ToString()] = c;
     }
     Debug.Assert(clauses.Union(definitions).All(c => !c.isTrue));
 }
Exemple #2
0
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public CNF2State cnf2i(IFormula f) //skolemized etc
        {
            CNF2State result;

            if (f is PredicateApplication)
            {
                result = new CNF2State(f as PredicateApplication, true);
            }
            else if (f is EqualityFormula)
            {
                result = new CNF2State(f as EqualityFormula, true);
            }
            else if (f is Not)
            {
                var nf = f as Not;
                if (nf.f is PredicateApplication)
                {
                    result = new CNF2State(nf.f as PredicateApplication, false);
                }
                else if (nf.f is EqualityFormula)
                {
                    result = new CNF2State(nf.f as EqualityFormula, false);
                }
                else
                {
                    throw new Exception();
                }
            }
            else if (f is UniversalFormula)
            {
                result = cnf2i((f as UniversalFormula).f);
            }
            else if (f is True)
            {
                result = new CNF2State(true);
            }
            else if (f is False)
            {
                result = new CNF2State(false);
            }
            else if (f is And)
            {
                var af = f as And;
                result = new CNF2State(cnf2i(af.f1), cnf2i(af.f2));
            }
            else if (f is Or) // /\a_i \/ /\b_j => (Na <-> /\a_i) /\ (Nb <-> /\b_j) /\ (Na\/Nb)
            {
                var of  = f as Or;
                var cs1 = cnf2i(of.f1);
                var cs2 = cnf2i(of.f2);
                //                Console.WriteLine("\tcnf:dis {0}x{1}", cs1.Count, cs2.Count);
                var d  = new SortedSet <Clause>(cs1.definitions.Union(cs2.definitions).Except(new [] { new Clause(true) }));
                var cs = new SortedSet <Clause>();
                //                Console.WriteLine("Oring {0} and {1}", cs1.clauses.ToString(), cs2.clauses.ToString());
                Debug.Assert(cs1.clauses.Any() || !cs1.definitions.Any());
                Debug.Assert(cs2.clauses.Any() || !cs2.definitions.Any());
//                Debug.Assert(cs1.clauses.Any() && cs2.clauses.Any());

                if (!cs1.clauses.Any() || !cs2.clauses.Any()) //true
                {
                }
                else if (cs1.clauses.Count() == 1 && cs2.clauses.Count() == 1)
                {
                    var c = new List <Literal>();
                    if (!cs1.clauses.First().isTrue&& !cs2.clauses.First().isTrue)
                    {
                        foreach (var a in cs1.clauses.First().literals)
                        {
                            c.Add(a);
                        }
                        foreach (var a in cs2.clauses.First().literals)
                        {
                            c.Add(a);
                        }
                        cs.Add(new Clause(c));
                    }
                }
                else if (cs1.clauses.Count() == 1)
                {
                    if (!cs1.clauses.First().isTrue)
                    {
                        foreach (var c in cs2.clauses)
                        {
                            cs.Add(new Clause(cs1.clauses.First().literals.Union(c.literals)));
                        }
                    }
                }
                else if (cs2.clauses.Count() == 1)
                {
                    if (!cs2.clauses.First().isTrue)
                    {
                        foreach (var c in cs1.clauses)
                        {
                            cs.Add(new Clause(cs2.clauses.First().literals.Union(c.literals)));
                        }
                    }
                }
                else
                {
                    var N1 = makeDefinition(d, cs1.clauses);
                    var N2 = makeDefinition(d, cs2.clauses);

                    var fvs1 = freeVariables(cs1.clauses).ToArray();
                    var fvs2 = freeVariables(cs2.clauses).ToArray();
                    var c    = new List <Literal>
                    {
                        new Literal(
                            new PredicateApplication(N1,
                                                     (from fv in fvs1 select new Variable(fv)).ToArray()),
                            true),
                        new Literal(
                            new PredicateApplication(N2,
                                                     (from fv in fvs2 select new Variable(fv)).ToArray()),
                            true)
                    };
                    cs.Add(new Clause(c));
                }
                result = new CNF2State(cs.Except(new [] { new Clause(true) }), d.Except(new [] { new Clause(true) }));
                //                Console.WriteLine(" = {0}", result.clauses.ToString());
            }
            else
            {
                throw new Exception();
            }
//            Debug.Assert(result.clauses.Union(result.definitions).All(c => c.freeVariables.All(fv=>!BooleanType.isBoolean(fv.type))));
            return(result);
        }