Example #1
0
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
Example #2
0
def formulaRekSkolemize(f, variables, subst):
    """
    Perform Skolemization of f, which is assumed to be in the scope of
    the list of variables provided.
    """
    if f.isLiteral():
        child = f.child1.instantiate(subst)
        f = Formula("", child)
    elif f.op == "?":
        var = f.child1
        skTerm = skolemGenerator(variables)
        oldbinding = subst.modifyBinding((var, skTerm))
        f = formulaRekSkolemize(f.child2, variables, subst)
        subst.modifyBinding((var, oldbinding))
    elif f.op == "!":
        var = f.child1
        variables.append(var)
        handle = formulaRekSkolemize(f.child2, variables, subst)
        f = Formula("!", var, handle)
        variables.pop()
    else:
        arg1 = None
        arg2 = None
        if f.hasSubform1():
            arg1 = formulaRekSkolemize(f.child1, variables, subst)
        if f.hasSubform2():
            arg2 = formulaRekSkolemize(f.child2, variables, subst)
        f = Formula(f.op, arg1, arg2)
    return f
Example #3
0
def formulaMiniScope(f):
    """
    Perform miniscoping, i.e. move quantors in as far as possible, so
    that their scope is only the smallest subformula in which the
    variable occurs.
    """
    res = False
    if f.isQuantified():
        op = f.child2.op
        quant = f.op
        var = f.child1
        subf = f.child2
        if op == "&" or op == "|":
            if not var in subf.child1.collectFreeVars():
                # q[X]:(P op Q)  -> P op (q[X]:Q) if X not free in P
                arg2 = Formula(quant, var, subf.child2)
                arg1 = subf.child1
                f = Formula(op, arg1, arg2)
                res = True
            elif not var in subf.child2.collectFreeVars():
                # q[X]:(P op Q)  -> (q[X]:P) op Q if X not free in Q
                arg1 = Formula(quant, var, subf.child1)
                arg2 = subf.child2
                f = Formula(op, arg1, arg2)
                res = True
            else:
                if op == "&" and quant == "!":
                    # ![X]:(P&Q) -> ![X]:P & ![X]:Q
                    arg1 = Formula("!", var, subf.child1)
                    arg2 = Formula("!", var, subf.child2)
                    f = Formula("&", arg1, arg2)
                    res = True
                elif op == "|" and quant == "?":
                    # ?[X]:(P|Q) -> ?[X]:P | ?[X]:Q
                    arg1 = Formula("?", var, subf.child1)
                    arg2 = Formula("?", var, subf.child2)
                    f = Formula("|", arg1, arg2)
                    res = True
    arg1 = f.child1
    arg2 = f.child2
    modified = False
    if f.hasSubform1():
        arg1, m = formulaMiniScope(f.child1)
        modified |= m
    if f.hasSubform2():
        arg2, m = formulaMiniScope(f.child2)
        modified |= m
    if modified:
        f = Formula(f.op, arg1, arg2)
        f, m = formulaMiniScope(f)
        res = True
    return f, res
Example #4
0
def formulaVarRename(f, subst=None):
    """
    Rename variables in f so that all bound variables are unique.
    """
    if subst == None:
        subst = Substitution()

    if f.isQuantified():
        # New scope of a variable -> add a new binding to a new
        # variable. Store potential old binding to restore when
        # leaving the scope later
        var = f.child1
        newvar = freshVar()
        oldbinding = subst.modifyBinding((var, newvar))

    if f.isLiteral():
        # Create copy with the new variables recorded in subst
        child = f.child1.instantiate(subst)
        f = Formula("", child)
    else:
        # This is a composite formula. Rename it...
        arg1 = None
        arg2 = None
        if f.isQuantified():
            # Apply new renaming locally to the bound variable and
            # recusively to the subformula
            arg1 = newvar
            arg2 = formulaVarRename(f.child2, subst)
        else:
            # Apply renaming to all subformulas
            if f.hasSubform1():
                arg1 = formulaVarRename(f.child1, subst)
            if f.hasSubform2():
                arg2 = formulaVarRename(f.child2, subst)
        f = Formula(f.op, arg1, arg2)

    if f.isQuantified():
        # We are leaving the scope of the quantifier, so restore
        # substitution.
        subst.modifyBinding((var, oldbinding))

    return f