def dpll_satisfiable(expr): """ Check satisfiability of a propositional sentence. It returns a model rather than True when it succeeds >>> from sympy.abc import A, B >>> from sympy.logic.algorithms.dpll import dpll_satisfiable >>> dpll_satisfiable(A & ~B) {A: True, B: False} >>> 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
def dpll_satisfiable(expr): """ Check satisfiability of a propositional sentence. It returns a model rather than True when it succeeds Examples ======== >>> from sympy.abc import A, B >>> from sympy.logic.algorithms.dpll2 import dpll_satisfiable >>> dpll_satisfiable(A & ~B) {A: True, B: False} >>> 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 = range(1, len(symbols) + 1) clauses_int_repr = to_int_repr(clauses, symbols) solver = SATSolver(clauses_int_repr, symbols_int_repr, set()) result = solver._find_model() if not result: return result # Uncomment to confirm the solution is valid (hitting set for the clauses) #else: #for cls in clauses_int_repr: #assert solver.var_settings.intersection(cls) return dict((symbols[abs(lit) - 1], lit > 0) for lit in solver.var_settings)
def dpll_satisfiable(expr): """ Check satisfiability of a propositional sentence. It returns a model rather than True when it succeeds Examples ======== >>> from sympy.abc import A, B >>> from sympy.logic.algorithms.dpll2 import dpll_satisfiable >>> dpll_satisfiable(A & ~B) {A: True, B: False} >>> dpll_satisfiable(A & ~A) False """ symbols = sorted(_find_predicates(expr), key=default_sort_key) symbols_int_repr = range(1, len(symbols) + 1) clauses = conjuncts(to_cnf(expr)) clauses_int_repr = to_int_repr(clauses, symbols) solver = SATSolver(clauses_int_repr, symbols_int_repr, set()) result = solver._find_model() if not result: return result # Uncomment to confirm the solution is valid (hitting set for the clauses) #else: #for cls in clauses_int_repr: #assert solver.var_settings.intersection(cls) return dict( (symbols[abs(lit) - 1], lit > 0) for lit in solver.var_settings)
def is_simplerel(expr): from sympy.logic.boolalg import _find_predicates variables = _find_predicates(expr) relations = tuple(v for v in variables if isinstance(v, Rel)) if any(rel.args[1] != 0 for rel in relations): return False simple_form = {Eq: Eq, Ne: Eq, Gt: Gt, Le: Gt, Lt: Lt, Ge: Lt} return all(len(set(simple_form[rel.func] for rel in rels)) == 1 for _, rels in groupby(relations, lambda r: r.args[0]))
def dpll_satisfiable(expr): 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
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 sympy.abc import A, B >>> from sympy.logic.algorithms.dpll2 import dpll_satisfiable >>> dpll_satisfiable(A & ~B) {A: True, B: False} >>> 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
def logicrelsimp(expr, form='dnf', deep=True): """ logically simplify relations using totality (WARNING: it is unstable) >>> from sympy import * >>> from symplus.strplus import init_mprinting >>> init_mprinting() >>> x, y, z = symbols('x y z') >>> logicrelsimp((x>0) >> ((x<=0)&(y<0))) x =< 0 >>> logicrelsimp((x>0) >> (x>=0)) True >>> logicrelsimp((x<0) & (x>0)) False >>> logicrelsimp(((x<0) | (y>0)) & ((x>0) | (y<0))) (x < 0) /\ (y < 0) \/ (x > 0) /\ (y > 0) >>> logicrelsimp(((x<0) & (y>0)) | ((x>0) & (y<0))) (x < 0) /\ (y > 0) \/ (x > 0) /\ (y < 0) """ from sympy.core.symbol import Wild from sympy.core import sympify from sympy.logic.boolalg import (SOPform, POSform, to_nnf, _find_predicates, simplify_logic) Nt = lambda x: Not(x, evaluate=False) if form not in ('cnf', 'dnf'): raise ValueError("form can be cnf or dnf only") expr = sympify(expr) if not isinstance(expr, BooleanFunction): return expr # canonicalize relations expr = expr.replace(lambda rel: isinstance(rel, Rel), lambda rel: canonicalize_polyeq(rel)) # to nnf w = Wild('w') expr = to_nnf(expr) expr = expr.replace(Not(w), lambda w: Not(w, evaluate=True)) if is_simplerel(expr): # standardize relation expr = expr.replace(Ne(w,0), Nt(Eq(w,0))) expr = expr.replace(Ge(w,0), Nt(Lt(w,0))) expr = expr.replace(Le(w,0), Nt(Gt(w,0))) expr = simplify_logic(expr, form, deep) return expr else: # standardize relation expr = expr.replace(Ne(w,0), Or(Gt(w,0), Lt(w,0))) expr = expr.replace(Ge(w,0), Or(Gt(w,0), Eq(w,0))) expr = expr.replace(Le(w,0), Or(Lt(w,0), Eq(w,0))) # make totality variables = _find_predicates(expr) relations = (v for v in variables if isinstance(v, Rel) and v.args[1] == 0) totalities = [] for a in set(rel.args[0] for rel in relations): totalities.append( Or(And(Gt(a,0), Nt(Eq(a,0)), Nt(Lt(a,0))), And(Nt(Gt(a,0)), Eq(a,0), Nt(Lt(a,0))), And(Nt(Gt(a,0)), Nt(Eq(a,0)), Lt(a,0)))) totality = And(*totalities) # make truth table, don't care table truthtable = [] dontcares = [] for t in product([0, 1], repeat=len(variables)): t = list(t) if totality.xreplace(dict(zip(variables, t))) == False: dontcares.append(t) elif expr.xreplace(dict(zip(variables, t))) == True: truthtable.append(t) if deep: variables = [simplify(v) for v in variables] if form == 'dnf': expr = SOPform(variables, truthtable, dontcares) elif form == 'cnf': expr = POSform(variables, truthtable, dontcares) return expr
def syntestbench(s, numlit, numclause): numlit = int(numlit) numclause = int(numclause) print("--ANSWER TO THIS TEST BENCH") print("--", end="") print(satisfiable(s)) s = to_cnf(sympify(s)) symbols = sorted(_find_predicates(s), key=default_sort_key) symbols_int_repr = set(range(0, len(symbols))) to_print = [] if s.func != And: s1 = repeat_to_length(0, numlit) s2 = repeat_to_length(0, numlit) if s.func != Or: if s.is_Symbol: s1[symbols.index(s)] = 1 to_print.append(s1) to_print.append(s2) else: s2[symbols.index(Not(s))] = 1 to_print.append(s1) to_print.append(s2) else: for arg in s.args: if arg.is_Symbol: s1[symbols.index(arg)] = 1 else: s2[symbols.index(Not(arg))] = 1 to_print.append(s1) to_print.append(s2) else: clauses = s.args for clause in clauses: s1 = repeat_to_length(0, numlit) s2 = repeat_to_length(0, numlit) if clause.func != Or: if clause.is_Symbol: s1[symbols.index(clause)] = 1 to_print.append(s1) to_print.append(s2) else: s2[symbols.index(Not(clause))] = 1 to_print.append(s1) to_print.append(s2) else: for arg in clause.args: if arg.is_Symbol: s1[symbols.index(arg)] = 1 else: s2[symbols.index(Not(arg))] = 1 to_print.append(s1) to_print.append(s2) if (numclause > len(to_print) / 2): s1 = repeat_to_length(0, numlit) s2 = repeat_to_length(0, numlit) for i in range(numclause - int(len(to_print) / 2)): to_print.append(s1) to_print.append(s2) return to_print
def syntestbench(s, numlit, numclause): numlit = int(numlit) numclause = int(numclause) print("--ANSWER TO THIS TEST BENCH") print("--", end="") print(satisfiable(s)) s = to_cnf(sympify(s)) symbols = sorted(_find_predicates(s), key=default_sort_key) symbols_int_repr = set(range(0, len(symbols))) to_print = [] if s.func != And: s1 = repeat_to_length(0, numlit) s2 = repeat_to_length(0, numlit) if s.func != Or: if s.is_Symbol: s1[symbols.index(s)] = 1 to_print.append(s1) to_print.append(s2) else: s2[symbols.index(Not(s))] = 1 to_print.append(s1) to_print.append(s2) else: for arg in s.args: if arg.is_Symbol: s1[symbols.index(arg)] = 1 else: s2[symbols.index(Not(arg))] = 1 to_print.append(s1) to_print.append(s2) else: clauses = s.args for clause in clauses: s1 = repeat_to_length(0, numlit) s2 = repeat_to_length(0, numlit) if clause.func != Or: if clause.is_Symbol: s1[symbols.index(clause)] = 1 to_print.append(s1) to_print.append(s2) else: s2[symbols.index(Not(clause))] = 1 to_print.append(s1) to_print.append(s2) else: for arg in clause.args: if arg.is_Symbol: s1[symbols.index(arg)] = 1 else: s2[symbols.index(Not(arg))] = 1 to_print.append(s1) to_print.append(s2) if(numclause > len(to_print)/2): s1 = repeat_to_length(0, numlit) s2 = repeat_to_length(0, numlit) for i in range(numclause - int(len(to_print)/2)): to_print.append(s1) to_print.append(s2) return to_print