def test_eliminate_assumptions(): a, b, x, y = symbols('abxy') assert eliminate_assume(Assume(x, 'a', True)) == a assert eliminate_assume(Assume(x, 'a', True), symbol=x) == a assert eliminate_assume(Assume(x, 'a', True), symbol=y) == None assert eliminate_assume(Assume(x, 'a', False)) == ~a assert eliminate_assume(Assume(x, 'a', False), symbol=y) == None assert eliminate_assume(Assume(x, 'a', True) | Assume(x, 'b')) == a | b assert eliminate_assume(Assume(x, 'a', True) | Assume(x, 'b', False)) == a | ~b
def test_eliminate_assumptions(): a, b = map(Predicate, symbols('ab')) x, y = symbols('xy') assert eliminate_assume(Assume(x, a)) == a assert eliminate_assume(Assume(x, a), symbol=x) == a assert eliminate_assume(Assume(x, a), symbol=y) == None assert eliminate_assume(Assume(x, a, False)) == ~a assert eliminate_assume(Assume(x, a), symbol=y) == None assert eliminate_assume(Assume(x, a) | Assume(x, b)) == a | b assert eliminate_assume(Assume(x, a) | Assume(x, b, False)) == a | ~b
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(expr, key, assumptions=True, context=global_assumptions, disable_preprocessing=False): """ 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) if type(key) is not Predicate: key = getattr(Q, str(key)) assumptions = And(assumptions, And(*context)) # direct resolution method, no logic if not disable_preprocessing: res = eval_predicate(key, expr, assumptions) if res is not None: return res if assumptions is True: return if not expr.is_Atom: return assumptions = eliminate_assume(assumptions, expr) if assumptions is None or assumptions is True: return # See if there's a straight-forward conclusion we can make for the inference if not disable_preprocessing: if assumptions.is_Atom: if key in known_facts_dict[assumptions]: return True if Not(key) in known_facts_dict[assumptions]: return False elif assumptions.func is And: for assum in assumptions.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 assumptions.func is Not and assumptions.args[0].is_Atom: if assumptions.args[0] in known_facts_dict[key]: return False # Failing all else, we do a full logical inference # If it's not consistent with the assumptions, then it can't be true if not satisfiable(And(known_facts_cnf, assumptions, key)): return False # If the negation is unsatisfiable, it is entailed if not satisfiable(And(known_facts_cnf, assumptions, Not(key))): return True # Otherwise, we don't have enough information to conclude one way or the other return None
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) if type(key) is not Predicate: key = getattr(Q, str(key)) assumptions = And(assumptions, And(*global_assumptions)) # direct resolution method, no logic res = eval_predicate(key, expr, assumptions) if res is not None: return res # use logic inference if assumptions is True: return 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: for clause in conjuncts(to_cnf(conj)): out = set() for atom in disjuncts(clause): lit, pos = literal_symbol(atom), type(atom) is not Not if pos: out.add(known_facts_keys.index(lit)+1) else: out.add(-(known_facts_keys.index(lit)+1)) clauses.append(out) n = len(known_facts_keys) clauses.append(set([known_facts_keys.index(key)+1])) if not dpll_int_repr(clauses, set(range(1, n+1)), {}): return False clauses[-1] = set([-(known_facts_keys.index(key)+1)]) if not dpll_int_repr(clauses, set(range(1, n+1)), {}): # if the negation is satisfiable, it is entailed return True del clauses
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 = set() for sym in conjuncts(to_cnf(conj)): lit, pos = literal_symbol(sym), type(sym) is not Not if pos: out.update([ known_facts_keys.index(str(l)) + 1 for l in disjuncts(lit) ]) else: out.update([ -(known_facts_keys.index(str(l)) + 1) for l in disjuncts(lit) ]) clauses.append(out) n = len(known_facts_keys) clauses.append(set([known_facts_keys.index(key) + 1])) if not dpll_int_repr(clauses, set(range(1, n + 1)), {}): return False clauses[-1] = set([-(known_facts_keys.index(key) + 1)]) if not dpll_int_repr(clauses, set(range(1, n + 1)), {}): # if the negation is satisfiable, it is entailed return True del clauses