示例#1
0
    def _process_rule(self, a, b):
        # right part first
        if isinstance(b, Logic):
            # a -> b & c    -->  a -> b  ;  a -> c
            # (?) FIXME this is only correct when b & c != null !
            if b.op == '&':
                for barg in b.args:
                    self.process_rule(a, barg)

            # a -> b | c    -->  !b & !c -> !a
            #               -->   a & !b -> c & !b
            #               -->   a & !c -> b & !c
            #
            # NB: the last two rewrites add 1 term, so the rule *grows* in size.
            # NB: without catching terminating conditions this could continue infinitely
            elif b.op == '|':
                # detect tautology first
                if not isinstance(a, Logic):  # Atom
                    # tautology:  a -> a|c|...
                    if a in b.args:
                        raise TautologyDetected(a, b, 'a -> a|c|...')
                self.process_rule(And(*[Not(barg) for barg in b.args]), Not(a))

                for bidx in range(len(b.args)):
                    barg = b.args[bidx]
                    brest = b.args[:bidx] + b.args[bidx + 1:]
                    self.process_rule(And(a, Not(barg)),
                                      And(b.__class__(*brest), Not(barg)))
            else:
                raise ValueError('unknown b.op %r' % b.op)

        # left part
        elif isinstance(a, Logic):
            # a & b -> c    -->  IRREDUCIBLE CASE -- WE STORE IT AS IS
            #                    (this will be the basis of beta-network)
            if a.op == '&':
                assert not isinstance(b, Logic)
                if b in a.args:
                    raise TautologyDetected(a, b, 'a & b -> a')
                self.proved_rules.append((a, b))
                # XXX NOTE at present we ignore  !c -> !a | !b

            elif a.op == '|':
                if b in a.args:
                    raise TautologyDetected(a, b, 'a | b -> a')
                for aarg in a.args:
                    self.process_rule(aarg, b)
            else:
                raise ValueError('unknown a.op %r' % a.op)
        else:
            # both `a` and `b` are atoms
            na, nb = name_not(a), name_not(b)
            self.proved_rules.append((a, b))  # a  -> b
            self.proved_rules.append((nb, na))  # !b -> !a
示例#2
0
    def get_edge_facts(self, edge, source, target, filter_polarity=None):
        """
        Returns a list of facts used by gather

        If filter_polarity is None, returns both positive and negative
        facts. If filter_polarity is True/False, returns only
        positive/negative.
        """
        a = dict(self.abstract_value)
        x = (edge, source, target)

        if ('edge_info', 'all_to_all') + x not in a:
            # not a well-sorted edge
            return []

        if a[('edge_info', 'none_to_none') + x]:
            polarity = False
        elif a[('edge_info', 'all_to_all') + x]:
            polarity = True
        else:
            # not a definite edge
            return []

        if filter_polarity is not None and filter_polarity != polarity:
            return []

        facts = []
        edge_concept = self.domain.concepts[edge]
        source_witnesses = self._get_witnesses(source)
        target_witnesses = self._get_witnesses(target)
        for source_c, target_c in product(source_witnesses, target_witnesses):
            f = edge_concept(source_c, target_c)
            facts.append(f if polarity else Not(f))

        return _normalize_facts(facts)
示例#3
0
def z3_implies(f1, f2, timeout=False):
    """
    Use z3 to test if f1 imples f2
    """
    print "<bhavya> z3_implies called"
    key = (f1, f2)
    if key in _implies_cache:
        return _implies_cache[key]
    s = z3.Solver()
    if timeout:
        s.set("timeout", 2000)  # 2 seconds
        #s.set("timeout", 60000) # 1 minute
    s.add(to_z3(f1))
    s.add(to_z3(Not(f2)))
    res = s.check()
    if res == z3.sat:
        _implies_cache[key] = False
        return False
    elif res == z3.unsat:
        _implies_cache[key] = True
        return True
    else:
        # no caching of unknown results
        print "z3 returned: {}".format(res)
        assert False
        return None
示例#4
0
 def suppose_empty(self, concept):
     self.push()
     f = self.domain.concepts[concept].formula
     self.suppose_constraints.append(
         ForAll(free_variables(f), Not(f))
     )
     self.recompute()
示例#5
0
def simp_not(x):
    if isinstance(x, Not):
        return x.args[0]
    if is_true(x):
        return Or()
    if is_false(x):
        return And()
    return Not(x)
示例#6
0
文件: facts.py 项目: vperic/sympy
    def _process_rule(self, a, b):
        # right part first

        # a -> b & c    -->  a -> b  ;  a -> c
        # (?) FIXME this is only correct when b & c != null !
        if isinstance(b, And):
            for barg in b.args:
                self.process_rule(a, barg)

        # a -> b | c    -->  !b & !c -> !a
        #               -->   a & !b -> c
        #               -->   a & !c -> b
        elif isinstance(b, Or):
            # detect tautology first
            if not isinstance(a, Logic):    # Atom
                # tautology:  a -> a|c|...
                if a in b.args:
                    raise TautologyDetected(a,b, 'a -> a|c|...')
            self.process_rule(And(*[Not(barg) for barg in b.args]), Not(a))

            for bidx in range(len(b.args)):
                barg = b.args[bidx]
                brest= b.args[:bidx] + b.args[bidx+1:]
                self.process_rule(And(a, Not(barg)), Or(*brest))

        # left part

        # a & b -> c    -->  IRREDUCIBLE CASE -- WE STORE IT AS IS
        #                    (this will be the basis of beta-network)
        elif isinstance(a, And):
            if b in a.args:
                raise TautologyDetected(a,b, 'a & b -> a')
            self.proved_rules.append((a,b))
            # XXX NOTE at present we ignore  !c -> !a | !b

        elif isinstance(a, Or):
            if b in a.args:
                raise TautologyDetected(a,b, 'a | b -> a')
            for aarg in a.args:
                self.process_rule(aarg, b)

        else:
            # both `a` and `b` are atoms
            self.proved_rules.append((a,b))     # a  -> b
            self.proved_rules.append((Not(b), Not(a)))   # !b -> !a
示例#7
0
 def _materialize_edge(self, edge, source, target, polarity):
     edge_concept = self.domain.concepts[edge]
     source_c = self._materialize_node(source)
     if source == target:
         target_c = source_c
     else:
         target_c = self._materialize_node(target)
     f = edge_concept(source_c, target_c)
     self.suppose(f if polarity else Not(f))
     return (source_c, target_c)
示例#8
0
    def _get_edge_fact(self, edge, source, target, polarity):
        facts = []
        edge_concept = self.domain.concepts[edge]
        source_witnesses = self._get_witnesses(source)
        target_witnesses = self._get_witnesses(target)
        for source_c, target_c in product(source_witnesses, target_witnesses):
            f = edge_concept(source_c, target_c)
            facts.append(f if polarity else Not(f))

        return _normalize_facts(facts)
示例#9
0
def exclusivity(sort,variants):
    # partial funciton 
    def pto(s):
        return Symbol('*>',RelationSort([sort,s]))
    excs = [partial_function(pto(s)) for s in variants]
    for s in enumerate(variants):
        x,y,z = [Variable(n,s) for n,s in [('X',sort),('Y',sort),('Z',s)]]
        excs.append(Implies(And(pto(s)(x,z),pto(s)(y,z)),Equals(x,y)))
    for i1,s1 in enumerate(variants):
        for s2 in variants[:i1]:
            x,y,z = [Variable(n,s) for n,s in [('X',sort),('Y',s1),('Z',s2)]]
            excs.append(Not(And(pto(s1)(x,y),pto(s2)(x,z))))
    return And(*excs)
示例#10
0
 def materialize_edge(self, edge, source, target, polarity):
     """
     Materialize an edge to either positive or negative
     """
     self.push()
     edge_concept = self.domain.concepts[edge]
     source_c = self._materialize_node(source)
     if source == target:
         target_c = source_c
     else:
         target_c = self._materialize_node(target)
     f = edge_concept(source_c, target_c)
     self.suppose_constraints.append(f if polarity else Not(f))
     self.recompute()
示例#11
0
 def get_node_facts(self, node):
     """
     Returns a list of facts used by gather
     """
     a = dict(self.abstract_value)
     facts = []
     if a[('node_info', 'at_least_one', node)]:
         for c in self._get_witnesses(node):
             facts.append(self.domain.concepts[node](c))
             for nl in self.domain.concepts['node_labels']:
                 if a.get(('node_label', 'node_necessarily', node, nl)):
                     facts.append(self.domain.concepts[nl](c))
                 elif a.get(('node_label', 'node_necessarily_not', node, nl)):
                     facts.append(Not(self.domain.concepts[nl](c)))
     return _normalize_facts(facts)
示例#12
0
文件: facts.py 项目: vchekan/sympy
def deduce_alpha_implications(implications):
    """deduce all implications

       Description by example
       ----------------------

       given set of logic rules:

         a -> b
         b -> c

       we deduce all possible rules:

         a -> b, c
         b -> c


       implications: [] of (a,b)
       return:       {} of a -> set([b, c, ...])
    """
    res = defaultdict(set)
    for a, b in implications:
        if a == b:
            continue  # skip a->a cyclic input

        res[a].add(b)

        # (x >> a) & (a >> b) => x >> b
        for fact in res:
            implied = res[fact]
            if a in implied:
                implied.add(b)

        # (a >> b) & (b >> x) => a >> x
        if b in res:
            res[a] |= res[b]

    # Clean up tautologies and check consistency
    for a, impl in res.iteritems():
        impl.discard(a)
        na = Not(a)
        if na in impl:
            raise ValueError('implications are inconsistent: %s -> %s %s' %
                             (a, na, impl))

    return res
示例#13
0
文件: concept.py 项目: simudream/ivy
    def split(self, concept, split_by):
        """
        concept and split_by are concept names.

        This splits concept into 2 concepts:
        (concept+split_by) and (concept-split_by)
        """
        c1 = self.concepts[concept]
        c2 = self.concepts[split_by]
        variables = c1.variables
        formula_plus = And(c1(*variables), c2(*variables))
        formula_minus = And(c1(*variables), Not(c2(*variables)))
        new_names = '({}+{})'.format(concept, split_by), '({}-{})'.format(concept, split_by)
        new_concepts = Concept(variables, formula_plus), Concept(variables, formula_minus)
        names = self.concepts.keys()
        self.concepts.update(zip(new_names, new_concepts))
        self.concepts = OrderedDict((k, self.concepts[k]) for k in _replace_name(names, concept, new_names))
        self.replace_concept(concept, new_names)
def alpha(concept_domain, state, cache=None, projection=None):
    """
    Right now, state is just a plain formula

    This is a *very* unoptimized implementation
    """

    time1 = time.time()

    facts = concept_domain.get_facts(projection)

    time2 = time.time()

    solver = slvr.new_solver()

    slvr.solver_add(solver, state)

    #    iu.dbg('state')

    if cache is None:
        cache = dict()
    result = []
    for tag, formula in facts:
        if tag in cache:
            value = cache[tag]
#            print "cached: {} = {}".format(tag,value)
        else:
            # assert len(cache) == 0, tag
            solver.push()
            slvr.solver_add(solver, Not(formula))
            value = not slvr.is_sat(solver)
            solver.pop()
            cache[tag] = value


#            print "computed: {} = {}".format(tag,value)

        result.append((tag, value))

    time3 = time.time()

    #    print 'alpha times: get_facts: {} check: {}'.format(time2-time1,time3-time2)

    return result
示例#15
0
    def split(self, concept, split_by):
        """
        concept and split_by are concept names.

        This splits concept into 2 concepts:
        (concept+split_by) and (concept-split_by)
        """
        c1 = self.concepts[concept]
        c2 = self.concepts[split_by]
        variables = c1.variables

        if isinstance(c2,ConceptSet):
            formulas = [self.concepts[n](*variables) for n in c2]
            new_names = ['({}+{})'.format(concept,n) for n in c2]
        else:
            formulas = [c2(*variables),Not(c2(*variables))]
            new_names = ['({}+{})'.format(concept, split_by), '({}-{})'.format(concept, split_by)]
        new_concepts = [Concept(n,variables,And(c1.formula,f)) for n,f in zip(new_names,formulas)]
        names = self.concepts.keys()
        self.concepts.update(zip(new_names, new_concepts))
        self.concepts = ConceptDict((k, self.concepts[k]) for k in _replace_name(names, concept, new_names))
        self.replace_concept(concept, new_names)
示例#16
0
def z3_implies_batch(premise, formulas, timeout=False):
    """
    Use z3 to test if premise implies each formula in formulas

    Equivalent to: [z3_implies(premise, f) for f in formulas]
    but more efficient
    """
    #import IPython
    #IPython.embed()
    print "<bhavya> z3_implies_batch called"
    s = z3.Solver()
    if timeout:
        s.set("timeout", 2000)  # 2 seconds
        #s.set("timeout", 60000) # 1 minute
    s.add(to_z3(premise))
    result = []
    for f in formulas:
        key = (premise, f)
        if key in _implies_cache:
            result.append(_implies_cache[key])
        else:
            s.push()
            s.add(to_z3(Not(f)))
            res = s.check()
            s.pop()
            if res == z3.sat:
                _implies_cache[key] = False
                result.append(False)
            elif res == z3.unsat:
                _implies_cache[key] = True
                result.append(True)
            else:
                # no caching of unknown results
                print "z3 returned: {}".format(res)
                assert False
                result.append(None)
    return result
示例#17
0
                # no caching of unknown results
                print "z3 returned: {}".format(res)
                assert False
                result.append(None)
    return result


if __name__ == '__main__':
    S = UninterpretedSort('S')
    X, Y, Z = (Var(n, S) for n in ['X', 'Y', 'Z'])
    BinRel = FunctionSort(S, S, Boolean)
    leq = Const('leq', BinRel)
    transitive1 = ForAll((X, Y, Z),
                         Implies(And(leq(X, Y), leq(Y, Z)), leq(X, Z)))
    transitive2 = ForAll((X, Y, Z),
                         Or(Not(leq(X, Y)), Not(leq(Y, Z)), leq(X, Z)))
    transitive3 = Not(
        Exists((X, Y, Z), And(leq(X, Y), leq(Y, Z), Not(leq(X, Z)))))
    antisymmetric = ForAll((X, Y),
                           Implies(And(leq(X, Y), leq(Y, X), true), Eq(Y, X)))

    print z3_implies(transitive1, transitive2)
    print z3_implies(transitive2, transitive3)
    print z3_implies(transitive3, transitive1)
    print z3_implies(transitive3, antisymmetric)
    print

    print z3_implies(true, Iff(transitive1, transitive2))
    print

    x, y = (Const(n, S) for n in ['x', 'y'])
示例#18
0
def refuted_goal(goal):
    from z3_utils import z3_implies
    axioms = _ivy_interp.background_theory()
    premise = (and_clauses(axioms, goal.node.clauses)).to_formula()
    f = Not(goal.formula.to_formula())
    return z3_implies(premise, f)
def check_knowledge(knowledge):
    for symbol in symbols:
        if model_check(knowledge, symbol):
            termcolor.cprint(f"{symbol}: YES", "green")
        elif not model_check(knowledge, Not(symbol)):
            print(f"{symbol}: MAYBE")
    BinaryRelation = FunctionSort(S, S, Boolean)

    X, Y, Z = (Var(n, S) for n in ['X', 'Y', 'Z'])
    U = Var('U', UnaryRelation)
    U1 = Var('U1', UnaryRelation)
    U2 = Var('U2', UnaryRelation)
    B = Var('B', BinaryRelation)
    B1 = Var('B1', BinaryRelation)
    B2 = Var('B2', BinaryRelation)

    nstar = Const('nstar', BinaryRelation)
    x = Const('x', S)
    y = Const('y', S)

    c11 = Concept('xy', [X], And(Eq(x, X), Eq(y, X)))
    c10 = Concept('x', [X], And(Eq(x, X), Not(Eq(y, X))))
    c01 = Concept('y', [X], And(Not(Eq(x, X)), Eq(y, X)))
    c00 = Concept('other', [X], And(Not(Eq(x, X)), Not(Eq(y, X))))

    cnstar = Concept('nstar', [X, Y], nstar(X, Y))
    cnplus = Concept('nplus', [X, Y], And(nstar(X, Y), Not(Eq(X, Y))))

    notexists = ConceptCombiner([U], Not(Exists([X], U(X))))
    exists = ConceptCombiner([U], Exists([X], U(X)))
    singleton = ConceptCombiner([U],
                                ForAll([X, Y],
                                       Implies(And(U(X), U(Y)), Eq(X, Y))))
    all_to_all = ConceptCombiner([U1, U2, B],
                                 ForAll([X, Y],
                                        Implies(And(U1(X), U2(Y)), B(X, Y))))
示例#21
0
 def _suppose_empty(self, concept):
     f = self.domain.concepts[concept].formula
     self.suppose_constraints.append(ForAll(free_variables(f), Not(f)))
示例#22
0
AKnight = Symbol("A is a Knight")
AKnave = Symbol("A is a Knave")

BKnight = Symbol("B is a Knight")
BKnave = Symbol("B is a Knave")

CKnight = Symbol("C is a Knight")
CKnave = Symbol("C is a Knave")

# Puzzle 0
# A says "I am both a knight and a knave."
knowledge0 = And(
    # Structure of the generic problem
    Or(AKnight, AKnave),
    Not(And(AKnight, AKnave)),

    # Information about what the characters said
    Implication(AKnight, And(AKnight, AKnave)),
    Implication(AKnave, Not(And(AKnight, AKnave)))
)

# Puzzle 1
# A says "We are both knaves."
# B says nothing.
knowledge1 = And(
    # Structure of the generic problem
    Or(AKnight, AKnave),
    Or(BKnight, BKnave),
    Not(And(AKnight, AKnave)),
    Not(And(BKnight, BKnave)),
示例#23
0
                         Or(CKnave, CKnight))

# Puzzle 0
# A says "I am both a knight and a knave."
knowledge0 = And(OnlyOneKindForEach, Implication(AKnight, And(AKnight,
                                                              AKnave)))

# Puzzle 1
# A says "We are both knaves."
# B says nothing.

WereBothKnaves = And(BKnave, AKnave)
knowledge1 = And(
    OnlyOneKindForEach,
    Implication(AKnight, WereBothKnaves),
    Implication(AKnave, Not(WereBothKnaves)),
)

# Puzzle 2
# A says "We are the same kind."
# B says "We are of different kinds."
WereTheSameKind = Or(And(BKnave, AKnave), And(BKnight, AKnight))
WereDifferentKinds = Or(And(BKnave, AKnight), And(BKnight, AKnave))

knowledge2 = And(
    OnlyOneKindForEach,
    Implication(AKnight, WereTheSameKind),
    Implication(AKnave, Not(WereTheSameKind)),
    Implication(BKnight, WereDifferentKinds),
    Implication(BKnave, Not(WereDifferentKinds)),
)
示例#24
0
文件: concept.py 项目: simudream/ivy
def get_standard_combiners():
    T = TopSort()
    UnaryRelation = FunctionSort(T, Boolean)
    BinaryRelation = FunctionSort(T, T, Boolean)
    X, Y, Z = (Var(n, T) for n in ['X', 'Y', 'Z'])
    U = Var('U', UnaryRelation)
    U1 = Var('U1', UnaryRelation)
    U2 = Var('U2', UnaryRelation)
    B = Var('B', BinaryRelation)
    B1 = Var('B1', BinaryRelation)
    B2 = Var('B2', BinaryRelation)
    result = OrderedDict()

    result['none'] = ConceptCombiner([U], Not(Exists([X], U(X))))
    result['at_least_one'] = ConceptCombiner([U], Exists([X], U(X)))
    result['at_most_one'] = ConceptCombiner([U], ForAll([X,Y], Implies(And(U(X), U(Y)), Eq(X,Y))))

    result['node_necessarily'] = ConceptCombiner(
        [U1, U2],
        ForAll([X], Implies(U1(X), U2(X))),
    )
    result['node_necessarily_not'] = ConceptCombiner(
        [U1, U2],
        ForAll([X], Implies(U1(X), Not(U2(X)))),
    )


    result['mutually_exclusive'] = ConceptCombiner(
        [U1, U2],
        ForAll([X, Y], Not(And(U1(X), U2(Y))))
    )

    result['all_to_all'] = ConceptCombiner(
        [B, U1, U2],
        ForAll([X,Y], Implies(And(U1(X), U2(Y)), B(X,Y)))
    )
    result['none_to_none'] = ConceptCombiner(
        [B, U1, U2],
        ForAll([X,Y], Implies(And(U1(X), U2(Y)), Not(B(X,Y))))
    )
    result['total'] = ConceptCombiner(
        [B, U1, U2],
        ForAll([X], Implies(U1(X), Exists([Y], And(U2(Y), B(X,Y)))))
    )
    result['functional'] = ConceptCombiner(
        [B, U1, U2],
        ForAll([X, Y, Z], Implies(And(U1(X), U2(Y), U2(Z), B(X,Y), B(X,Z)), Eq(Y,Z)))
    )
    result['surjective'] = ConceptCombiner(
        [B, U1, U2],
        ForAll([Y], Implies(U2(Y), Exists([X], And(U1(X), B(X,Y)))))
    )
    result['injective'] = ConceptCombiner(
        [B, U1, U2],
        ForAll([X, Y, Z], Implies(And(U1(X), U1(Y), U2(Z), B(X,Z), B(Y,Z)), Eq(X,Y)))
    )

    result['node_info'] = ['none', 'at_least_one', 'at_most_one']
    if False:
        # this just slows us down, and it's not clear it's needed
        # later this should be made customizable by the user
        result['edge_info'] = ['all_to_all', 'none_to_none', 'total',
                               'functional', 'surjective', 'injective']
    else:
        result['edge_info'] = ['all_to_all', 'none_to_none']

    result['node_label'] = ['node_necessarily', 'node_necessarily_not']

    return result
示例#25
0
文件: concept.py 项目: simudream/ivy
    UnaryRelationS = FunctionSort(S, Boolean)
    BinaryRelationS = FunctionSort(S, S, Boolean)
    UnaryRelationT = FunctionSort(T, Boolean)
    BinaryRelationT = FunctionSort(T, T, Boolean)


    X, Y, Z = (Var(n, S) for n in ['X', 'Y', 'Z'])

    r = Const('r', BinaryRelationS)
    n = Const('n', BinaryRelationS)
    p = Const('p', UnaryRelationS)
    q = Const('q', UnaryRelationS)
    u = Const('u', UnaryRelationS)

    c11 = Concept([X], And(p(X), q(X)))
    c10 = Concept([X], And(p(X), Not(q(X))))
    c01 = Concept([X], And(Not(p(X)), q(X)))
    c00 = Concept([X], And(Not(p(X)), Not(q(X))))
    cu = Concept([X], u(X))

    crn = Concept([X, Y], Or(r(X,Y), n(X,Y)))

    combiners = get_standard_combiners()
    combinations = get_standard_combinations()

    test('c11')
    test('c10')
    test('c01')
    test('c00')
    test('cu')
    test('crn')
示例#26
0
文件: facts.py 项目: vperic/sympy
def apply_beta_to_alpha_route(alpha_implications, beta_rules):
    """apply additional beta-rules (And conditions) to already-built alpha implication tables

       TODO: write about

       - static extension of alpha-chains
       - attaching refs to beta-nodes to alpha chains


       e.g.

       alpha_implications:

       a  ->  [b, !c, d]
       b  ->  [d]
       ...


       beta_rules:

       &(b,d) -> e


       then we'll extend a's rule to the following

       a  ->  [b, !c, d, e]
    """
    x_impl = {}
    for x in alpha_implications.keys():
        x_impl[x] = (set(alpha_implications[x]), [])
    for bcond, bimpl in beta_rules:
        for bk in bcond.args:
            if bk in x_impl:
                continue
            x_impl[bk] = (set(), [])

    # static extensions to alpha rules:
    # A: x -> a,b   B: &(a,b) -> c  ==>  A: x -> a,b,c
    seen_static_extension = True
    while seen_static_extension:
        seen_static_extension = False

        for bcond, bimpl in beta_rules:
            assert isinstance(bcond, And)
            bargs = set(bcond.args)
            for x, (ximpls, bb) in x_impl.iteritems():
                x_all = ximpls | set([x])
                # A: ... -> a   B: &(...) -> a  is non-informative
                if bimpl not in x_all and bargs.issubset(x_all):
                    ximpls.add(bimpl)

                    # we introduced new implication - now we have to restore
                    # completness of the whole set.
                    bimpl_impl = x_impl.get(bimpl)
                    if bimpl_impl is not None:
                        ximpls |= bimpl_impl[0]
                    seen_static_extension=True

    # attach beta-nodes which can be possibly triggered by an alpha-chain
    for bidx, (bcond,bimpl) in enumerate(beta_rules):
        bargs = set(bcond.args)
        for x, (ximpls, bb) in x_impl.iteritems():
            x_all = ximpls | set([x])
            # A: ... -> a   B: &(...) -> a      (non-informative)
            if bimpl in x_all:
                continue
            # A: x -> a...  B: &(!a,...) -> ... (will never trigger)
            # A: x -> a...  B: &(...) -> !a     (will never trigger)
            if any(Not(xi) in bargs or Not(xi) == bimpl for xi in x_all):
                continue

            if bargs & x_all:
                bb.append(bidx)

    return x_impl
示例#27
0
    UnaryRelationS = FunctionSort(S, Boolean)
    BinaryRelationS = FunctionSort(S, S, Boolean)
    UnaryRelationT = FunctionSort(T, Boolean)
    BinaryRelationT = FunctionSort(T, T, Boolean)


    X, Y, Z = (Var(n, S) for n in ['X', 'Y', 'Z'])

    r = Const('r', BinaryRelationS)
    n = Const('n', BinaryRelationS)
    p = Const('p', UnaryRelationS)
    q = Const('q', UnaryRelationS)
    u = Const('u', UnaryRelationS)

    c11 = Concept('both',[X], And(p(X), q(X)))
    c10 = Concept('onlyp',[X], And(p(X), Not(q(X))))
    c01 = Concept('onlyq',[X], And(Not(p(X)), q(X)))
    c00 = Concept('none',[X], And(Not(p(X)), Not(q(X))))
    cu = Concept('u',[X], u(X))

    crn = Concept('r_or_n',[X, Y], Or(r(X,Y), n(X,Y)))

    combiners = get_standard_combiners()
    combinations = get_standard_combinations()

    test('c11')
    test('c10')
    test('c01')
    test('c00')
    test('cu')
    test('crn')
    Or(knife, revolver, wrench)
)

# Initial cards
knowledge.add(And(
    Not(mustard), Not(kitchen), Not(revolver)
))

# Unknown card
knowledge.add(Or(
    Not(scarlet), Not(library), Not(wrench)
))
"""

# Known cards
knowledge.add(Not(Black))
knowledge.add(Not(Rosa))
knowledge.add(Not(cano))
knowledge.add(Not(hall))
knowledge.add(Not(cozinha))
knowledge.add(Not(corda))

knowledge.add(
    And(
        Or(Not(Violeta), Not(biblioteca), Not(chave)),
        Or(Not(Branca), Not(jantar), Not(revolver)),
        Or(Not(Branca), Not(estar), Not(chave)),
    ))

knowledge.add(
    And(
示例#29
0
def apply_beta_to_alpha_route(alpha_implications, beta_rules):
    """apply additional beta-rules (And conditions) to already-built alpha implication tables

       TODO: write about

       - static extension of alpha-chains
       - attaching refs to beta-nodes to alpha chains


       e.g.

       alpha_implications:

       a  ->  [b, !c, d]
       b  ->  [d]
       ...


       beta_rules:

       &(b,d) -> e


       then we'll extend a's rule to the following

       a  ->  [b, !c, d, e]
    """
    x_impl = {}
    for x in alpha_implications.keys():
        x_impl[x] = (alpha_implications[x][:], [])
    for bcond, bimpl in beta_rules:
        for bk in bcond.args:
            if bk in x_impl:
                continue
            x_impl[bk] = ([], [])

    # we do it in 2 phases:
    #
    # 1st phase -- only do static extensions to alpha rules
    # 2nd phase -- attach beta-nodes which can be possibly triggered by an
    #              alpha-chain
    phase = 1
    while True:
        seen_static_extension = False

        for bidx, (bcond, bimpl) in enumerate(beta_rules):
            assert isinstance(bcond, And)
            for x, (ximpls, bb) in x_impl.iteritems():
                # A: x -> a     B: &(...) -> x      (non-informative)
                if x == bimpl:  # XXX bimpl may become a list
                    continue
                # A: ... -> a   B: &(...) -> a      (non-informative)
                if bimpl in ximpls:
                    continue
                # A: x -> a     B: &(a,!x) -> ...   (will never trigger)
                if Not(x) in bcond.args:
                    continue
                # A: x -> a...  B: &(!a,...) -> ... (will never trigger)
                # A: x -> a...  B: &(...) -> !a     (will never trigger)
                if any(
                        Not(xi) in bcond.args or Not(xi) == bimpl
                        for xi in ximpls):
                    continue

                # A: x -> a,b   B: &(a,b) -> c      (static extension)
                #                                       |
                # A: x -> a,b,c <-----------------------+
                for barg in bcond.args:
                    if not ((barg == x) or (barg in ximpls)):
                        break
                else:
                    assert phase == 1
                    list_populate(ximpls, bimpl)  # XXX bimpl may become a list

                    # we introduced new implication - now we have to restore
                    # completness of the whole set.
                    bimpl_impl = x_impl.get(bimpl)
                    if bimpl_impl is not None:
                        for _ in bimpl_impl[0]:
                            list_populate(ximpls, _)
                    seen_static_extension = True
                    continue

                # does this beta-rule even has a chance to be triggered ?
                if phase == 2:
                    for barg in bcond.args:
                        if (barg == x) or (barg in ximpls):
                            bb.append(bidx)
                            break

        # no static extensions was seen at this pass -- lets move to phase2
        if phase == 1 and (not seen_static_extension):
            phase = 2
            continue

        # let's finish at the end of phase2
        if phase == 2:
            break

    return x_impl
示例#30
0
from logic import And, Or, Symbol, Biconditional, Implication, Not, model_check

AKnight = Symbol("A is a Knight")
AKnave = Symbol("A is a Knave")

BKnight = Symbol("B is a Knight")
BKnave = Symbol("B is a Knave")

CKnight = Symbol("C is a Knight")
CKnave = Symbol("C is a Knave")

# Puzzle 0
# A says "I am both a knight and a knave."
knowledge0 = And(Or(AKnight, AKnave), Implication(AKnight, Not(AKnave)),
                 Implication(AKnave, Not(AKnight)),
                 Biconditional(AKnight, And(AKnight, AKnave)))

# Puzzle 1
# A says "We are both knaves."
# B says nothing.
knowledge1 = And(Or(AKnight, AKnave), Implication(AKnight, Not(AKnave)),
                 Implication(AKnave, Not(AKnight)), Or(BKnight, BKnave),
                 Implication(BKnight, Not(BKnave)),
                 Implication(BKnave, Not(BKnight)),
                 Biconditional(AKnight, And(AKnave, BKnave)))

# Puzzle 2
# A says "We are the same kind."
# B says "We are of different kinds."
knowledge2 = And(
    Or(AKnight, AKnave), Implication(AKnight, Not(AKnave)),