def formulaDistributeDisjunctions(f): """ Convert a Skolemized formula in prefix-NNF form into Conjunctive Normal Form. """ arg1 = None arg2 = None if f.isQuantified(): arg1 = f.child1 arg2 = formulaDistributeDisjunctions(f.child2) f = Formula(f.op, arg1, arg2) elif f.isLiteral(): pass else: if f.hasSubform1(): arg1 = formulaDistributeDisjunctions(f.child1) if f.hasSubform2(): arg2 = formulaDistributeDisjunctions(f.child2) f = Formula(f.op, arg1, arg2) if f.op == "|": if f.child1.op == "&": # (P&Q)|R -> (P|R) & (Q|R) arg1 = Formula("|", f.child1.child1, f.child2) arg2 = Formula("|", f.child1.child2, f.child2) f = Formula("&", arg1, arg2) f = formulaDistributeDisjunctions(f) elif f.child2.op == "&": # (R|(P&Q) -> (R|P) & (R|Q) arg1 = Formula("|", f.child1, f.child2.child1) arg2 = Formula("|", f.child1, f.child2.child2) f = Formula("&", arg1, arg2) f = formulaDistributeDisjunctions(f) return f
def formulaNNF(f, polarity): """ Convert f into a NNF. Equivalences (<=>) are eliminated polarity-dependend, top to bottom. Returns (f', m), where f' is a NNF of f, and m indicates if f!=f' """ normalform = False modified = False while not normalform: normalform = True f, m = rootFormulaNNF(f, polarity) modified |= m if f.op == "~": handle, m = formulaNNF(f.child1, -polarity) if m: normalform = False f = Formula("~", handle) elif f.op in ["!", "?"]: handle, m = formulaNNF(f.child2, polarity) if m: normalform = False f = Formula(f.op, f.child1, handle) elif f.op in ["|", "&"]: handle1, m1 = formulaNNF(f.child1, polarity) handle2, m2 = formulaNNF(f.child2, polarity) m = m1 or m2 if m: normalform = False f = Formula(f.op, handle1, handle2) else: assert f.isLiteral() modified |= m return f, modified