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
Example #2
0
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 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
Example #4
0
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
Example #5
0
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
Example #6
0
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
Example #7
0
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