def convert(self, init): """Converts strings into exprs""" try: init = conjuncts(expr(init)) except AttributeError: init = expr(init) return init
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
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
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
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
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
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
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
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)
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
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
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
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', '~')))
def tell(self, sentence): self.clauses.update( map(frozenset, map(set, map(disjuncts, conjuncts(to_cnf(sentence))))))
def goal_test(self): """Checks if the goals have been reached""" return all(goal in self.init for goal in conjuncts(self.goals))