def FeasTruthTable(self, exp, robot_region): """ Find feasible truth table to make exp true :param exp: expression :return: """ if exp == '(1)': return '1' sgl_value = [] for key, value in robot_region.items(): if len(value) == 1: sgl_value.append(value[0]) # set all to be false exp1 = to_cnf(exp) value_in_exp = [value.name for value in exp1.atoms()] subs = {true_rb_rg: False for true_rb_rg in value_in_exp} if exp1.subs(subs): return subs # set one to be true, the other to be false for prod in itertools.product(*robot_region.values()): exp1 = exp # set one specific item to be true for true_rb_rg in prod: # set the other to be false value_cp = list(robot_region[true_rb_rg.split('_')[1]]) if len(value_cp) > 1: value_cp.remove(true_rb_rg) # replace the rest with same robot to be ~ for v_remove in value_cp: exp1 = exp1.replace(v_remove, '~' + true_rb_rg) # simplify exp1 = to_cnf(exp1) # all value in expression value_in_exp = [value.name for value in exp1.atoms()] # all single value in expression sgl_value_in_exp = [value for value in value_in_exp if value in sgl_value] # not signle value in expression not_sgl_value_in_exp = [value for value in value_in_exp if value not in sgl_value] subs1 = {true_rb_rg: True for true_rb_rg in not_sgl_value_in_exp} tf = [False, True] # if type(exp1) == Or: # tf = [False, True] if len(sgl_value_in_exp): for p in itertools.product(*[tf] * len(sgl_value_in_exp)): subs2 = {sgl_value_in_exp[i]: p[i] for i in range(len(sgl_value_in_exp))} subs = {**subs1, **subs2} if exp1.subs(subs): return subs else: if exp1.subs(subs1): return subs1 return []
def resolution(self, beliefBase, newBelief): tmpBeliefBase = [] formula = to_cnf(newBelief) neg_formula = to_cnf(~formula) tmpBeliefBase += helpFunctions.conjuncts(neg_formula) for belief in beliefBase: tmpBeliefBase += helpFunctions.conjuncts(belief) tmpBeliefBase = helpFunctions.removeAllDuplicates(tmpBeliefBase) result = set() while True: # Generate all pairs of clauses for pair in combinations(tmpBeliefBase, 2): resolvents = helpFunctions.resolve(pair[0], pair[1]) if False in resolvents: # Arrived to contradiction return True # Add resolvent to knowledge base result = result.union(set(resolvents)) if result.issubset(set(tmpBeliefBase)): # We are looping return False else: for x in result: if x not in tmpBeliefBase: tmpBeliefBase.append(x)
def test_issue_18904(): x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 = symbols('x1:16') eq = (( x1 & x2 & x3 & x4 & x5 & x6 & x7 & x8 & x9 ) | ( x1 & x2 & x3 & x4 & x5 & x6 & x7 & x10 & x9 ) | ( x1 & x11 & x3 & x12 & x5 & x13 & x14 & x15 & x9 )) assert is_cnf(to_cnf(eq)) raises(ValueError, lambda: to_cnf(eq, simplify=True)) for f, t in zip((And, Or), (to_cnf, to_dnf)): eq = f(x1, x2, x3, x4, x5, x6, x7, x8, x9) raises(ValueError, lambda: to_cnf(eq, simplify=True)) assert t(eq, simplify=True, force=True) == eq
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(A & B) == And(A, B) 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 + 1) == A + 1
def get_negated_theory(self): """ Negates a theory :return: A new generated theory, corresponding to the negation of the current theory """ sympy_and_clauses = [] for c in self.clauses: sympy_or_clauses = [] for l in c: if l > 0: # sympy_or_clauses.append(Symbol("cnf_%s" % l)) sympy_or_clauses.append(~Symbol("cnf_%s" % l)) else: # sympy_or_clauses.append(~Symbol("cnf_%s" % abs(l))) sympy_or_clauses.append(Symbol("cnf_%s" % abs(l))) # sympy_and_clauses.append(Or(*sympy_or_clauses)) sympy_and_clauses.append(And(*sympy_or_clauses)) # sympy_cnf = And(*sympy_and_clauses) sympy_cnf = Or(*sympy_and_clauses) # negated_cnf = to_cnf(~sympy_cnf, True) negated_cnf = to_cnf(sympy_cnf, True) negated_cnf1 = to_cnf(sympy_cnf, False) negated_cnf_dimacs = [] if isinstance(negated_cnf, And): for clause in negated_cnf.args: or_literals = [] if isinstance(clause, Or): for sympy_literal in clause.args: or_literals.append( TheoryNoisyGenerator.get_dimacs_repr(sympy_literal) ) else: or_literals.append(TheoryNoisyGenerator.get_dimacs_repr(clause)) negated_cnf_dimacs.append(or_literals) else: or_literals = [] if isinstance(negated_cnf, Or): for sympy_literal in negated_cnf.args: or_literals.append( TheoryNoisyGenerator.get_dimacs_repr(sympy_literal) ) else: or_literals.append(TheoryNoisyGenerator.get_dimacs_repr(negated_cnf)) negated_cnf_dimacs.append(or_literals) # negated_cnf_dimacs.append( # [TheoryNoisyGenerator.get_dimacs_repr(negated_cnf)] # ) return GeneratedTheory(negated_cnf_dimacs)
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 expr_to_satfmt(expr, mapper, convert_cnf=True): """ Takes a sympy formula in CNF, return a list of lists of integers for use with pycosat """ # ensure CNF cnf_expr = None if convert_cnf and not is_cnf(expr): print( "Got a non-CNF expression, converting... (depending on the size and " "structure of the expression, this could take a prohibitively long time)" ) # see https://cs.stackexchange.com/a/41071/97082 for an explanation # if this becomes a problem, Tseitin transforms might be worth exploring # for now I'm just gonna try to stick to CNF everywhere cnf_expr = to_cnf(expr, simplify=True, force=True) else: cnf_expr = expr # make list of lists of integers clauses = [] for clause in cnf_expr.args: if type(clause) in [Symbol, Not]: clauses.append([mapper.to_int(clause)]) else: clauses.append(list(map(mapper.to_int, clause.args))) return clauses
def satisfiable(expr, algorithm="dpll2"): """ Check satisfiability of a propositional sentence. Returns a model when it succeeds. Returns {true: true} for trivially true expressions. Examples ======== >>> from sympy.abc import A, B >>> from sympy.logic.inference import satisfiable >>> satisfiable(A & ~B) {A: True, B: False} >>> satisfiable(A & ~A) False >>> satisfiable(True) {True: True} """ expr = to_cnf(expr) if algorithm == "dpll": from sympy.logic.algorithms.dpll import dpll_satisfiable return dpll_satisfiable(expr) elif algorithm == "dpll2": from sympy.logic.algorithms.dpll2 import dpll_satisfiable return dpll_satisfiable(expr) raise NotImplementedError
def revise(self, formula, order, add_on_finish=True): """ Updates entrenchment ranking for belief base revision. Params: - add_on_finish: If true, the formula will be added to the belief base after the ranking has been updated. """ x = to_cnf(formula) _validate_order(order) dx = self.degree(x) logger.debug(f'Revising with {x} and order {order} and degree {dx}') if not entails([], ~x): # If x is a contradiction, ignore if entails([], x): # If x is a tautology, assign order = 1 order = 1 elif order <= dx: self.contract(x, order) else: self.contract(~x, 0) self.expand(x, order, add_on_finish=False) if add_on_finish: self.add(x, order) logger.debug(f'New belief base:\n{self}')
def label2sat(self): for edge in self.buchi_graph.edges(): label = self.buchi_graph.edges[edge]['label'] label = label.replace('||', '|').replace('&&', '&').replace('!', '~') exp1 = to_cnf(label) self.buchi_graph.edges[edge]['label'] = exp1
def encode(self): """Converts this decision tree to a sympy CNF formula.""" n_inputs, n_targets = self.n_inputs, self.n_targets x_symbols = np.array([(sympy.Symbol(f'X{i}.0'), sympy.Symbol(f'X{i}.1')) for i in range(0, n_inputs)]) z_symbols = np.array([(sympy.Symbol(f'X{i}.0'), sympy.Symbol(f'X{i}.1')) for i in range(n_inputs, 2 * n_inputs)]) y_symbols = np.array([ (sympy.Symbol(f'X{i}.0'), sympy.Symbol(f'X{i}.1')) for i in range(2 * n_inputs, 2 * n_inputs + n_targets) ]) leaves = self._extract_leaves() constraints = [ self._encode_mutex(y_symbols), self._encode_leaf_to_y(leaves, x_symbols, y_symbols), ] if self.use_relevance: constraints.append( self._encode_leaf_to_z(leaves, x_symbols, z_symbols)) # XXX THIS IS F*****G SLOW constraint = to_cnf(sympy.And(*constraints)) return constraint, n_inputs, n_targets
def _encode_leaf_to_y(self, leaves, inputs, outputs): """Each leaf entails one and only one label.""" formulas = [] for leaf in leaves: cond = sympy.And(*[inputs[i, value] for i, value in leaf.conds]) formulas.append(cond & outputs[leaf.klass, 1]) return to_cnf(sympy.Or(*formulas))
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 dnf_to_cnf_list(self, dnf_clauses): symbol_list = list( set([str(abs(j)) for sub in dnf_clauses for j in sub])) amount_of_symbols = len(symbol_list) letter_list = [ "".join(p) for i in range(1, (amount_of_symbols // 26 + 2)) for p in itertools.product(string.ascii_lowercase, repeat=i + 1) ] letter_list.remove('as') letter_list = letter_list[:amount_of_symbols] symbol_dict = dict( zip(symbol_list + ['-', '], [', ', ', '[[', ']]'], letter_list + ['~', ')|(', '&', '(', ')'])) dnf_clauses_string = str(dnf_clauses) for key, value in symbol_dict.items(): dnf_clauses_string = dnf_clauses_string.replace(key, value) expression = sympy.parsing.sympy_parser.parse_expr(dnf_clauses_string) cnf_expression = str(to_cnf(expression, simplify=False)) symbol_dict2 = dict( zip(letter_list + ['~', '(', ')'], symbol_list + ['-', '', ''])) for key, value in sorted(list(symbol_dict2.items()), key=lambda x: len(x[0]), reverse=True): cnf_expression = cnf_expression.replace(key, value) cnf_expression2 = [ str.split(x, '|') for x in str.split(cnf_expression, '&') ] for i in range(len(cnf_expression2)): for j in range(len(cnf_expression2[i])): cnf_expression2[i][j] = int(cnf_expression2[i][j]) return cnf_expression2
def _collective_beliefs(self) -> str: """Concatenates all the beliefs in belief base in their cnf with &.""" return str( to_cnf( '&'.join( [str(belief.cnf) for belief in self.beliefBase.values()]), True))
def getRemainders(self, belief): beliefCnf = to_cnf(belief) if not self.resolution(self.beliefs, beliefCnf): # Whole knowledge base is solution return [self.beliefs] solutions = [] allBeliefs = self.beliefs def contract(beliefList, beliefToRemove): if len(beliefList) == 1: if not self.resolution(beliefList, beliefToRemove): solutions.append(beliefList) return for i in beliefList: tmp = helpFunctions.removeFromList(i, beliefList) if self.resolution(tmp, beliefToRemove): # Implies beliefToRemove, have to remove more contract(tmp, beliefToRemove) else: # Does not imply beliefToRemove, one of the possible solutions solutions.append(tmp) contract(allBeliefs, beliefCnf) # Remove duplicates and solutions that are not maximal (remainders) solutions = helpFunctions.removeSublist(solutions) return solutions
def ask(self, query): """Checks if the query is true given the set of clauses. Examples ======== >>> from sympy.logic.inference import PropKB >>> from sympy.abc import x, y >>> l = PropKB() >>> l.tell(x & ~y) >>> l.ask(x) True >>> l.ask(y) False """ if len(self.clauses) == 0: return False from sympy.logic.algorithms.dpll import dpll query_conjuncts = self.clauses[:] query_conjuncts.extend(conjuncts(to_cnf(query))) s = set() for q in query_conjuncts: s = s.union(q.atoms(C.Symbol)) return bool(dpll(query_conjuncts, list(s), {}))
def compute_known_facts(): """Compute the various forms of knowledge compilation used by the assumptions system. """ # Compute the known facts in CNF form for logical inference fact_string = "# -{ Known facts in CNF }-\n" cnf = to_cnf(known_facts) fact_string += "known_facts_cnf = And(\n " fact_string += ",\n ".join(map(str, cnf.args)) fact_string += "\n)\n" # Compute the quick lookup for single facts mapping = {} for key in known_facts_keys: mapping[key] = set([key]) for other_key in known_facts_keys: if other_key != key: if ask_full_inference(other_key, key): mapping[key].add(other_key) fact_string += "\n# -{ Known facts in compressed sets }-\n" fact_string += "known_facts_dict = {\n " fact_string += ",\n ".join( ["%s: %s" % item for item in mapping.items()]) fact_string += "\n}\n" return fact_string
def satisfiable(expr, algorithm="dpll2"): """ Check satisfiability of a propositional sentence. Returns a model when it succeeds Examples: >>> from sympy.abc import A, B >>> from sympy.logic.inference import satisfiable >>> satisfiable(A & ~B) {A: True, B: False} >>> satisfiable(A & ~A) False """ expr = to_cnf(expr) if algorithm == "dpll": from sympy.logic.algorithms.dpll import dpll_satisfiable return dpll_satisfiable(expr) elif algorithm == "dpll2": from sympy.logic.algorithms.dpll2 import dpll_satisfiable return dpll_satisfiable(expr) raise NotImplementedError
def compute_known_facts(known_facts, known_facts_keys): """Compute the various forms of knowledge compilation used by the assumptions system. """ from textwrap import dedent, wrap fact_string = dedent('''\ from sympy.logic.boolalg import And, Not, Or from sympy.assumptions.ask import Q # -{ Known facts in CNF }- known_facts_cnf = And( %s ) # -{ Known facts in compressed sets }- known_facts_dict = { %s }''') # Compute the known facts in CNF form for logical inference LINE = ",\n " HANG = ' '*8 cnf = to_cnf(known_facts) c = LINE.join([str(a) for a in cnf.args]) mapping = single_fact_lookup(known_facts_keys, cnf) m = LINE.join(['\n'.join( wrap("%s: %s" % item, subsequent_indent=HANG, break_long_words=False)) for item in mapping.items()]) return fact_string % (c, m)
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 resolution(b_base, alpha): base = b_base.copy() base.append(Belief(to_cnf(Not(alpha)))) resolve_elements = resolution_elements(conjunction(base)) N = len(resolve_elements) N1 = len(resolve_elements) + 1 resolve_elements_new = resolve_elements.copy() l = 0 while True: l = l + 1 resolve_elements = resolve_elements_new.copy() N = len(resolve_elements) p = [] new_base = [] for i in range(N): for cj in resolve_elements[i + 1:]: p.append((resolve_elements[i], cj)) for (ci, cj) in p: b = resolve(ci, cj) bc = b.copy() print() if b != None: if [] in b: print('The function is already entailed!') return True for r in b: if r in resolve_elements: bc.remove(r) new_base = new_base + bc if len(new_base) == 0: return False resolve_elements_new = resolve_elements + new_base N1 = len(resolve_elements_new) return resolve_elements
def compute_known_facts(): """Compute the various forms of knowledge compilation used by the assumptions system. """ # Compute the known facts in CNF form for logical inference fact_string = " -{ Known facts in CNF }-\n" cnf = to_cnf(known_facts) fact_string += "known_facts_cnf = And( \\\n ", fact_string += ", \\\n ".join(map(str, cnf.args)) fact_string += "\n)\n" # Compute the quick lookup for single facts from sympy.abc import x mapping = {} for key in known_facts_keys: mapping[key] = set([key]) for other_key in known_facts_keys: if other_key != key: if ask(x, other_key, Assume(x, key, False), disable_preprocessing=True): mapping[key].add(Not(other_key)) fact_string += "\n\n -{ Known facts in compressed sets }-\n" fact_string += "known_facts_dict = { \\\n ", fact_string += ", \\\n ".join(["%s: %s" % item for item in mapping.items()]) fact_string += "\n}\n" return fact_string
def process_conds(cond): """ Turn ``cond`` into a strip (a, b), and auxiliary conditions. """ a = -oo b = oo aux = True conds = conjuncts(to_cnf(cond)) t = Dummy('t', real=True) for c in conds: a_ = oo b_ = -oo aux_ = [] for d in disjuncts(c): d_ = d.replace(re, lambda x: x.as_real_imag()[0]).subs(re(s), t) if not d.is_Relational or (d.rel_op != '<' and d.rel_op != '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ (soln.rel_op != '<' and soln.rel_op != '<='): aux_ += [d] continue if soln.lhs == t: b_ = Max(soln.rhs, b_) else: a_ = Min(soln.lhs, a_) if a_ != oo and a_ != b: a = Max(a_, a) elif b_ != -oo and b_ != a: b = Min(b_, b) else: aux = And(aux, Or(*aux_)) return a, b, aux
def convertAndPrintCNF(expr_inpt): expr_inpt = expr_inpt.split(",") CNF_array = [] for i in range(0, len(expr_inpt)): CNF_array.append(to_cnf(expr_inpt[i])) print(CNF_array) return CNF_array
def toCnf(s): try: z=simplify_logic(s) x=to_cnf(z) return str(x) except: return 'this is wrong format'
def parse_bif(contents, enc1, verbose): nodes = None bif_w = contents.splitlines() bif = BIFP.fixWhiteSpace(bif_w) nodes = BIFP.parseBIF(bif) if nodes is None: print("error parsing bif") return -1 if verbose: print(">bif info:") for n in nodes: n.printNode() # create variables # map from name to int variables, queries = create_variables(nodes, enc1) if verbose: print("variables:") for v in variables: print(v) # create cnf cnf = toEnc1(nodes) if enc1 else toEnc2(nodes) if verbose: print("enc:") clauses = cnf.args for clause in clauses: p = "$ " p += latex_print(clause) p += " $" print(p) print() cnf = to_cnf(cnf) if verbose: print("cnf:") print(cnf) # assign weights weights = assign_weights_enc1(nodes) if enc1 else assign_weights_enc2( nodes) weights = weights_to_dict(weights, variables, enc1) # if verbose: # print("weights:") # keys = weights.keys() # for key in keys: # print("$ " + key + " $ & " + str(weights[key][0]) + "&" + str(weights[key][1]) + " \\\\") return variables, cnf, weights, queries
def compute_known_facts(known_facts, known_facts_keys): """Compute the various forms of knowledge compilation used by the assumptions system. This function is typically applied to the results of the ``get_known_facts`` and ``get_known_facts_keys`` functions defined at the bottom of this file. """ from textwrap import dedent, wrap fact_string = dedent( '''\ """ The contents of this file are the return value of ``sympy.assumptions.ask.compute_known_facts``. Do NOT manually edit this file. Instead, run ./bin/ask_update.py. """ from sympy.core.cache import cacheit from sympy.logic.boolalg import And, Not, Or from sympy.assumptions.ask import Q # -{ Known facts in Conjunctive Normal Form }- @cacheit def get_known_facts_cnf(): return And( %s ) # -{ Known facts in compressed sets }- @cacheit def get_known_facts_dict(): return { %s } ''' ) # Compute the known facts in CNF form for logical inference LINE = ",\n " HANG = " " * 8 cnf = to_cnf(known_facts) c = LINE.join([str(a) for a in cnf.args]) mapping = single_fact_lookup(known_facts_keys, cnf) items = sorted(mapping.items(), key=str) keys = [str(i[0]) for i in items] values = ["set(%s)" % sorted(i[1], key=str) for i in items] m = ( LINE.join( [ "\n".join(wrap("%s: %s" % (k, v), subsequent_indent=HANG, break_long_words=False)) for k, v in zip(keys, values) ] ) + "," ) return fact_string % (c, m)
def addToKnowledgeBase(self, box): expression_box_neighbours = S.false neighbours = self.getNeighbours(box) if box.clue == 0: for neighbour in neighbours: if neighbour in self.fringe: self.fringe.remove(neighbour) # neighbour.solved = True # self.solvedBoxes += 1 self.knowledgeBase = self.knowledgeBase.subs( {neighbour.symbol: False}) if (neighbour.solved == False): self.observedMineField[neighbour.row][ neighbour.col].prob = 0.0 self.fringe.append(neighbour) elif box.clue == 8: for neighbour in neighbours: if neighbour in self.fringe: self.fringe.remove(neighbour) neighbour.solved = True neighbour.mineFlag = IS_MINE self.solvedBoxes += 1 # self.unseenBoxes -= 1 self.knowledgeBase = self.knowledgeBase.subs( {neighbour.symbol: True}) self.observedMineField[neighbour.row][neighbour.col].prob = 1.0 else: for ci in range(0, box.clue + 1): for subset in itertools.combinations(neighbours, box.clue): expression_subset = S.true for neighbour in neighbours: if neighbour not in subset: expression_subset = expression_subset & ~neighbour.symbol else: expression_subset = expression_subset & neighbour.symbol expression_box_neighbours = expression_box_neighbours | ( expression_subset) for neighbour in neighbours: if neighbour.solved == True: if neighbour.mineFlag: expression_box_neighbours = expression_box_neighbours.subs( {neighbour.symbol: True}) else: expression_box_neighbours = expression_box_neighbours.subs( {neighbour.symbol: False}) # print("Expression Generated:", expression_box_neighbours) expr = expression_box_neighbours if not is_cnf(expr): expr = to_cnf(expr, simplify=True) # print("Converted new expression") # print("After CNF:", expr) self.updateKnowledgeBase(expr, box)
def disjunctionlist(blist): if type(blist) == Symbol: w = [] w.append(blist) blist = w a = False for i in range(len(blist)): a = to_cnf(Or(a, blist[i])) return a
def conjunctionlist(blist): if type(blist) == Symbol: w = [] w.append(blist) blist = w a = True for i in range(len(blist)): a = to_cnf(And(a, blist[i])) return a
def convert_to_cnf(clause): out_clause = repr(to_cnf(clause)) out_clause = out_clause.replace("(", "").replace(")", "").replace(" ", "") out_clause = out_clause.upper() if "&" in out_clause: out_clause = out_clause.split("&") return out_clause return [out_clause]
def ask(self, query): """TODO: examples""" if len(self.clauses) == 0: return False query_conjuncts = self.clauses[:] query_conjuncts.extend(conjuncts(to_cnf(query))) s = set() for q in query_conjuncts: s = s.union(q.atoms(Symbol)) return bool(dpll(query_conjuncts, list(s), {}))
def _laplace_transform(f, t, s, simplify=True): """ The backend function for laplace transforms. """ from sympy import (re, Max, exp, pi, Abs, Min, periodic_argument as arg, cos, Wild, symbols) F = integrate(exp(-s * t) * f, (t, 0, oo)) if not F.has(Integral): return _simplify(F, simplify), -oo, True if not F.is_Piecewise: raise IntegralTransformError('Laplace', f, 'could not compute integral') F, cond = F.args[0] if F.has(Integral): raise IntegralTransformError('Laplace', f, 'integral in unexpected form') a = -oo aux = True conds = conjuncts(to_cnf(cond)) u = Dummy('u', real=True) p, q, w1, w2, w3 = symbols('p q w1 w2 w3', cls=Wild, exclude=[s]) for c in conds: a_ = oo aux_ = [] for d in disjuncts(c): m = d.match(abs(arg((s + w3)**p * q, w1)) < w2) if m: if m[q] > 0 and m[w2] / m[p] == pi / 2: d = re(s + m[w3]) > 0 m = d.match(0 < cos(abs(arg(s, q))) * abs(s) - p) if m: d = re(s) > m[p] d_ = d.replace(re, lambda x: x.expand().as_real_imag()[0]).subs( re(s), t) if not d.is_Relational or (d.rel_op != '<' and d.rel_op != '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ (soln.rel_op != '<' and soln.rel_op != '<='): aux_ += [d] continue if soln.lhs == t: raise IntegralTransformError('Laplace', f, 'convergence not in half-plane?') else: a_ = Min(soln.lhs, a_) if a_ != oo: a = Max(a_, a) else: aux = And(aux, Or(*aux_)) return _simplify(F, simplify), a, aux
def ask(self, query): """TODO: examples""" if len(self.clauses) == 0: return False from sympy.logic.algorithms.dpll import dpll query_conjuncts = self.clauses[:] query_conjuncts.extend(conjuncts(to_cnf(query))) s = set() for q in query_conjuncts: s = s.union(q.atoms(C.Symbol)) return bool(dpll(query_conjuncts, list(s), {}))
def translate(self, string: str): """ This function takes a boolean statement in string format and transform it into the boolean statement. :param string: he string of boolean statement :return: the sympy expr object translated from the string. """ string1 = string.replace('not', '~') expr = to_cnf(parse_expr(string1)) self.logger.log(level=1, msg=' is out of range') self.math_statement = expr
def _mellin_transform(f, x, s_, integrator=_default_integrator, simplify=True): """ Backend function to compute mellin transforms. """ from sympy import re, Max, Min # We use a fresh dummy, because assumptions on s might drop conditions on # convergence of the integral. s = _dummy('s', 'mellin-transform', f) F = integrator(x**(s-1) * f, x) if not F.has(Integral): return _simplify(F.subs(s, s_), simplify), (-oo, oo), True if not F.is_Piecewise: raise IntegralTransformError('Mellin', f, 'could not compute integral') F, cond = F.args[0] if F.has(Integral): raise IntegralTransformError('Mellin', f, 'integral in unexpected form') a = -oo b = oo aux = True conds = conjuncts(to_cnf(cond)) t = Dummy('t', real=True) for c in conds: a_ = oo b_ = -oo aux_ = [] for d in disjuncts(c): d_ = d.replace(re, lambda x: x.as_real_imag()[0]).subs(re(s), t) if not d.is_Relational or (d.rel_op != '<' and d.rel_op != '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ (soln.rel_op != '<' and soln.rel_op != '<='): aux_ += [d] continue if soln.lhs == t: b_ = Max(soln.rhs, b_) else: a_ = Min(soln.lhs, a_) if a_ != oo and a_ != b: a = Max(a_, a) elif b_ != -oo and b_ != a: b = Min(b_, b) else: aux = And(aux, Or(*aux_)) if aux is False: raise IntegralTransformError('Mellin', f, 'no convergence found') return _simplify(F.subs(s, s_), simplify), (a, b), aux
def _laplace_transform(f, t, s, simplify=True): """ The backend function for laplace transforms. """ from sympy import (re, Max, exp, pi, Abs, Min, periodic_argument as arg, cos, Wild, symbols) F = integrate(exp(-s*t) * f, (t, 0, oo)) if not F.has(Integral): return _simplify(F, simplify), -oo, True if not F.is_Piecewise: raise IntegralTransformError('Laplace', f, 'could not compute integral') F, cond = F.args[0] if F.has(Integral): raise IntegralTransformError('Laplace', f, 'integral in unexpected form') a = -oo aux = True conds = conjuncts(to_cnf(cond)) u = Dummy('u', real=True) p, q, w1, w2, w3 = symbols('p q w1 w2 w3', cls=Wild, exclude=[s]) for c in conds: a_ = oo aux_ = [] for d in disjuncts(c): m = d.match(abs(arg((s + w3)**p*q, w1)) < w2) if m: if m[q] > 0 and m[w2]/m[p] == pi/2: d = re(s + m[w3]) > 0 m = d.match(0 < cos(abs(arg(s, q)))*abs(s) - p) if m: d = re(s) > m[p] d_ = d.replace(re, lambda x: x.expand().as_real_imag()[0]).subs(re(s), t) if not d.is_Relational or (d.rel_op != '<' and d.rel_op != '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ (soln.rel_op != '<' and soln.rel_op != '<='): aux_ += [d] continue if soln.lhs == t: raise IntegralTransformError('Laplace', f, 'convergence not in half-plane?') else: a_ = Min(soln.lhs, a_) if a_ != oo: a = Max(a_, a) else: aux = And(aux, Or(*aux_)) return _simplify(F, simplify), a, aux
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 sympy.abc import A, B >>> from sympy.logic.inference import satisfiable >>> satisfiable(A & ~B) {A: True, B: False} >>> 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} >>> next(models) {A: True, B: True} >>> def use_models(models): ... for model in models: ... if model: ... # Do something with the model. ... print(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 sympy.logic.algorithms.dpll import dpll_satisfiable return dpll_satisfiable(expr) elif algorithm == "dpll2": from sympy.logic.algorithms.dpll2 import dpll_satisfiable return dpll_satisfiable(expr, all_models) raise NotImplementedError
def dpll_satisfiable(expr): """Check satisfiability of a propositional sentence. It returns a model rather than True when it succeeds >>> from sympy import symbols >>> A, B = symbols('AB') >>> dpll_satisfiable(A & ~B) {A: True, B: False} >>> dpll_satisfiable(A & ~A) False """ clauses = conjuncts(to_cnf(expr)) symbols = list(expr.atoms(Symbol)) return dpll(clauses, symbols, {})
def test_to_cnf(): A, B, C = symbols('ABC') 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(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)) == \ And(Or(Not(B), A), Or(Not(C), A), Or(B, C, Not(A)))
def dpll_satisfiable(expr): """Check satisfiability of a propositional sentence. It returns a model rather than True when it succeeds >>> from sympy import symbols >>> A, B = symbols('AB') >>> dpll_satisfiable(A & ~B) {A: True, B: False} >>> dpll_satisfiable(A & ~A) False References: Implemented as described in http://aima.cs.berkeley.edu/ """ clauses = conjuncts(to_cnf(expr)) symbols = list(expr.atoms(Symbol)) return dpll(clauses, symbols, {})
def compute_known_facts(known_facts, known_facts_keys): """Compute the various forms of knowledge compilation used by the assumptions system. This function is typically applied to the variables ``known_facts`` and ``known_facts_keys`` defined at the bottom of this file. """ from textwrap import dedent, wrap fact_string = dedent( '''\ """ The contents of this file are the return value of ``sympy.assumptions.ask.compute_known_facts``. Do NOT manually edit this file. """ from sympy.logic.boolalg import And, Not, Or from sympy.assumptions.ask import Q # -{ Known facts in CNF }- known_facts_cnf = And( %s ) # -{ Known facts in compressed sets }- known_facts_dict = { %s } ''' ) # Compute the known facts in CNF form for logical inference LINE = ",\n " HANG = " " * 8 cnf = to_cnf(known_facts) c = LINE.join([str(a) for a in cnf.args]) mapping = single_fact_lookup(known_facts_keys, cnf) m = ( LINE.join( [ "\n".join(wrap("%s: %s" % item, subsequent_indent=HANG, break_long_words=False)) for item in mapping.items() ] ) + "," ) return fact_string % (c, m)
def process_conds(conds): """ Turn ``conds`` into a strip and auxiliary conditions. """ a = -oo aux = True conds = conjuncts(to_cnf(conds)) u = Dummy('u', real=True) p, q, w1, w2, w3, w4, w5 = symbols('p q w1 w2 w3 w4 w5', cls=Wild, exclude=[s]) for c in conds: a_ = oo aux_ = [] for d in disjuncts(c): m = d.match(abs(arg((s + w3)**p*q, w1)) < w2) if not m: m = d.match(abs(arg((s + w3)**p*q, w1)) <= w2) if not m: m = d.match(abs(arg((polar_lift(s + w3))**p*q, w1)) < w2) if not m: m = d.match(abs(arg((polar_lift(s + w3))**p*q, w1)) <= w2) if m: if m[q] > 0 and m[w2]/m[p] == pi/2: d = re(s + m[w3]) > 0 m = d.match(0 < cos(abs(arg(s**w1*w5, q))*w2)*abs(s**w3)**w4 - p) if not m: m = d.match(0 < cos(abs(arg(polar_lift(s)**w1*w5, q))*w2)*abs(s**w3)**w4 - p) if m and all(m[wild] > 0 for wild in [w1, w2, w3, w4, w5]): d = re(s) > m[p] d_ = d.replace(re, lambda x: x.expand().as_real_imag()[0]).subs(re(s), t) if not d.is_Relational or \ d.rel_op not in ('>', '>=', '<', '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ soln.rel_op not in ('>', '>=', '<', '<='): aux_ += [d] continue if soln.lts == t: raise IntegralTransformError('Laplace', f, 'convergence not in half-plane?') else: a_ = Min(soln.lts, a_) if a_ != oo: a = Max(a_, a) else: aux = And(aux, Or(*aux_)) return a, aux
def satisfiable(expr, algorithm="dpll"): """Check satisfiability of a propositional sentence. Returns a model when it succeeds Examples >>> from sympy import symbols >>> A, B = symbols('AB') >>> satisfiable(A & ~B) {A: True, B: False} >>> satisfiable(A & ~A) False """ expr = to_cnf(expr) if algorithm == "dpll": from sympy.logic.algorithms.dpll import dpll_satisfiable return dpll_satisfiable(expr) raise NotImplementedError
def tell(self, sentence): """Add the sentence's clauses to the KB Examples ======== >>> from sympy.logic.inference import PropKB >>> from sympy.abc import x, y, z >>> l = PropKB() >>> l.clauses [] >>> l.tell(x | y) >>> l.clauses [Or(x, y)] >>> l.tell(y & z) >>> l.clauses [Or(x, y), y, z] """ for c in conjuncts(to_cnf(sentence)): if not c in self.clauses: self.clauses.append(c)
def compute_known_facts(known_facts, known_facts_keys): """Compute the various forms of knowledge compilation used by the assumptions system. """ fact_string = "from sympy.logic.boolalg import And, Not, Or\n" fact_string += "from sympy.assumptions.ask import Q\n\n" # Compute the known facts in CNF form for logical inference cnf = to_cnf(known_facts) fact_string += "# -{ Known facts in CNF }-\n" fact_string += "known_facts_cnf = And(\n " fact_string += ",\n ".join(map(str, cnf.args)) fact_string += "\n)\n" mapping = single_fact_lookup(known_facts_keys, cnf) fact_string += "\n# -{ Known facts in compressed sets }-\n" fact_string += "known_facts_dict = {\n " fact_string += ",\n ".join( ["%s: %s" % item for item in mapping.items()]) fact_string += "\n}\n" return fact_string
def dpll_satisfiable(expr): """ Check satisfiability of a propositional sentence. It returns a model rather than True when it succeeds >>> from sympy import symbols >>> A, B = symbols('AB') >>> dpll_satisfiable(A & ~B) {A: True, B: False} >>> dpll_satisfiable(A & ~A) False """ symbols = list(expr.atoms(Symbol)) symbols_int_repr = range(1, len(symbols) + 1) clauses = conjuncts(to_cnf(expr)) 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 tell(self, sentence): """Add the sentence's clauses to the KB Examples ======== >>> from sympy.logic.inference import PropKB >>> from sympy.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)
def retract(self, sentence): """Remove the sentence's clauses from the KB Examples ======== >>> from sympy.logic.inference import PropKB >>> from sympy.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)
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 ask(expr, key, assumptions=True): """ Method for inferring properties about objects. **Syntax** * ask(expression, key) * ask(expression, key, assumptions) where expression is any SymPy expression **Examples** >>> from sympy import ask, Q, Assume, pi >>> from sympy.abc import x, y >>> ask(pi, Q.rational) False >>> ask(x*y, Q.even, Assume(x, Q.even) & Assume(y, Q.integer)) True >>> ask(x*y, Q.prime, Assume(x, Q.integer) & Assume(y, Q.integer)) False **Remarks** Relations in assumptions are not implemented (yet), so the following will not give a meaningful result. >> ask(x, positive=True, Assume(x>0)) It is however a work in progress and should be available before the official release """ expr = sympify(expr) assumptions = And(assumptions, And(*global_assumptions)) # direct resolution method, no logic resolutors = [] for handler in handlers_dict[key]: resolutors.append( get_class(handler) ) res, _res = None, None mro = inspect.getmro(type(expr)) for handler in resolutors: for subclass in mro: if hasattr(handler, subclass.__name__): res = getattr(handler, subclass.__name__)(expr, assumptions) if _res is None: _res = res elif res is None: # since first resolutor was conclusive, we keep that value res = _res else: # only check consistency if both resolutors have concluded if _res != res: raise ValueError, 'incompatible resolutors' break if res is not None: return res if assumptions is True: return # use logic inference if not expr.is_Atom: return clauses = copy.deepcopy(known_facts_compiled) assumptions = conjuncts(to_cnf(assumptions)) # add assumptions to the knowledge base for assump in assumptions: conj = eliminate_assume(assump, symbol=expr) if conj: out = [] for sym in conjuncts(to_cnf(conj)): lit, pos = literal_symbol(sym), type(sym) is not Not if pos: out.extend([known_facts_keys.index(str(l))+1 for l in disjuncts(lit)]) else: out.extend([-(known_facts_keys.index(str(l))+1) for l in disjuncts(lit)]) clauses.append(out) n = len(known_facts_keys) clauses.append([known_facts_keys.index(key)+1]) if not dpll_int_repr(clauses, range(1, n+1), {}): return False clauses[-1][0] = -clauses[-1][0] if not dpll_int_repr(clauses, range(1, n+1), {}): # if the negation is satisfiable, it is entailed return True del clauses
def ask(proposition, assumptions=True, context=global_assumptions): """ Method for inferring properties about objects. **Syntax** * ask(proposition) * ask(proposition, assumptions) where ``proposition`` is any boolean expression Examples ======== >>> from sympy import ask, Q, pi >>> from sympy.abc import x, y >>> ask(Q.rational(pi)) False >>> ask(Q.even(x*y), Q.even(x) & Q.integer(y)) True >>> ask(Q.prime(x*y), Q.integer(x) & Q.integer(y)) False **Remarks** Relations in assumptions are not implemented (yet), so the following will not give a meaningful result. >>> ask(Q.positive(x), Q.is_true(x > 0)) # doctest: +SKIP It is however a work in progress. """ if not isinstance(proposition, (BooleanFunction, AppliedPredicate, bool, BooleanAtom)): raise TypeError("proposition must be a valid logical expression") if not isinstance(assumptions, (BooleanFunction, AppliedPredicate, bool, BooleanAtom)): raise TypeError("assumptions must be a valid logical expression") if isinstance(proposition, AppliedPredicate): key, expr = proposition.func, sympify(proposition.arg) else: key, expr = Q.is_true, sympify(proposition) assumptions = And(assumptions, And(*context)) assumptions = to_cnf(assumptions) local_facts = _extract_facts(assumptions, expr) if local_facts and satisfiable(And(local_facts, known_facts_cnf)) is False: raise ValueError("inconsistent assumptions %s" % assumptions) # direct resolution method, no logic res = key(expr)._eval_ask(assumptions) if res is not None: return bool(res) if assumptions == True: return if local_facts is None: return # See if there's a straight-forward conclusion we can make for the inference if local_facts.is_Atom: if key in known_facts_dict[local_facts]: return True if Not(key) in known_facts_dict[local_facts]: return False elif local_facts.func is And and all(k in known_facts_dict for k in local_facts.args): for assum in local_facts.args: if assum.is_Atom: if key in known_facts_dict[assum]: return True if Not(key) in known_facts_dict[assum]: return False elif assum.func is Not and assum.args[0].is_Atom: if key in known_facts_dict[assum]: return False if Not(key) in known_facts_dict[assum]: return True elif (isinstance(key, Predicate) and local_facts.func is Not and local_facts.args[0].is_Atom): if local_facts.args[0] in known_facts_dict[key]: return False # Failing all else, we do a full logical inference return ask_full_inference(key, local_facts, known_facts_cnf)
def retract(self, sentence): "Remove the sentence's clauses from the KB" for c in conjuncts(to_cnf(sentence)): if c in self.clauses: self.clauses.remove(c)