示例#1
0
def propagate_known_value(literal: Literal, formula: List[Clause]) -> List[Clause]:
    """
    Simplifies `formula` based on `literal`. If literal is +x, then any clauses containing +x can be removed and all
    -x literals can be removed. The simplified formula is returned.
    """
    clauses_purged = purge_clauses_with_literal(literal, deepcopy(formula))

    flipped_literal = Literal(literal.name, not literal.sign)
    both_purged = purge_literal(flipped_literal, clauses_purged)

    return both_purged
def sentences():
    a = Literal("A", False)
    b = Literal("B", False)
    c = Literal("C", False)
    d = Literal("D", False)
    e = Literal("E", False)
    f = Literal("F", False)
    not_a = -a
    not_b = -b
    not_c = -c
    not_d = -d
    not_e = -e
    not_f = -f
    dt = dict()
    dt['a'] = a
    dt['b'] = b
    dt['c'] = c
    dt['d'] = d
    dt['e'] = e
    dt['f'] = f
    dt['not_a'] = not_a
    dt['not_b'] = not_b
    dt['not_c'] = not_c
    dt['not_d'] = not_d
    dt['not_e'] = not_e
    dt['not_f'] = not_f
    return dt
def do_pure_literal_elimination(
        formula: List[Clause]) -> (List[Clause], Mapping[int, bool]):
    known_mapping: Mapping[int, bool] = {}
    new_formula = deepcopy(formula)

    variables = get_variables(formula)
    for variable in variables:
        # Check variable purity on original formula because variables might get removed during purging. Purity does not
        # change across purges, so we're safe to use the original formula.
        variable_purity = get_variable_purity(variable, formula)
        if variable_purity is not None:
            new_formula = purge_clauses_with_literal(
                Literal(variable, variable_purity), new_formula)
            known_mapping[variable] = variable_purity

    return new_formula, known_mapping
示例#4
0
def read_input(cnfFile: str):
    variableSet = []
    clauseSet = []
    nextCID = 0
    with open(cnfFile, "r") as f:
        for line in f.readlines():
            tokens = line.strip().split()
            if tokens and tokens[0] != "p" and tokens[0] != "c":
                literals = []
                for lit in tokens[:-1]:
                    sign = lit[0] != "-"
                    variable = lit.strip("-")

                    literals.append(Literal(variable, sign))
                    if variable not in variableSet:
                        variableSet.append(variable)

                clauseSet.append(Clause(nextCID, literals))
                nextCID += 1

    return variableSet, clauseSet
def do_unit_elimination(
        formula: List[Clause]) -> (List[Clause], Mapping[bool, int]):
    """
    For every unit clause with variable {+/-x} in formula, removes non-unit clauses containing {+/-x}, all literals that
    are {-/+x} (flipped sign!), and assigns x a boolean value according to its polarity. Returns a tuple with the
    modified formula and the mapping that was created.
    """
    known_values = {}
    unit_clauses = get_unit_clauses(formula)
    new_formula = deepcopy(formula)

    for unit in unit_clauses:
        unit_literal = unit.literals[0]
        flipped_literal = Literal(unit_literal.name, not unit_literal.sign)

        new_formula = purge_non_unit_clauses_with_literal(
            unit_literal, new_formula)
        new_formula = purge_literal(flipped_literal, new_formula)

        known_values[unit_literal.name] = unit_literal.sign

    return new_formula, known_values
    for clause in formula:
        for literal in clause.literals:
            if target == literal.name:
                if polarity is None:
                    polarity = literal.sign
                else:
                    if not polarity == literal.sign:
                        return None

    return polarity


if __name__ == "__main__":
    # (!x)
    assert (get_variable_purity(1, [Clause("foo", [Literal(1, False)])]) is
            False)

    # (x or !z) AND (!z or x)
    everything_pure = [
        Clause("foo", [Literal(1, True), Literal(3, False)]),
        Clause("bar", [Literal(3, False), Literal(1, True)])
    ]
    assert (get_variable_purity(1, everything_pure))
    assert (get_variable_purity(3, everything_pure) is False)

    # (x or y) AND (!x or !y). Ensure global purity, not clausal purity.
    global_purity_check = [
        Clause("foo", [Literal(1, True), Literal(2, True)]),
        Clause("bar", [Literal(1, False), Literal(2, False)])
    ]
from util import purge_non_unit_clauses_with_literal, purge_literal
from copy import deepcopy


def get_unit_clauses(formula: List[Clause]) -> List[Clause]:
    """
    Returns a list of the unit clauses in `formula`
    """
    return [clause for clause in formula if len(clause.literals) == 1]


if __name__ == "__main__":
    # (x or x) is not valid, so we won't test clauses that have repetitive Literals.

    # (x or !x) is valid, however.
    plus_or_minus = [Clause("foo", [Literal(1, True), Literal(1, False)])]
    assert (get_unit_clauses(plus_or_minus) == [])

    # (x) and (!x or y) and (z)
    three_clauses = [
        Clause("foo", [Literal(1, True)]),
        Clause("bar", [Literal(1, False), Literal(2, True)]),
        Clause("baz", [Literal(3, True)])
    ]
    unit_clauses = [
        Clause("foo", [Literal(1, True)]),
        Clause("baz", [Literal(3, True)])
    ]
    assert (get_unit_clauses(three_clauses) == unit_clauses)

示例#8
0
# A series of Clause/Literal manipulators and accessors.


def purge_literal(literal: Literal, formula: List[Clause]) -> List[Clause]:
    """
    Removes all instance of `literal` from all Clauses in `formula`
    """
    for clause in formula:
        clause.remove_literal(literal)

    return formula


if __name__ == "__main__":
    # (x) -x-> ()
    assert(purge_literal(Literal(1, True), [Clause("foo", [Literal(1, True)])]) == [Clause("foo", [])])

    # (x or !x) -x-> (!x)
    assert (purge_literal(Literal(1, True), [Clause("foo", [
        Literal(1, True), Literal(1, False)])]) == [Clause("foo", [Literal(1, False)])])

    # (x or y) -z-> (x or y)
    assert (purge_literal(Literal(3, True), [Clause("foo", [
        Literal(1, True), Literal(2, True)
    ])]) == [Clause("foo", [Literal(1, True), Literal(2, True)])])


def purge_clauses_with_literal(literal: Literal, formula: List[Clause]) -> List[Clause]:
    """
    Removes all clauses that contain `literal` from `formula` and returns the new formula. Should be used to simplify
    a formula after making a guess.