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)); }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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); }