Beispiel #1
0
 def convert(self, init):
     """Converts strings into exprs"""
     try:
         init = conjuncts(expr(init))
     except AttributeError:
         init = expr(init)
     return init
Beispiel #2
0
def run_minisat_test():
    """
    Test connection to MiniSat
    """
    import logic

    queries = [("(P | ~P)", True), # SAT
               ("(P & ~P)", False), # UNSAT
               ("(P | R) <=> (~(Q | R) & (R >> ~(S <=> T)))", True) # SAT
               ]
    
    print "Running simple MiniSat test:"
    t = 1
    failed = []
    for query, expected_result in queries:
        print "-----------------------------------------------------"
        print "Test {0}".format(t)
        print "  Query:      '{0}'".format(query)
        query = logic.conjuncts(logic.to_cnf(logic.expr(query)))
        result = minisat(query, None, variable=None, value=True, verbose=False)
        print "  Query CNF:  {0}".format(query)
        print "  Result:     {0}   (Expected: {1})".format(result.success, expected_result)
        if result.success != expected_result:
            print "    FAILURE: unexpected result."
            failed.append(t)
        if result.success:
            print "  Variable Assignment: {0}".format(result.varmap)
        t += 1
    print "-----------------------------------------------------"
    if not failed:
        print "Successfully passed {0} tests.".format(len(queries))
    else:
        print "Passed {0} test(s).".format(len(queries) - len(failed))
        print "The following tests failed: {0}".format(failure)
    print "DONE."
Beispiel #3
0
def run_minisat_test():
    """
    Test connection to MiniSat
    """
    import logic

    queries = [("(P | ~P)", True), # SAT
               ("(P & ~P)", False), # UNSAT
               ("(P | R) <=> (~(Q | R) & (R >> ~(S <=> T)))", True) # SAT
               ]
    
    print "Running simple MiniSat test:"
    t = 1
    failed = []
    for query, expected_result in queries:
        print "-----------------------------------------------------"
        print "Test {0}".format(t)
        print "  Query:      '{0}'".format(query)
        query = logic.conjuncts(logic.to_cnf(logic.expr(query)))
        result = minisat(query, None, variable=None, value=True, verbose=False)
        print "  Query CNF:  {0}".format(query)
        print "  Result:     {0}   (Expected: {1})".format(result.success, expected_result)
        if result.success != expected_result:
            print "    FAILURE: unexpected result."
            failed.append(t)
        if result.success:
            print "  Variable Assignment: {0}".format(result.varmap)
        t += 1
    print "-----------------------------------------------------"
    if not failed:
        print "Successfully passed {0} tests.".format(len(queries))
    else:
        print "Passed {0} test(s).".format(len(queries) - len(failed))
        print "The following tests failed: {0}".format(failure)
    print "DONE."
def prop_fc(kb, alpha):
    old_clauses_len = 0
    while old_clauses_len != len(kb.clauses):
        old_clauses_len = len(kb.clauses)
        for clause in set(kb.clauses):
            if clause.op in ("==>", "<=>"):
                if all(
                        map(lambda c: c in kb.clauses,
                            conjuncts(clause.args[0]))):
                    kb.clauses.update(conjuncts(clause.args[1]))
            if clause.op in ("<==", "<=>"):
                if all(
                        map(lambda c: c in kb.clauses,
                            conjuncts(clause.args[1]))):
                    kb.clauses.update(conjuncts(clause.args[0]))
            if alpha in kb.clauses:
                return True
    return False
Beispiel #5
0
def resolution(KB, alpha):
    """Apply the resolution algorithm to determine if alpha can be inferred from KB.

  Args:
    KB: an instance of logic.PropKB
    alpha: an instance of logic.Expr

  Return True if KB |- alpha
  """
    # We do not want to waste effort resolving clauses of the KB against
    # one another directly, we only want to resolve clauses that contain
    # information derived from alpha.  tainted_clauses will be the set
    # we grow.
    tainted_clauses = set(
        normalize(clause) for clause in logic.conjuncts(logic.to_cnf(~alpha)))
    KB_clauses = [normalize(clause) for clause in KB.clauses]
    new = set()
    while True:
        # clausesWith is a map from literals to clauses containing that literal.
        clausesWith = collections.defaultdict(list)
        for clause in list(tainted_clauses) + KB_clauses:
            for literal in clause:
                clausesWith[literal].append(clause)

        # For each tainted clause, add a pair of that clause and any
        # tainted or KB clause that matches it (i.e. opposes on one literal).
        pairs = []
        for clause0 in tainted_clauses:
            for literal in clause0:
                for clause1 in clausesWith[negate(literal)]:
                    pairs.append((literal, clause0, clause1))

        # Resolve all the pairs found above.  If any result in None, the
        # resolution is a bust (provides no new information).
        # If any result in False (empty set), we have reached a contradiction
        # and proven our goal.
        for literal, clause0, clause1 in pairs:
            result = resolve(clause0, clause1, literal)
            if result is not None:
                if result == set(): return True
                else: new.add(frozenset(result))

        # We now survey all the new clauses.  In order to want to keep them,
        # they must not be a superset of any already-known clause (since that
        # would provide no new information).
        added = False
        for clause in new:
            if not any(
                    old_clause.issubset(clause)
                    for old_clause in list(tainted_clauses) + KB_clauses):
                tainted_clauses.add(clause)
                added = True

        # If we have not found any new information, we've reached the end
        # and cannot prove our goal (it may be True, it may be False, but we
        # can't definitively say either way).
        if not added: return False
def resolution(KB, alpha):
  """Apply the resolution algorithm to determine if alpha can be inferred from KB.

  Args:
    KB: an instance of logic.PropKB
    alpha: an instance of logic.Expr

  Return True if KB |- alpha
  """
  # We do not want to waste effort resolving clauses of the KB against
  # one another directly, we only want to resolve clauses that contain
  # information derived from alpha.  tainted_clauses will be the set
  # we grow.
  tainted_clauses = set(normalize(clause)
      for clause in logic.conjuncts(logic.to_cnf(~alpha)))
  KB_clauses = [normalize(clause) for clause in KB.clauses]
  new = set()
  while True:
    # clausesWith is a map from literals to clauses containing that literal.
    clausesWith = collections.defaultdict(list)
    for clause in list(tainted_clauses) + KB_clauses:
      for literal in clause:
        clausesWith[literal].append(clause)

    # For each tainted clause, add a pair of that clause and any
    # tainted or KB clause that matches it (i.e. opposes on one literal).
    pairs = []
    for clause0 in tainted_clauses:
      for literal in clause0:
        for clause1 in clausesWith[negate(literal)]:
          pairs.append((literal, clause0, clause1))

    # Resolve all the pairs found above.  If any result in None, the 
    # resolution is a bust (provides no new information).
    # If any result in False (empty set), we have reached a contradiction
    # and proven our goal.
    for literal, clause0, clause1 in pairs:
      result = resolve(clause0, clause1, literal)
      if result is not None:
        if result == set(): return True
        else: new.add(frozenset(result))

    # We now survey all the new clauses.  In order to want to keep them,
    # they must not be a superset of any already-known clause (since that
    # would provide no new information).
    added = False
    for clause in new:
      if not any(old_clause.issubset(clause)
          for old_clause in list(tainted_clauses) + KB_clauses):
        tainted_clauses.add(clause)
        added = True

    # If we have not found any new information, we've reached the end
    # and cannot prove our goal (it may be True, it may be False, but we
    # can't definitively say either way).
    if not added: return False
Beispiel #7
0
    def convert(self, clauses):
        """Converts strings into Exprs"""
        if isinstance(clauses, Expr):
            clauses = conjuncts(clauses)
            for i in range(len(clauses)):
                if clauses[i].op == '~':
                    clauses[i] = expr('Not' + str(clauses[i].args[0]))

        elif isinstance(clauses, str):
            clauses = clauses.replace('~', 'Not')
            if len(clauses) > 0:
                clauses = expr(clauses)

            try:
                clauses = conjuncts(clauses)
            except AttributeError:
                pass

        return clauses
Beispiel #8
0
    def convert(self, clauses):
        """Converts strings into Exprs"""
        if isinstance(clauses, Expr):
            clauses = conjuncts(clauses)
            for i in range(len(clauses)):
                if clauses[i].op == '~':
                    clauses[i] = expr('Not' + str(clauses[i].args[0]))

        elif isinstance(clauses, str):
            clauses = clauses.replace('~', 'Not')
            if len(clauses) > 0:
                clauses = expr(clauses)

            try:
                clauses = conjuncts(clauses)
            except AttributeError:
                pass

        return clauses
Beispiel #9
0
    def convert(self, precond, effect):
        """Converts strings into Exprs"""

        precond = precond.replace('~', 'Not')
        if len(precond) > 0:
            precond = expr(precond)
        effect = effect.replace('~', 'Not')
        if len(effect) > 0:
            effect = expr(effect)

        try:
            precond = conjuncts(precond)
        except AttributeError:
            pass
        try:
            effect = conjuncts(effect)
        except AttributeError:
            pass

        return precond, effect
Beispiel #10
0
    def ask(self, prop):
        to_prove = frozenset(map(frozenset,
                                 map(set,
                                     map(disjuncts,
                                         conjuncts(to_cnf(~prop)))))) \
                    | self.clauses #把要证明的结论先否定再整理成CNF的形式,再和原来KB中的子句们并一下

        if fast_dpll(to_prove):
            return False  #是否有contradiction,若没有(fast_dpll()为True)
        else:
            self.tell(prop)  #如果结论成立(有contradiction),那么就把新的推论给到KB
            return True
Beispiel #11
0
    def ask(self, prop):
        to_prove = frozenset(map(frozenset,
                                 map(set,
                                     map(disjuncts,
                                         conjuncts(to_cnf(~prop)))))) \
                    | self.clauses

        if fast_dpll(to_prove):
            return False
        else:
            self.tell(prop)
            return True
Beispiel #12
0
 def convert(self, clauses):
     """Converts strings into exprs"""
     if not isinstance(clauses, Expr):
         if len(clauses) > 0:
             clauses = expr(clauses)
         else:
             clauses = []
     try:
         clauses = conjuncts(clauses)
     except AttributeError:
         clauses = clauses
     return clauses
Beispiel #13
0
def test_action():
    precond = 'At(c, a) & At(p, a) & Cargo(c) & Plane(p) & Airport(a)'
    effect = 'In(c, p) & ~At(c, a)'
    a = Action('Load(c, p, a)', precond, effect)
    args = [expr("C1"), expr("P1"), expr("SFO")]
    assert a.substitute(expr("Load(c, p, a)"), args) == expr("Load(C1, P1, SFO)")
    test_kb = FolKB(conjuncts(expr('At(C1, SFO) & At(C2, JFK) & At(P1, SFO) & At(P2, JFK) & Cargo(C1) & Cargo(C2) & Plane(P1) & Plane(P2) & Airport(SFO) & Airport(JFK)')))
    assert a.check_precond(test_kb, args)
    a.act(test_kb, args)
    assert test_kb.ask(expr("In(C1, P2)")) is False
    assert test_kb.ask(expr("In(C1, P1)")) is not False
    assert test_kb.ask(expr("Plane(P2)")) is not False
    assert not a.check_precond(test_kb, args)
Beispiel #14
0
    def convert(self, clauses):
        """Converts strings into exprs"""
        if not isinstance(clauses, Expr):
            if len(clauses) > 0:
                clauses = expr(clauses)
            else:
                clauses = []
        try:
            clauses = conjuncts(clauses)
        except AttributeError:
            clauses = clauses

        new_clauses = []
        for clause in clauses:
            if clause.op == '~':
                new_clauses.append(expr('Not' + str(clause.args[0])))
            else:
                new_clauses.append(clause)
        return new_clauses
Beispiel #15
0
def is_valid_cnf(exp):
    if not isinstance(exp, Expr):
        print "Input is not an expression."
        return False
    
    clauses = conjuncts(exp);
    
    for c in clauses:
        literals = disjuncts(c)
        
        for lit in literals:
            if len(lit.args) == 0:
                symbol = lit;
            elif len(lit.args) == 1:
                symbol = lit.args[0]
                
                if len(symbol.args) != 0:
                    print "Found a NOT outside of %s" % symbol
                    return False
                
            else:
                print "Found %s where only a literal should be." % lit
                return False
    
            symbol_str = str(symbol)
    
            if not is_symbol(symbol_str):
                print "%s is not a valid symbol." % symbol_str
                return False
            elif not symbol_str[0].isupper():
                print "The symbol %s must begin with an upper-case letter." % symbol_str
                return False
            elif symbol_str == 'TRUE':
                print "TRUE is not a valid symbol." % symbol_str
                return False
            elif symbol_str == 'FALSE':
                print "FALSE is not a valid symbol." % symbol_str
                return False
        
    return True
Beispiel #16
0
def is_valid_cnf(exp):
    if not isinstance(exp, Expr):
        print "Input is not an expression."
        return False

    clauses = conjuncts(exp)

    for c in clauses:
        literals = disjuncts(c)

        for lit in literals:
            if len(lit.args) == 0:
                symbol = lit
            elif len(lit.args) == 1:
                symbol = lit.args[0]

                if len(symbol.args) != 0:
                    print "Found a NOT outside of %s" % symbol
                    return False

            else:
                print "Found %s where only a literal should be." % lit
                return False

            symbol_str = str(symbol)

            if not is_symbol(symbol_str):
                print "%s is not a valid symbol." % symbol_str
                return False
            elif not symbol_str[0].isupper():
                print "The symbol %s must begin with an upper-case letter." % symbol_str
                return False
            elif symbol_str == 'TRUE':
                print "TRUE is not a valid symbol." % symbol_str
                return False
            elif symbol_str == 'FALSE':
                print "FALSE is not a valid symbol." % symbol_str
                return False

    return True
Beispiel #17
0
 def result(self, state, action):
     terms = parse_state(state)
     sentence = str(
         logic.associate(
             '&',
             action(logic.conjuncts(state), action.args).clauses))
     #print('------------\nBefore: ' + sentence)
     while sentence.find('divide(x)') != -1:
         quotient = terms[4] / terms[0]
         terms[0] = 1
         terms[4] = quotient
         sentence = sentence.replace('divide(x)', '{:.2f}'.format(quotient))
     while sentence.find('combine') != -1:
         start = sentence.find('combine')
         term = int(sentence[start + 9]) - 1
         if term < 3:
             new_val = terms[term] + terms[2]
             terms[term] = new_val
             terms[2] = 0
         else:
             new_val = terms[term] + terms[5]
             terms[term] = new_val
             terms[5] = 0
         sentence = sentence.replace(sentence[start:(start + 11)],
                                     str(new_val))
     while sentence.find('inverse') != -1:
         start = sentence.find('inverse')
         term = int(sentence[start + 9]) - 1
         new_val = -1 * terms[term]
         if term == 3:
             terms[2] = new_val
         elif term == 1:
             terms[5] = new_val
         terms[term] = 0
         sentence = sentence.replace(sentence[start:(start + 11)],
                                     str(new_val))
     #print('After: ' + sentence + '\n------------')
     return logic.associate('&', self.convert(sentence.replace('Not', '~')))
Beispiel #18
0
 def tell(self, sentence):
     self.clauses.update(
         map(frozenset, map(set, map(disjuncts,
                                     conjuncts(to_cnf(sentence))))))
Beispiel #19
0
 def goal_test(self):
     """Checks if the goals have been reached"""
     return all(goal in self.init for goal in conjuncts(self.goals))