コード例 #1
0
def dpll_satisfiable(expr):
    """
    Check satisfiability of a propositional sentence.
    It returns a model rather than True when it succeeds

    >>> from diofant.abc import A, B
    >>> from diofant.logic.algorithms.dpll import dpll_satisfiable
    >>> dpll_satisfiable(A & ~B) == {A: True, B: False}
    True
    >>> dpll_satisfiable(A & ~A)
    False
    """
    clauses = conjuncts(to_cnf(expr))
    if False in clauses:
        return False
    symbols = sorted(_find_predicates(expr), key=default_sort_key)
    symbols_int_repr = set(range(1, len(symbols) + 1))
    clauses_int_repr = to_int_repr(clauses, symbols)
    result = dpll_int_repr(clauses_int_repr, symbols_int_repr, {})
    if not result:
        return result
    output = {}
    for key in result:
        output.update({symbols[key - 1]: result[key]})
    return output
コード例 #2
0
def dpll_satisfiable(expr, all_models=False):
    """
    Check satisfiability of a propositional sentence.
    It returns a model rather than True when it succeeds.
    Returns a generator of all models if all_models is True.

    Examples
    ========

    >>> from diofant.abc import A, B
    >>> from diofant.logic.algorithms.dpll2 import dpll_satisfiable
    >>> dpll_satisfiable(A & ~B) == {A: True, B: False}
    True
    >>> dpll_satisfiable(A & ~A)
    False
    """
    clauses = conjuncts(to_cnf(expr))
    if False in clauses:
        if all_models:
            return (f for f in [False])
        return False
    symbols = sorted(_find_predicates(expr), key=default_sort_key)
    symbols_int_repr = range(1, len(symbols) + 1)
    clauses_int_repr = to_int_repr(clauses, symbols)

    solver = SATSolver(clauses_int_repr, symbols_int_repr, set(), symbols)
    models = solver._find_model()

    if all_models:
        return _all_models(models)

    try:
        return next(models)
    except StopIteration:
        return False
コード例 #3
0
def test_to_cnf():

    assert to_cnf(~(B | C)) == And(Not(B), Not(C))
    assert to_cnf((A & B) | C) == And(Or(A, C), Or(B, C))
    assert to_cnf(A >> B) == (~A) | B
    assert to_cnf(A >> (B & C)) == (~A | B) & (~A | C)
    assert to_cnf(A & (B | C) | ~A & (B | C), True) == B | C

    assert to_cnf(Equivalent(A, B)) == And(Or(A, Not(B)), Or(B, Not(A)))
    assert to_cnf(Equivalent(A, B & C)) == \
        (~A | B) & (~A | C) & (~B | ~C | A)
    assert to_cnf(Equivalent(A, B | C), True) == \
        And(Or(Not(B), A), Or(Not(C), A), Or(B, C, Not(A)))
    assert to_cnf(~(A | B) | C) == And(Or(Not(A), C), Or(Not(B), C))
コード例 #4
0
def satisfiable(expr, algorithm="dpll2", all_models=False):
    """
    Check satisfiability of a propositional sentence.
    Returns a model when it succeeds.
    Returns {true: true} for trivially true expressions.

    On setting all_models to True, if given expr is satisfiable then
    returns a generator of models. However, if expr is unsatisfiable
    then returns a generator containing the single element False.

    Examples
    ========

    >>> from diofant.abc import A, B
    >>> from diofant.logic.inference import satisfiable
    >>> satisfiable(A & ~B) == {A: True, B: False}
    True
    >>> satisfiable(A & ~A)
    False
    >>> satisfiable(True)
    {true: True}
    >>> next(satisfiable(A & ~A, all_models=True))
    False
    >>> models = satisfiable((A >> B) & B, all_models=True)
    >>> next(models) == {A: False, B: True}
    True
    >>> next(models) == {A: True, B: True}
    True
    >>> def use_models(models):
    ...     for model in models:
    ...         if model:
    ...             # Do something with the model.
    ...             return model
    ...         else:
    ...             # Given expr is unsatisfiable.
    ...             print("UNSAT")
    >>> use_models(satisfiable(A >> ~A, all_models=True))
    {A: False}
    >>> use_models(satisfiable(A ^ A, all_models=True))
    UNSAT
    """
    expr = to_cnf(expr)
    if algorithm == "dpll":
        from diofant.logic.algorithms.dpll import dpll_satisfiable
        return dpll_satisfiable(expr)
    elif algorithm == "dpll2":
        from diofant.logic.algorithms.dpll2 import dpll_satisfiable
        return dpll_satisfiable(expr, all_models)
    else:  # pragma: no cover
        raise NotImplementedError
コード例 #5
0
    def retract(self, sentence):
        """Remove the sentence's clauses from the KB

        Examples
        ========

        >>> from diofant.logic.inference import PropKB
        >>> from diofant.abc import x, y
        >>> l = PropKB()
        >>> l.clauses
        []

        >>> l.tell(x | y)
        >>> l.clauses
        [Or(x, y)]

        >>> l.retract(x | y)
        >>> l.clauses
        []
        """
        for c in conjuncts(to_cnf(sentence)):
            self.clauses_.discard(c)
コード例 #6
0
    def tell(self, sentence):
        """Add the sentence's clauses to the KB

        Examples
        ========

        >>> from diofant.logic.inference import PropKB
        >>> from diofant.abc import x, y
        >>> l = PropKB()
        >>> l.clauses
        []

        >>> l.tell(x | y)
        >>> l.clauses
        [Or(x, y)]

        >>> l.tell(y)
        >>> l.clauses
        [y, Or(x, y)]
        """
        for c in conjuncts(to_cnf(sentence)):
            self.clauses_.add(c)