def test_satisfiable_all_models(): assert next(satisfiable(False, all_models=True)) is False assert list(satisfiable((a >> ~a) & a, all_models=True)) == [False] assert list(satisfiable(True, all_models=True)) == [{true: true}] assert next(satisfiable(a & ~a, all_models=True)) is False models = [{a: True, b: False}, {a: False, b: True}] result = satisfiable(a ^ b, all_models=True) models.remove(next(result)) models.remove(next(result)) pytest.raises(StopIteration, lambda: next(result)) assert not models assert list(satisfiable(Equivalent(a, b), all_models=True)) == [{a: False, b: False}, {a: True, b: True}] models = [{a: False, b: False}, {a: False, b: True}, {a: True, b: True}] for model in satisfiable(a >> b, all_models=True): models.remove(model) assert not models # This is a santiy test to check that only the required number # of solutions are generated. The expr below has 2**100 - 1 models # which would time out the test if all are generated at once. X = [Symbol(f'x{i}') for i in range(100)] result = satisfiable(Or(*X), all_models=True) for _ in range(10): assert next(result)
def test_satisfiable_non_symbols(): class Zero(Boolean): pass assumptions = Zero(x*y) facts = Implies(Zero(x*y), Zero(x) | Zero(y)) query = ~Zero(x) & ~Zero(y) refutations = [ {Zero(x): True, Zero(x*y): True}, {Zero(y): True, Zero(x*y): True}, {Zero(x): True, Zero(y): True, Zero(x*y): True}, {Zero(x): True, Zero(y): False, Zero(x*y): True}, {Zero(x): False, Zero(y): True, Zero(x*y): True}] assert not satisfiable(And(assumptions, facts, query), algorithm='dpll') assert satisfiable(And(assumptions, facts, ~query), algorithm='dpll') in refutations assert not satisfiable(And(assumptions, facts, query), algorithm='dpll2') assert satisfiable(And(assumptions, facts, ~query), algorithm='dpll2') in refutations
def test_satisfiable_all_models(): assert next(satisfiable(False, all_models=True)) is False assert list(satisfiable((A >> ~A) & A, all_models=True)) == [False] assert list(satisfiable(True, all_models=True)) == [{true: true}] models = [{A: True, B: False}, {A: False, B: True}] result = satisfiable(A ^ B, all_models=True) models.remove(next(result)) models.remove(next(result)) pytest.raises(StopIteration, lambda: next(result)) assert not models assert list(satisfiable(Equivalent(A, B), all_models=True)) == \ [{A: False, B: False}, {A: True, B: True}] models = [{A: False, B: False}, {A: False, B: True}, {A: True, B: True}] for model in satisfiable(A >> B, all_models=True): models.remove(model) assert not models # This is a santiy test to check that only the required number # of solutions are generated. The expr below has 2**100 - 1 models # which would time out the test if all are generated at once. sym = numbered_symbols() X = [next(sym) for i in range(100)] result = satisfiable(Or(*X), all_models=True) for i in range(10): assert next(result)
def test_satisfiable_bool(): assert satisfiable(true) == {true: true} assert satisfiable(false) is False
def test_satisfiable(): assert satisfiable(A & (A >> B) & ~B) is False assert next(satisfiable(A & ~A, all_models=True)) is False
def test_satisfiable(algorithm): assert satisfiable(true, algorithm=algorithm) == {true: true} assert satisfiable(false, algorithm=algorithm) is False assert satisfiable(a & ~a, algorithm=algorithm) is False assert satisfiable(a & ~b, algorithm=algorithm) == {a: True, b: False} assert satisfiable(a | b, algorithm=algorithm) in ({a: True}, {b: True}, {a: True, b: True}) assert satisfiable((~a | b) & (~b | a), algorithm=algorithm) in ({a: True, b: True}, {a: False, b: False}) assert satisfiable((a | b) & (~b | c), algorithm=algorithm) in ({a: True, b: False}, {a: True, c: True}, {b: True, c: True}, {a: True, c: True, b: False}) assert satisfiable(a & (a >> b) & ~b, algorithm=algorithm) is False assert satisfiable(a & b & c, algorithm=algorithm) == {a: True, b: True, c: True} assert satisfiable((a | b) & (a >> b), algorithm=algorithm) in ({b: True}, {b: True, a: False}) assert satisfiable(Equivalent(a, b) & a, algorithm=algorithm) == {a: True, b: True} assert satisfiable(Equivalent(a, b) & ~a, algorithm=algorithm) == {a: False, b: False} class Zero(Boolean): pass assumptions = Zero(x*y) facts = Zero(x*y) >> (Zero(x) | Zero(y)) query = ~Zero(x) & ~Zero(y) refutations = [{Zero(x): True, Zero(x*y): True}, {Zero(y): True, Zero(x*y): True}, {Zero(x): True, Zero(y): True, Zero(x*y): True}, {Zero(x): True, Zero(y): False, Zero(x*y): True}, {Zero(x): False, Zero(y): True, Zero(x*y): True}] assert not satisfiable(assumptions & facts & query, algorithm=algorithm) assert satisfiable(assumptions & facts & ~query, algorithm=algorithm) in refutations