def refinements(hla, state, library): # TODO - refinements may be (multiple) HLA themselves ... """ state is a Problem, containing the current state kb library is a dictionary containing details for every possible refinement. eg: { 'HLA': ['Go(Home,SFO)', 'Go(Home,SFO)', 'Drive(Home, SFOLongTermParking)', 'Shuttle(SFOLongTermParking, SFO)', 'Taxi(Home, SFO)'], 'steps': [['Drive(Home, SFOLongTermParking)', 'Shuttle(SFOLongTermParking, SFO)'], ['Taxi(Home, SFO)'], [], [], []], # empty refinements ie primitive action 'precond': [['At(Home), Have(Car)'], ['At(Home)'], ['At(Home)', 'Have(Car)'], ['At(SFOLongTermParking)'], ['At(Home)']], 'effect': [['At(SFO)'], ['At(SFO)'], ['At(SFOLongTermParking)'], ['At(SFO)'], ['At(SFO)'], ['~At(Home)'], ['~At(Home)'], ['~At(Home)'], ['~At(SFOLongTermParking)'], ['~At(Home)']] } """ e = Expr(hla.name, hla.args) indices = [i for i, x in enumerate(library['HLA']) if expr(x).op == hla.name] for i in indices: # TODO multiple refinements precond = [] for p in library['precond'][i]: if p[0] == '~': precond.append(expr('Not' + p[1:])) else: precond.append(expr(p)) effect = [] for e in library['effect'][i]: if e[0] == '~': effect.append(expr('Not' + e[1:])) else: effect.append(expr(e)) action = HLA(library['steps'][i][0], precond, effect) if action.check_precond(state.init, action.args): yield action
def test_extend_example(): assert list(test_network.extend_example({x: A, y: B}, expr('Conn(x, z)'))) == [ {x: A, y: B, z: B}, {x: A, y: B, z: D}] assert list(test_network.extend_example({x: G}, expr('Conn(x, y)'))) == [{x: G, y: I}] assert list(test_network.extend_example({x: C}, expr('Conn(x, y)'))) == [] assert len(list(test_network.extend_example({}, expr('Conn(x, y)')))) == 10 assert len(list(small_family.extend_example({x: expr('Andrew')}, expr('Father(x, y)')))) == 2 assert len(list(small_family.extend_example({x: expr('Andrew')}, expr('Mother(x, y)')))) == 0 assert len(list(small_family.extend_example({x: expr('Andrew')}, expr('Female(y)')))) == 6
def __init__(self, goals, initial_clauses=None): if initial_clauses is None: initial_clauses = [] initial_clauses = [expr(c) if not isinstance(c, Expr) else c for c in initial_clauses] self.clause_set = frozenset(initial_clauses) goals = [expr(g) if not isinstance(g, Expr) else g for g in goals] self.goal_clauses = frozenset(goals)
def test_have_cake_and_eat_cake_too(): p = have_cake_and_eat_cake_too() assert p.goal_test() is False solution = [expr("Eat(Cake)"), expr("Bake(Cake)")] for action in solution: p.act(action) assert p.goal_test()
def test_three_block_tower(): p = three_block_tower() assert p.goal_test() is False solution = [expr("MoveToTable(C, A)"), expr("Move(B, Table, C)"), expr("Move(A, Table, B)")] for action in solution: p.act(action) assert p.goal_test()
def test_spare_tire(): p = spare_tire() assert p.goal_test() is False solution = [expr("Remove(Flat, Axle)"), expr("Remove(Spare, Trunk)"), expr("PutOn(Spare, Axle)")] for action in solution: p.act(action) assert p.goal_test()
def test_double_tennis(): p = double_tennis_problem() assert p.goal_test() is False solution = [expr("Go(A, RightBaseLine, LeftBaseLine)"), expr("Hit(A, Ball, RightBaseLine)"), expr("Go(A, LeftNet, RightBaseLine)")] for action in solution: p.act(action) assert p.goal_test()
def to_cnf(s): """Convert a propositional logical sentence to conjunctive normal form. That is, to the form ((A | ~B | ...) & (B | C | ...) & ...) [p. 253] >>> to_cnf('~(B | C)') (~B & ~C) """ s = expr(s) if isinstance(s, str): s = expr(s) s = eliminate_implications(s) # Steps 1, 2 from p. 253 s = move_not_inwards(s) # Step 3 return distribute_and_over_or(s) # Step 4
def test_new_clause(): target = expr('Open(x, y)') examples_pos = [{x: B}, {x: A}, {x: G}] examples_neg = [{x: C}, {x: F}, {x: I}] clause = test_network.new_clause([examples_pos, examples_neg], target)[0][1] assert len(clause) == 1 and clause[0].op == 'Conn' and clause[0].args[0] == x target = expr('Flow(x, y)') examples_pos = [{x: B}, {x: D}, {x: E}, {x: G}] examples_neg = [{x: A}, {x: C}, {x: F}, {x: I}, {x: H}] clause = test_network.new_clause([examples_pos, examples_neg], target)[0][1] assert len(clause) == 2 and \ ((clause[0].args[0] == x and clause[1].args[1] == x) or \ (clause[0].args[1] == x and clause[1].args[0] == x))
def from_action(cls, action): op = action.name args = action.args preconds = [] for p in action.precond: precond_op = p.op.replace('Not', '~') precond_args = [repr(a) for a in p.args] preconds.append(expr(build_expr_string(precond_op, precond_args))) effects = [] for e in action.effect: effect_op = e.op.replace('Not', '~') effect_args = [repr(a) for a in e.args] effects.append(expr(build_expr_string(effect_op, effect_args))) return cls(Expr(op, *args), preconds, effects)
def have_cake_and_eat_cake_too(): init = [expr('Have(Cake)')] def goal_test(kb): required = [expr('Have(Cake)'), expr('Eaten(Cake)')] for q in required: if kb.ask(q) is False: return False return True ##Actions # Eat cake precond_pos = [expr('Have(Cake)')] precond_neg = [] effect_add = [expr('Eaten(Cake)')] effect_rem = [expr('Have(Cake)')] eat_cake = Action(expr('Eat(Cake)'), [precond_pos, precond_neg], [effect_add, effect_rem]) #Bake Cake precond_pos = [] precond_neg = [expr('Have(Cake)')] effect_add = [expr('Have(Cake)')] effect_rem = [] bake_cake = Action(expr('Bake(Cake)'), [precond_pos, precond_neg], [effect_add, effect_rem]) return PDLL(init, [eat_cake, bake_cake], goal_test)
def __init__(self, expression, preconds, effects): if isinstance(expression, str): expression = expr(expression) preconds = [expr(p) if not isinstance(p, Expr) else p for p in preconds] effects = [expr(e) if not isinstance(e, Expr) else e for e in effects] self.name = expression.op self.args = expression.args self.subst = None precond_neg, precond_pos = partition(preconds, is_negative_clause) self.precond_pos = set(precond_pos) self.precond_neg = set(e.args[0] for e in precond_neg) # change the negative Exprs to positive for evaluation effect_rem, effect_add = partition(effects, is_negative_clause) self.effect_add = set(effect_add) self.effect_rem = set(e.args[0] for e in effect_rem) # change the negative Exprs to positive for evaluation
def tt_true(s): """Is a propositional sentence a tautology? >>> tt_true('P | ~P') True """ s = expr(s) return tt_entails(True, s)
def __init__(self, action, precond, effect): if isinstance(action, str): action = expr(action) self.name = action.op self.args = action.args self.precond = self.convert(precond) self.effect = self.convert(effect)
def distribute_and_over_or(s): """Given a sentence s consisting of conjunctions and disjunctions of literals, return an equivalent sentence in CNF. >>> distribute_and_over_or((A & B) | C) ((A | C) & (B | C)) """ s = expr(s) if s.op == '|': s = associate('|', s.args) if s.op != '|': return distribute_and_over_or(s) if len(s.args) == 0: return False if len(s.args) == 1: return distribute_and_over_or(s.args[0]) conj = first(arg for arg in s.args if arg.op == '&') if not conj: return s others = [a for a in s.args if a is not conj] rest = associate('|', others) return associate('&', [distribute_and_over_or(c | rest) for c in conj.args]) elif s.op == '&': return associate('&', list(map(distribute_and_over_or, s.args))) else: return s
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 test_find_open_precondition(): st = spare_tire() pop = PartialOrderPlanner(st) assert pop.find_open_precondition()[0] == expr('At(Spare, Axle)') assert pop.find_open_precondition()[1] == pop.finish assert pop.find_open_precondition()[2][0].name == 'PutOn' ss = socks_and_shoes() pop = PartialOrderPlanner(ss) assert (pop.find_open_precondition()[0] == expr('LeftShoeOn') and pop.find_open_precondition()[2][0].name == 'LeftShoe') or (pop.find_open_precondition()[0] == expr('RightShoeOn') and pop.find_open_precondition()[2][0].name == 'RightShoe') assert pop.find_open_precondition()[1] == pop.finish cp = have_cake_and_eat_cake_too() pop = PartialOrderPlanner(cp) assert pop.find_open_precondition()[0] == expr('Eaten(Cake)') assert pop.find_open_precondition()[1] == pop.finish assert pop.find_open_precondition()[2][0].name == 'Eat'
def test_convert_angelic_HLA(): """ Converts angelic HLA's into expressions that correspond to their actions ~ : Delete (Not) $+ : Possibly add (PosYes) $-: Possibly delete (PosNo) $$: Possibly add / delete (PosYesNo) """ ang1 = AngelicHLA('Test', precond=None, effect='~A') ang2 = AngelicHLA('Test', precond=None, effect='$+A') ang3 = AngelicHLA('Test', precond=None, effect='$-A') ang4 = AngelicHLA('Test', precond=None, effect='$$A') assert (ang1.convert(ang1.effect) == [expr('NotA')]) assert (ang2.convert(ang2.effect) == [expr('PosYesA')]) assert (ang3.convert(ang3.effect) == [expr('PosNotA')]) assert (ang4.convert(ang4.effect) == [expr('PosYesNotA')])
def test_graph_call(): pddl = spare_tire() negkb = FolKB([expr('At(Flat, Trunk)')]) graph = Graph(pddl, negkb) levels_size = len(graph.levels) graph() assert levels_size == len(graph.levels) - 1
def test_graph_call(): pdll = spare_tire() negkb = FolKB([expr('At(Flat, Trunk)')]) graph = Graph(pdll, negkb) levels_size = len(graph.levels) graph() assert levels_size == len(graph.levels) - 1
def spare_tire_graphplan(): pdll = spare_tire() negkb = FolKB([expr('At(Flat, Trunk)')]) graphplan = GraphPlan(pdll, negkb) ##Not sure goals_pos = [expr('At(Spare, Axle)'), expr('At(Flat, Ground)')] goals_neg = [] while True: if goal_test(graphplan.graph.levels[-1].poskb, goals_pos) and graphplan.graph.non_mutex_goals( goals_pos + goals_neg, -1): solution = graphplan.extract_solution(goals_pos, goals_neg, -1) if solution: return solution graphplan.graph.expand_graph() if len(graphplan.graph.levels) >= 2 and graphplan.check_leveloff(): return None
def test_new_literals(): assert len(list(test_network.new_literals([expr('p | q'), [expr('p')]]))) == 8 assert len( list(test_network.new_literals([expr('p'), [expr('q'), expr('p | r')]]))) == 15 assert len(list(small_family.new_literals([expr('p'), []]))) == 8 assert len(list(small_family.new_literals([expr('p & q'), []]))) == 20
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, 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 test_x_in_2_1_3(): answer = kb.ask_generator( expr('Pert(x, (Ins(Two,Ins(One ,Ins(Three, EmptyList)))))')) for i in answer: if i == 0: assert i.x == 'Two' if i == 1: assert i.x == 'One' if i == 2: assert i.x == 'Three'
def test_inconsistent_support_mutex(self): self.assertFalse(PlanningGraph.inconsistent_support_mutex(self.pg, self.ns1, self.ns2), "Independent node paths should NOT be inconsistent-support mutex") mutexify(self.na1, self.na2) self.assertTrue(PlanningGraph.inconsistent_support_mutex(self.pg, self.ns1, self.ns2), "Mutex parent actions should result in inconsistent-support mutex") self.na6 = PgNode_a(Action(expr('Go(everywhere)'), [[], []], [[expr('At(here)'), expr('At(there)')], []])) self.na6.children.add(self.ns1) self.ns1.parents.add(self.na6) self.na6.children.add(self.ns2) self.ns2.parents.add(self.na6) self.na6.parents.add(self.ns3) self.na6.parents.add(self.ns4) mutexify(self.na1, self.na6) mutexify(self.na2, self.na6) self.assertFalse(PlanningGraph.inconsistent_support_mutex( self.pg, self.ns1, self.ns2), "If one parent action can achieve both states, should NOT be inconsistent-support mutex, even if parent actions are themselves mutex")
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 nested_tell_inner(KB, clause): """ Assert a clause and, when lhs(clause) is not null, also a set of implications where lhs is clause and rhs a derived clause producted by produce_clauses accordingly to a specific knowledge base.""" if str(clause).find("==>") == -1: derived = [] KB.produce_clauses(clause, derived) for derived_clause in derived: if unify(clause, derived_clause) is None: new_clause = str(clause) + " ==> " + str(derived_clause) KB.tell(expr(new_clause)) if clause not in KB.clauses: KB.tell(clause)
def test_x_y_concat_1_2_3(): answer = kb.ask_generator( expr('Concat(x, y, Ins(One, Ins(Two, Ins(Three, EmptyList))))')) for i in answer: if i == 0: assert i.x == 'EmptyList' and i.y == 'Ins(One, Ins(Two, Ins(Three, EmptyList)))' # x == [] & y == [1,2,3] if i == 1: assert i.x == 'Ins(One, EmptyList)' and i.y == 'Ins(Two, Ins(Three, EmptyList))' # x == [1] & y == [2,3] if i == 2: assert i.x == 'Ins(Two, Ins(One, EmptyList))' and i.y == 'Ins(Three, EmptyList)' # x == [1,2] & y == [3] if i == 3: assert i.x == 'Ins(Three, Ins(Two, Ins(One, EmptyList)))' and i.y == 'EmptyList' # x == [1,2,3] & y == []
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 spare_tire_graphplan(): pddl = spare_tire() negkb = FolKB([expr('At(Flat, Trunk)')]) graphplan = GraphPlan(pddl, negkb) def goal_test(kb, goals): return all(kb.ask(q) is not False for q in goals) # Not sure goals_pos = [expr('At(Spare, Axle)'), expr('At(Flat, Ground)')] goals_neg = [] while True: if (goal_test(graphplan.graph.levels[-1].poskb, goals_pos) and graphplan.graph.non_mutex_goals(goals_pos+goals_neg, -1)): solution = graphplan.extract_solution(goals_pos, goals_neg, -1) if solution: return solution graphplan.graph.expand_graph() if len(graphplan.graph.levels)>=2 and graphplan.check_leveloff(): return None
def test_SATPlan(): spare_tire_solution = SATPlan(spare_tire(), 3) assert expr('Remove(Flat, Axle)') in spare_tire_solution assert expr('Remove(Spare, Trunk)') in spare_tire_solution assert expr('PutOn(Spare, Axle)') in spare_tire_solution cake_solution = SATPlan(have_cake_and_eat_cake_too(), 2) assert expr('Eat(Cake)') in cake_solution assert expr('Bake(Cake)') in cake_solution blocks_world_solution = SATPlan(simple_blocks_world(), 3) assert expr('ToTable(A, B)') in blocks_world_solution assert expr('FromTable(B, A)') in blocks_world_solution assert expr('FromTable(C, B)') in blocks_world_solution
def refinements( hla, state, library ): # TODO - refinements may be (multiple) HLA themselves ... """ state is a Problem, containing the current state kb library is a dictionary containing details for every possible refinement. eg: { "HLA": [ "Go(Home,SFO)", "Go(Home,SFO)", "Drive(Home, SFOLongTermParking)", "Shuttle(SFOLongTermParking, SFO)", "Taxi(Home, SFO)" ], "steps": [ ["Drive(Home, SFOLongTermParking)", "Shuttle(SFOLongTermParking, SFO)"], ["Taxi(Home, SFO)"], [], # empty refinements ie primitive action [], [] ], "precond_pos": [ ["At(Home), Have(Car)"], ["At(Home)"], ["At(Home)", "Have(Car)"] ["At(SFOLongTermParking)"] ["At(Home)"] ], "precond_neg": [[],[],[],[],[]], "effect_pos": [ ["At(SFO)"], ["At(SFO)"], ["At(SFOLongTermParking)"], ["At(SFO)"], ["At(SFO)"] ], "effect_neg": [ ["At(Home)"], ["At(Home)"], ["At(Home)"], ["At(SFOLongTermParking)"], ["At(Home)"] ] } """ e = Expr(hla.name, hla.args) indices = [ i for i, x in enumerate(library["HLA"]) if expr(x).op == hla.name ] for i in indices: action = HLA( expr(library["steps"][i][0]), [ # TODO multiple refinements [expr(x) for x in library["precond_pos"][i]], [expr(x) for x in library["precond_neg"][i]] ], [[expr(x) for x in library["effect_pos"][i]], [expr(x) for x in library["effect_neg"][i]]]) if action.check_precond(state.kb, action.args): yield action
def test_angelic_search(): """ Test angelic search for problem, hierarchy, initialPlan """ #test_1 prob_1 = Problem('At(Home) & Have(Cash) & Have(Car) ', 'At(SFO) & Have(Cash)', [go_SFO, taxi_SFO, drive_SFOLongTermParking, shuttle_SFO]) angelic_opt_description = Angelic_HLA('Go(Home, SFO)', precond='At(Home)', effect='$+At(SFO) & $-At(Home)') angelic_pes_description = Angelic_HLA('Go(Home, SFO)', precond='At(Home)', effect='$+At(SFO) & ~At(Home)') initialPlan = [ Angelic_Node(prob_1.init, None, [angelic_opt_description], [angelic_pes_description]) ] solution = Problem.angelic_search(prob_1, library_1, initialPlan) assert (len(solution) == 2) assert (solution[0].name == drive_SFOLongTermParking.name) assert (solution[0].args == drive_SFOLongTermParking.args) assert (solution[1].name == shuttle_SFO.name) assert (solution[1].args == shuttle_SFO.args) #test_2 solution_2 = Problem.angelic_search(prob_1, library_2, initialPlan) assert (len(solution_2) == 2) assert (solution_2[0].name == 'Bus') assert (solution_2[0].args == (expr('Home'), expr('MetroStop'))) assert (solution_2[1].name == 'Metro1') assert (solution_2[1].args == (expr('MetroStop'), expr('SFO')))
def test_refinements(): library = { 'HLA': ['Go(Home,SFO)', 'Taxi(Home, SFO)'], 'steps': [['Taxi(Home, SFO)'], []], 'precond': [['At(Home)'], ['At(Home)']], 'effect': [['At(SFO)'], ['At(SFO)'], ['~At(Home)'], ['~At(Home)']] } go_SFO = HLA('Go(Home,SFO)', precond='At(Home)', effect='At(SFO) & ~At(Home)') taxi_SFO = HLA('Go(Home,SFO)', precond='At(Home)', effect='At(SFO) & ~At(Home)') prob = Problem('At(Home)', 'At(SFO)', [go_SFO, taxi_SFO]) result = [i for i in Problem.refinements(go_SFO, prob, library)] assert (len(result) == 1) assert (result[0].name == 'Taxi') assert (result[0].args == (expr('Home'), expr('SFO')))
def giveFeedback(studentState): feedback_kb = PropKB() # The implementation of .tell() is found in logic.py # def to_cnf(s): -> This takes in the string passed into .tell() # def eliminate_implications(s): -> This will parse the expressions and logic symbols # CorrectAnswer => (Message1 v Message2 v Message3 v Message7) feedback_kb.tell( 'CorrectAnswer ==> (Message1 | Message2 | Message3 | Message7)') # ~CorrectAnswer => (Message4 v Message5 v Message6 v Message8) feedback_kb.tell( '~CorrectAnswer ==> (Message4 | Message5 | Message6 | Message8)') # (MasteredSkill & IncorrectAnswer) v (MasteredSkill & CorrectStreak) => IsBored feedback_kb.tell( '(MasteredSkill & ~CorrectAnswer) | (MasteredSkill & CorrectStreak) ==> IsBored' ) # NewSkill v IncorrectStreak => Message6 feedback_kb.tell('NewSkill | IncorrectStreak ==> Message6') # (IncorrectStreak & CorrectAnswer) v (NewSkill & CorrectStreak) => NeedsEncouragement feedback_kb.tell( '(IncorrectStreak & CorrectAnswer) | (NewSkill & CorrectStreak) ==> NeedsEncouragement' ) # NeedsEncouragement => Message2 v Message4 feedback_kb.tell('NeedsEncouragement ==> Message2 | Message4') # IsBored => Message3 v Message5 feedback_kb.tell('IsBored ==> Message3 | Message5') # (NewSkill & CorrectAnswer) v CorrectStreak => Message1 feedback_kb.tell('(NewSkill & CorrectAnswer) | CorrectStreak ==> Message1') feedback_kb.tell(expr(studentState)) message = "NONE FOUND" # Look for the correct message for m in message_arr: # print("Finding if " + m + " is TRUE in the KB") foundMessage = pl_resolution(feedback_kb, expr(m)) if foundMessage: return message_lookup[m] else: feedback_kb.tell(expr("~" + m))
def eliminate_implications(s): "Change implications into equivalent form with only &, |, and ~ as logical operators." if s == False: s = expr("F") if s == True: s = expr("T") s = expr(s) if not s.args or is_symbol(s.op): return s # Atoms are unchanged. args = list(map(eliminate_implications, s.args)) a, b = args[0], args[-1] if s.op == '==>': return b | ~a elif s.op == '<==': return a | ~b elif s.op == '<=>': return (a | ~b) & (b | ~a) elif s.op == '^': assert len(args) == 2 # TODO: relax this restriction return (a & ~b) | (~a & b) else: assert s.op in ('&', '|', '~') return Expr(s.op, *args)
def main(): a = [i for i in range(10) if i % 2 == 1] b = [i for i in range(10, 16) if i % 2 == 1] print(a) print(b) c = [(i, j) for (i, j) in zip(a, b)] print(c) testThing() a = utils.expr('A & B') A = Expr('A') B = Expr('B') print(logic.pl_true(a, {A: True, B: True}))
def test_extend_example(): """ Create the extended examples of the given clause. (The extended examples are a set of examples created by extending example with each possible constant value for each new variable in literal.) """ assert len(list(small_family.extend_example({x: expr('Andrew')}, expr('Father(x, y)')))) == 2 assert len(list(small_family.extend_example({x: expr('Andrew')}, expr('Mother(x, y)')))) == 0 assert len(list(small_family.extend_example({x: expr('Andrew')}, expr('Female(y)')))) == 6
def refinements(hla, state, library): # TODO - refinements may be (multiple) HLA themselves ... """ state is a Problem, containing the current state kb library is a dictionary containing details for every possible refinement. eg: { "HLA": [ "Go(Home,SFO)", "Go(Home,SFO)", "Drive(Home, SFOLongTermParking)", "Shuttle(SFOLongTermParking, SFO)", "Taxi(Home, SFO)" ], "steps": [ ["Drive(Home, SFOLongTermParking)", "Shuttle(SFOLongTermParking, SFO)"], ["Taxi(Home, SFO)"], [], # empty refinements ie primitive action [], [] ], "precond_pos": [ ["At(Home), Have(Car)"], ["At(Home)"], ["At(Home)", "Have(Car)"] ["At(SFOLongTermParking)"] ["At(Home)"] ], "precond_neg": [[],[],[],[],[]], "effect_pos": [ ["At(SFO)"], ["At(SFO)"], ["At(SFOLongTermParking)"], ["At(SFO)"], ["At(SFO)"] ], "effect_neg": [ ["At(Home)"], ["At(Home)"], ["At(Home)"], ["At(SFOLongTermParking)"], ["At(Home)"] ] } """ e = Expr(hla.name, hla.args) indices = [i for i,x in enumerate(library["HLA"]) if expr(x).op == hla.name] for i in indices: action = HLA(expr(library["steps"][i][0]), [ # TODO multiple refinements [expr(x) for x in library["precond_pos"][i]], [expr(x) for x in library["precond_neg"][i]] ], [ [expr(x) for x in library["effect_pos"][i]], [expr(x) for x in library["effect_neg"][i]] ]) if action.check_precond(state.kb, action.args): yield action
def goal_test(kb): # print(kb.clauses) required = [expr('Has(C1, W1)'), expr('Has(C1, E1)'), expr('Inspected(C1)'), expr('Has(C2, W2)'), expr('Has(C2, E2)'), expr('Inspected(C2)')] for q in required: # print(q) # print(kb.ask(q)) if kb.ask(q) is False: return False return True
def test_tell(): """ adds in the knowledge base a sentence """ smaller_family.tell(expr("Male(George)")) smaller_family.tell(expr("Female(Mum)")) assert smaller_family.ask(expr("Male(George)")) == {} assert smaller_family.ask(expr("Female(Mum)"))=={} assert not smaller_family.ask(expr("Female(George)")) assert not smaller_family.ask(expr("Male(Mum)"))
def test_angelic_action(): """ Finds the HLA actions that correspond to the HLA actions with angelic semantics h1 : precondition positive: B _______ (add A) or (add A and remove B) effect: add A and possibly remove B h2 : precondition positive: A _______ (add A and add C) or (delete A and add C) or (add C) or (add A and delete C) or effect: possibly add/remove A and possibly add/remove C (delete A and delete C) or (delete C) or (add A) or (delete A) or [] """ h_1 = Angelic_HLA( expr('h1'), 'B' , 'A & $-B') h_2 = Angelic_HLA( expr('h2'), 'A', '$$A & $$C') action_1 = Angelic_HLA.angelic_action(h_1) action_2 = Angelic_HLA.angelic_action(h_2) assert ([a.effect for a in action_1] == [ [expr('A'),expr('NotB')], [expr('A')]] ) assert ([a.effect for a in action_2] == [[expr('A') , expr('C')], [expr('NotA'), expr('C')], [expr('C')], [expr('A'), expr('NotC')], [expr('NotA'), expr('NotC')], [expr('NotC')], [expr('A')], [expr('NotA')], [None] ] )
def test_find_reachable_set(): h_1 = AngelicHLA('h1', 'B', '$+A & $-B ') f_1 = HLA('h1', 'B', 'A & ~B') problem = RealWorldPlanningProblem('B', 'A', [f_1]) reachable_set = {0: [problem.initial]} action_description = [h_1] reachable_set = RealWorldPlanningProblem.find_reachable_set( reachable_set, action_description) assert (reachable_set[1] == [[expr('A'), expr('NotB')], [expr('NotB')], [expr('B'), expr('A')], [expr('B')]])
def test_find_reachable_set(): h_1 = Angelic_HLA('h1', 'B', '$+A & $-B ') f_1 = HLA('h1', 'B', 'A & ~B') problem = Problem('B', 'A', [f_1]) plan = Angelic_Node(problem.init, None, [h_1], [h_1]) reachable_set = {0: [problem.init]} action_description = [h_1] reachable_set = Problem.find_reachable_set(reachable_set, action_description) assert (reachable_set[1] == [[expr('A'), expr('NotB')], [expr('NotB')], [expr('B'), expr('A')], [expr('B')]])
def shopping_graphplan(): pddl = shopping_problem() graphplan = GraphPlan(pddl) def goal_test(kb, goals): return all(kb.ask(q) is not False for q in goals) goals = expr('Have(Milk), Have(Banana), Have(Drill)') while True: if (goal_test(graphplan.graph.levels[-1].kb, goals) and graphplan.graph.non_mutex_goals(goals, -1)): solution = graphplan.extract_solution(goals, -1) if solution: return solution graphplan.graph.expand_graph() if len(graphplan.graph.levels) >= 2 and graphplan.check_leveloff(): return None
def socks_and_shoes_graphplan(): pddl = socks_and_shoes() graphplan = GraphPlan(pddl) def goal_test(kb, goals): return all(kb.ask(q) is not False for q in goals) goals = expr('RightShoeOn, LeftShoeOn') while True: if (goal_test(graphplan.graph.levels[-1].kb, goals) and graphplan.graph.non_mutex_goals(goals, -1)): solution = graphplan.extract_solution(goals, -1) if solution: return solution graphplan.graph.expand_graph() if len(graphplan.graph.levels) >= 2 and graphplan.check_leveloff(): return None
def predictSuccess(current_skills, equation): plan = solveEquation(equation) KnownKB = logic.FolKB() # Create FOL knowledge base NeedKB = logic.FolKB() # Create FOL knowledge base for skill in current_skills: KnownKB.tell(expr(skill + '(x)')) getNeededSkills(plan, NeedKB) for i in range(len(NeedKB.clauses) - 1, -1, -1): new_skill = NeedKB.clauses[i] for skill in KnownKB.clauses: if logic.unify(new_skill, skill) is not None: NeedKB.retract(new_skill) missing_skills = set() for clause in NeedKB.clauses: missing_skills.add(clause.op) return list(missing_skills)
def eliminate_implications(s): "Change implications into equivalent form with only &, |, and ~ as logical operators." s = expr(s) if not s.args or is_symbol(s.op): return s # Atoms are unchanged. args = list(map(eliminate_implications, s.args)) a, b = args[0], args[-1] if s.op == '==>': return b | ~a elif s.op == '<==': return a | ~b elif s.op == '<=>': return (a | ~b) & (b | ~a) elif s.op == '^': assert len(args) == 2 # TODO: relax this restriction return (a & ~b) | (~a & b) else: assert s.op in ('&', '|', '~') return Expr(s.op, *args)
def test_air_cargo_2(): p = air_cargo() assert p.goal_test() is False solution_2 = [expr("Load(C2, P2, JFK)"), expr("Fly(P2, JFK, SFO)"), expr("Unload (C2, P2, SFO)"), expr("Load(C1 , P1, SFO)"), expr("Fly(P1, SFO, JFK)"), expr("Unload(C1, P1, JFK)")] for action in solution_2: p.act(action) assert p.goal_test()
def air_cargo_graphplan(): """Solves the air cargo problem using GraphPlan""" pddl = air_cargo() graphplan = GraphPlan(pddl) def goal_test(kb, goals): return all(kb.ask(q) is not False for q in goals) goals = expr('At(C1, JFK), At(C2, SFO)') while True: if (goal_test(graphplan.graph.levels[-1].kb, goals) and graphplan.graph.non_mutex_goals(goals, -1)): solution = graphplan.extract_solution(goals, -1) if solution: return solution graphplan.graph.expand_graph() if len(graphplan.graph.levels) >= 2 and graphplan.check_leveloff(): return None
def three_block_tower_graphplan(): """Solves the Sussman Anomaly problem using GraphPlan""" pddl = three_block_tower() graphplan = GraphPlan(pddl) def goal_test(kb, goals): return all(kb.ask(q) is not False for q in goals) goals = expr('On(A, B), On(B, C)') while True: if (goal_test(graphplan.graph.levels[-1].kb, goals) and graphplan.graph.non_mutex_goals(goals, -1)): solution = graphplan.extract_solution(goals, -1) if solution: return solution graphplan.graph.expand_graph() if len(graphplan.graph.levels) >= 2 and graphplan.check_leveloff(): return None
def have_cake_and_eat_cake_too_graphplan(): """Solves the cake problem using GraphPlan""" pddl = have_cake_and_eat_cake_too() graphplan = GraphPlan(pddl) def goal_test(kb, goals): return all(kb.ask(q) is not False for q in goals) goals = expr('Have(Cake), Eaten(Cake)') while True: graphplan.graph.expand_graph() if (goal_test(graphplan.graph.levels[-1].kb, goals) and graphplan.graph.non_mutex_goals(goals, -1)): solution = graphplan.extract_solution(goals, -1) if solution: return [solution[1]] if len(graphplan.graph.levels) >= 2 and graphplan.check_leveloff(): return None
def spare_tire_graphplan(): """Solves the spare tire problem using GraphPlan""" pddl = spare_tire() graphplan = GraphPlan(pddl) def goal_test(kb, goals): return all(kb.ask(q) is not False for q in goals) goals = expr('At(Spare, Axle), At(Flat, Ground)') while True: graphplan.graph.expand_graph() if (goal_test(graphplan.graph.levels[-1].kb, goals) and graphplan.graph.non_mutex_goals(goals, -1)): solution = graphplan.extract_solution(goals, -1) if solution: return solution if len(graphplan.graph.levels) >= 2 and graphplan.check_leveloff(): return None
def move_not_inwards(s): """Rewrite sentence s by moving negation sign inward. >>> move_not_inwards(~(A | B)) (~A & ~B)""" s = expr(s) if s.op == '~': def NOT(b): return move_not_inwards(~b) a = s.args[0] if a.op == '~': return move_not_inwards(a.args[0]) # ~~A ==> A if a.op == '&': return associate('|', list(map(NOT, a.args))) if a.op == '|': return associate('&', list(map(NOT, a.args))) return s elif is_symbol(s.op) or not s.args: return s else: return Expr(s.op, *list(map(move_not_inwards, s.args)))