From e14c34b980fdc2bf19eb326e7d4b967f0ad6a1c0 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Fri, 17 Mar 2017 17:17:51 +0530 Subject: [PATCH 01/51] Update utils.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in pseudo code the sequence of arguments is " WEIGHTED-SAMPLE-WITH-REPLACEMENT(N, S, W)"   --- utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils.py b/utils.py index 3c070293e..714512ae0 100644 --- a/utils.py +++ b/utils.py @@ -193,7 +193,7 @@ def probability(p): return p > random.uniform(0.0, 1.0) -def weighted_sample_with_replacement(seq, weights, n): +def weighted_sample_with_replacement(n,seq, weights): """Pick n samples from seq at random, with replacement, with the probability of each element in proportion to its corresponding weight.""" From 82983326e8365516366b7ebb6f2f7d12941dd82d Mon Sep 17 00:00:00 2001 From: sofmonk Date: Fri, 17 Mar 2017 17:27:54 +0530 Subject: [PATCH 02/51] Update utils.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in pseudo code the sequence of arguments is " WEIGHTED-SAMPLE-WITH-REPLACEMENT(N, S, W)"  same must follow in function "particle_filtering" in the file probability.py --- utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils.py b/utils.py index 3c070293e..714512ae0 100644 --- a/utils.py +++ b/utils.py @@ -193,7 +193,7 @@ def probability(p): return p > random.uniform(0.0, 1.0) -def weighted_sample_with_replacement(seq, weights, n): +def weighted_sample_with_replacement(n,seq, weights): """Pick n samples from seq at random, with replacement, with the probability of each element in proportion to its corresponding weight.""" From 588c3184cc81f7cb1fcf6a27ecfdca4711e2a359 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Fri, 17 Mar 2017 17:41:01 +0530 Subject: [PATCH 03/51] Update learning.py weight_sample_with_replacement sequence of args --- learning.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/learning.py b/learning.py index df5d6fce3..3e7f4690c 100644 --- a/learning.py +++ b/learning.py @@ -746,7 +746,7 @@ def weighted_replicate(seq, weights, n): wholes = [int(w * n) for w in weights] fractions = [(w * n) % 1 for w in weights] return (flatten([x] * nx for x, nx in zip(seq, wholes)) + - weighted_sample_with_replacement(seq, fractions, n - sum(wholes))) + weighted_sample_with_replacement(n - sum(wholes),seq, fractions, )) def flatten(seqs): return sum(seqs, []) From 8b2b94beee2d6041672238021b0380e6dd704802 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Fri, 17 Mar 2017 17:42:18 +0530 Subject: [PATCH 04/51] Update probability.py weighted_sample_with_replacement sequence of args --- probability.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/probability.py b/probability.py index abbc07791..d28a8a38b 100644 --- a/probability.py +++ b/probability.py @@ -651,5 +651,5 @@ def particle_filtering(e, N, HMM): w[i] = float("{0:.4f}".format(w[i])) # STEP 2 - s = weighted_sample_with_replacement(s, w, N) + s = weighted_sample_with_replacement(N,s,w) return s From 35c9d51ac5b6a79108c0a0384c0b6b41cb6340b1 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 11:03:34 +0530 Subject: [PATCH 05/51] Update search.py --- search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search.py b/search.py index 04d5b6c51..e4e20da3f 100644 --- a/search.py +++ b/search.py @@ -587,7 +587,7 @@ def genetic_algorithm(population, fitness_fn, ngen=1000, pmut=0.1): new_population = [] for i in range(len(population)): fitnesses = map(fitness_fn, population) - p1, p2 = weighted_sample_with_replacement(population, fitnesses, 2) + p1, p2 = weighted_sample_with_replacement(2,population, fitnesses) child = p1.mate(p2) if random.uniform(0, 1) < pmut: child.mutate() From 4a678711bb1e3e663efcf6d4083cf40528c9d687 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 13:29:51 +0530 Subject: [PATCH 06/51] included double_tennis_problem from chapter 11 --- planning.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/planning.py b/planning.py index a17677460..c8e1e3d87 100644 --- a/planning.py +++ b/planning.py @@ -526,3 +526,43 @@ def spare_tire_graphplan(): graphplan.graph.expand_graph() if len(graphplan.graph.levels)>=2 and graphplan.check_leveloff(): return None + + + +def double_tennis_problem(): + init = [expr('At(A, LeftBaseLine)'), + expr('At(B, RightNet)'), + expr('Approaching(Ball, RightBaseLine)'), + expr('Partner(A,B)'), + expr('Partner(A,B)')] + + + def goal_test(kb): + required = [expr('Goal(Returned(Ball'), + expr('At(a, RightNet)'), + expr('At(a, LeftNet)')] + for q in required: + if kb.ask(q) is False: + return False + return True + + + ###actions + #hit + precond_pos=[expr('Approaching(Ball,loc'),expr('At(actor,loc')] + precond_neg=[] + effect_add=[expr('Returned(Ball')] + effect_rem = [] + hit = Action(expr('Hit(actor,Ball'), [precond_pos, precond_neg], [effect_add, effect_rem]) + + ##go + precond_pos = [ expr('At(actor,loc')] + precond_neg = [] + effect_add = [expr('At(actor,to')] + effect_rem = [expr('At(actor,loc')] + go = Action(expr('Go(actor,to'), [precond_pos, precond_neg], [effect_add, effect_rem]) + + return PDLL(init, [hit, go], goal_test) + + + From 0be9f2c3c03a19d2a3ac383f0d9f859db7eef5e4 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 13:33:56 +0530 Subject: [PATCH 07/51] Update planning.py added double_tennis_problem from chapter 11 , figure 11.10 --- planning.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/planning.py b/planning.py index a17677460..347fd944d 100644 --- a/planning.py +++ b/planning.py @@ -526,3 +526,43 @@ def spare_tire_graphplan(): graphplan.graph.expand_graph() if len(graphplan.graph.levels)>=2 and graphplan.check_leveloff(): return None + + +def double_tennis_problem(): + init = [expr('At(A, LeftBaseLine)'), + expr('At(B, RightNet)'), + expr('Approaching(Ball, RightBaseLine)'), + expr('Partner(A,B)'), + expr('Partner(A,B)')] + + + def goal_test(kb): + required = [expr('Goal(Returned(Ball'), + expr('At(a, RightNet)'), + expr('At(a, LeftNet)')] + for q in required: + if kb.ask(q) is False: + return False + return True + + + ###actions + #hit + precond_pos=[expr('Approaching(Ball,loc'),expr('At(actor,loc')] + precond_neg=[] + effect_add=[expr('Returned(Ball')] + effect_rem = [] + hit = Action(expr('Hit(actor,Ball'), [precond_pos, precond_neg], [effect_add, effect_rem]) + + ##go + precond_pos = [ expr('At(actor,loc')] + precond_neg = [] + effect_add = [expr('At(actor,to')] + effect_rem = [expr('At(actor,loc')] + go = Action(expr('Go(actor,to'), [precond_pos, precond_neg], [effect_add, effect_rem]) + + return PDLL(init, [hit, go], goal_test) + + + + From 76bd895ae5327c632672c6e0b9b98a54ffddbfa6 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 13:38:12 +0530 Subject: [PATCH 08/51] Update utils.py added missing space after comma --- utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils.py b/utils.py index 714512ae0..6d181dd4c 100644 --- a/utils.py +++ b/utils.py @@ -193,7 +193,7 @@ def probability(p): return p > random.uniform(0.0, 1.0) -def weighted_sample_with_replacement(n,seq, weights): +def weighted_sample_with_replacement(n, seq, weights): """Pick n samples from seq at random, with replacement, with the probability of each element in proportion to its corresponding weight.""" From f9b8ad475792f9ef9a613c3b85e5eddf22f0c871 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 13:40:50 +0530 Subject: [PATCH 09/51] Update learning.py added missing space after comma --- learning.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/learning.py b/learning.py index 3e7f4690c..88d5e474b 100644 --- a/learning.py +++ b/learning.py @@ -746,7 +746,7 @@ def weighted_replicate(seq, weights, n): wholes = [int(w * n) for w in weights] fractions = [(w * n) % 1 for w in weights] return (flatten([x] * nx for x, nx in zip(seq, wholes)) + - weighted_sample_with_replacement(n - sum(wholes),seq, fractions, )) + weighted_sample_with_replacement(n - sum(wholes), seq, fractions)) def flatten(seqs): return sum(seqs, []) From a60ef5a6a1a2b25e4fe985636163a00e3c27f5f4 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 13:41:50 +0530 Subject: [PATCH 10/51] Update probability.py added missing space after comma --- probability.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/probability.py b/probability.py index d28a8a38b..0d7b996f4 100644 --- a/probability.py +++ b/probability.py @@ -651,5 +651,5 @@ def particle_filtering(e, N, HMM): w[i] = float("{0:.4f}".format(w[i])) # STEP 2 - s = weighted_sample_with_replacement(N,s,w) + s = weighted_sample_with_replacement(N ,s ,w) return s From f1b4e258e835306a02c581790753e3130d5cc16b Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 13:43:28 +0530 Subject: [PATCH 11/51] Update search.py added missing space after comma --- search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search.py b/search.py index e4e20da3f..45e061119 100644 --- a/search.py +++ b/search.py @@ -587,7 +587,7 @@ def genetic_algorithm(population, fitness_fn, ngen=1000, pmut=0.1): new_population = [] for i in range(len(population)): fitnesses = map(fitness_fn, population) - p1, p2 = weighted_sample_with_replacement(2,population, fitnesses) + p1, p2 = weighted_sample_with_replacement(2, population, fitnesses) child = p1.mate(p2) if random.uniform(0, 1) < pmut: child.mutate() From d45d8d4b052a4a33bc3327fa7e7b68c7fa2115ae Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 13:52:52 +0530 Subject: [PATCH 12/51] Update planning.py --- planning.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/planning.py b/planning.py index 347fd944d..b94a8526e 100644 --- a/planning.py +++ b/planning.py @@ -535,11 +535,8 @@ def double_tennis_problem(): expr('Partner(A,B)'), expr('Partner(A,B)')] - def goal_test(kb): - required = [expr('Goal(Returned(Ball'), - expr('At(a, RightNet)'), - expr('At(a, LeftNet)')] + required = [expr('Goal(Returned(Ball'), expr('At(a, RightNet)'), expr('At(a, LeftNet)')] for q in required: if kb.ask(q) is False: return False @@ -548,18 +545,18 @@ def goal_test(kb): ###actions #hit - precond_pos=[expr('Approaching(Ball,loc'),expr('At(actor,loc')] + precond_pos=[expr("Approaching(Ball,loc)"), expr("At(actor,loc)")] precond_neg=[] - effect_add=[expr('Returned(Ball')] + effect_add=[expr("Returned(Ball)")] effect_rem = [] - hit = Action(expr('Hit(actor,Ball'), [precond_pos, precond_neg], [effect_add, effect_rem]) + hit = Action(expr("Hit(actor,Ball)"), [precond_pos, precond_neg], [effect_add, effect_rem]) ##go - precond_pos = [ expr('At(actor,loc')] + precond_pos = [ expr("At(actor,loc)")] precond_neg = [] - effect_add = [expr('At(actor,to')] - effect_rem = [expr('At(actor,loc')] - go = Action(expr('Go(actor,to'), [precond_pos, precond_neg], [effect_add, effect_rem]) + effect_add = [expr("At(actor,to)")] + effect_rem = [expr("At(actor,loc)")] + go = Action(expr("Go(actor,to)"), [precond_pos, precond_neg], [effect_add, effect_rem]) return PDLL(init, [hit, go], goal_test) From c43fd7ee8a7eb63df26fac8f046bac4e79a76f2e Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 13:53:43 +0530 Subject: [PATCH 13/51] Update planning.py --- planning.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/planning.py b/planning.py index b94a8526e..d7bf3c44f 100644 --- a/planning.py +++ b/planning.py @@ -542,8 +542,7 @@ def goal_test(kb): return False return True - - ###actions + ##actions #hit precond_pos=[expr("Approaching(Ball,loc)"), expr("At(actor,loc)")] precond_neg=[] @@ -551,7 +550,7 @@ def goal_test(kb): effect_rem = [] hit = Action(expr("Hit(actor,Ball)"), [precond_pos, precond_neg], [effect_add, effect_rem]) - ##go + #go precond_pos = [ expr("At(actor,loc)")] precond_neg = [] effect_add = [expr("At(actor,to)")] From dc20b935344a62bb6069fa2b1b11e1b35e99687f Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 13:57:56 +0530 Subject: [PATCH 14/51] Update planning.py --- planning.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planning.py b/planning.py index d7bf3c44f..4002cb54b 100644 --- a/planning.py +++ b/planning.py @@ -536,7 +536,7 @@ def double_tennis_problem(): expr('Partner(A,B)')] def goal_test(kb): - required = [expr('Goal(Returned(Ball'), expr('At(a, RightNet)'), expr('At(a, LeftNet)')] + required = [expr('Goal(Returned(Ball))'), expr('At(a, RightNet)'), expr('At(a, LeftNet)')] for q in required: if kb.ask(q) is False: return False From 4bac0585b91b91419c2ec5246bc288c46d7c05f8 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 15:01:17 +0530 Subject: [PATCH 15/51] Update planning.py --- planning.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/planning.py b/planning.py index 4002cb54b..6a159cec9 100644 --- a/planning.py +++ b/planning.py @@ -558,7 +558,3 @@ def goal_test(kb): go = Action(expr("Go(actor,to)"), [precond_pos, precond_neg], [effect_add, effect_rem]) return PDLL(init, [hit, go], goal_test) - - - - From cdbbde70057d08467bc20b6bddfb0f770d84224c Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 17:01:54 +0530 Subject: [PATCH 16/51] Update planning.py --- planning.py | 67 ++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/planning.py b/planning.py index 4002cb54b..6fb952a8b 100644 --- a/planning.py +++ b/planning.py @@ -237,6 +237,39 @@ def goal_test(kb): return PDLL(init, [eat_cake, bake_cake], goal_test) + +def double_tennis_problem(): + init = [expr('At(A, LeftBaseLine)'), + expr('At(B, RightNet)'), + expr('Approaching(Ball, RightBaseLine)'), + expr('Partner(A,B)'), + expr('Partner(A,B)')] + + def goal_test(kb): + required = [expr('Goal(Returned(Ball))'), expr('At(a, RightNet)'), expr('At(a, LeftNet)')] + for q in required: + if kb.ask(q) is False: + return False + return True + + ##actions + #hit + precond_pos=[expr("Approaching(Ball,loc)"), expr("At(actor,loc)")] + precond_neg=[] + effect_add=[expr("Returned(Ball)")] + effect_rem = [] + hit = Action(expr("Hit(actor,Ball)"), [precond_pos, precond_neg], [effect_add, effect_rem]) + + #go + precond_pos = [ expr("At(actor,loc)")] + precond_neg = [] + effect_add = [expr("At(actor,to)")] + effect_rem = [expr("At(actor,loc)")] + go = Action(expr("Go(actor,to)"), [precond_pos, precond_neg], [effect_add, effect_rem]) + + return PDLL(init, [hit, go], goal_test) + + class Level(): """ Contains the state of the planning problem @@ -528,37 +561,3 @@ def spare_tire_graphplan(): return None -def double_tennis_problem(): - init = [expr('At(A, LeftBaseLine)'), - expr('At(B, RightNet)'), - expr('Approaching(Ball, RightBaseLine)'), - expr('Partner(A,B)'), - expr('Partner(A,B)')] - - def goal_test(kb): - required = [expr('Goal(Returned(Ball))'), expr('At(a, RightNet)'), expr('At(a, LeftNet)')] - for q in required: - if kb.ask(q) is False: - return False - return True - - ##actions - #hit - precond_pos=[expr("Approaching(Ball,loc)"), expr("At(actor,loc)")] - precond_neg=[] - effect_add=[expr("Returned(Ball)")] - effect_rem = [] - hit = Action(expr("Hit(actor,Ball)"), [precond_pos, precond_neg], [effect_add, effect_rem]) - - #go - precond_pos = [ expr("At(actor,loc)")] - precond_neg = [] - effect_add = [expr("At(actor,to)")] - effect_rem = [expr("At(actor,loc)")] - go = Action(expr("Go(actor,to)"), [precond_pos, precond_neg], [effect_add, effect_rem]) - - return PDLL(init, [hit, go], goal_test) - - - - From 86615b38a99d6019e3f81c18a5bf4ae702d3d54a Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 17:09:40 +0530 Subject: [PATCH 17/51] Update planning.py --- planning.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/planning.py b/planning.py index 6fb952a8b..c1130dd2f 100644 --- a/planning.py +++ b/planning.py @@ -237,7 +237,6 @@ def goal_test(kb): return PDLL(init, [eat_cake, bake_cake], goal_test) - def double_tennis_problem(): init = [expr('At(A, LeftBaseLine)'), expr('At(B, RightNet)'), @@ -269,7 +268,6 @@ def goal_test(kb): return PDLL(init, [hit, go], goal_test) - class Level(): """ Contains the state of the planning problem From 9d272b73dacef0520709e9340498935206b02ee3 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 17:26:13 +0530 Subject: [PATCH 18/51] Update test_agents.py pep8 changes, showed flake8 errors --- tests/test_agents.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/tests/test_agents.py b/tests/test_agents.py index 89ee3fcf3..7d251f547 100644 --- a/tests/test_agents.py +++ b/tests/test_agents.py @@ -1,21 +1,23 @@ from agents import Direction + def test_move_forward(): d = Direction("up") - l1 = d.move_forward((0,0)) - assert l1 == (0,-1) + l1 = d.move_forward((0, 0)) + assert l1 == (0, -1) d = Direction(Direction.R) - l1 = d.move_forward((0,0)) - assert l1 == (1,0) + l1 = d.move_forward((0, 0)) + assert l1 == (1, 0) d = Direction(Direction.D) - l1 = d.move_forward((0,0)) - assert l1 == (0,1) + l1 = d.move_forward((0, 0)) + assert l1 == (0, 1) d = Direction("left") - l1 = d.move_forward((0,0)) - assert l1 == (-1,0) - l2 = d.move_forward((1,0)) - assert l2 == (0,0) + l1 = d.move_forward((0, 0)) + assert l1 == (-1, 0) + l2 = d.move_forward((1, 0)) + assert l2 == (0, 0) + def test_add(): d = Direction(Direction.U) l1 = d + "right" @@ -36,5 +38,4 @@ def test_add(): l1 = d + Direction.R l2 = d + Direction.L assert l1.direction == Direction.U - assert l2.direction == Direction.D #fixed - + assert l2.direction == Direction.D # fixed From 1581f7a72b3f91267e5a87fcfffa0f07d0140beb Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 17:32:01 +0530 Subject: [PATCH 19/51] Update test_agents.py --- tests/test_agents.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_agents.py b/tests/test_agents.py index 7d251f547..aece69d7f 100644 --- a/tests/test_agents.py +++ b/tests/test_agents.py @@ -17,7 +17,6 @@ def test_move_forward(): l2 = d.move_forward((1, 0)) assert l2 == (0, 0) - def test_add(): d = Direction(Direction.U) l1 = d + "right" @@ -38,4 +37,4 @@ def test_add(): l1 = d + Direction.R l2 = d + Direction.L assert l1.direction == Direction.U - assert l2.direction == Direction.D # fixed + assert l2.direction == Direction.D From 7f9d0534f52faa3f137c5a14f3ed45a75080bf52 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 17:34:40 +0530 Subject: [PATCH 20/51] Update test_agents.py --- tests/test_agents.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_agents.py b/tests/test_agents.py index aece69d7f..20aa33af6 100644 --- a/tests/test_agents.py +++ b/tests/test_agents.py @@ -16,7 +16,8 @@ def test_move_forward(): assert l1 == (-1, 0) l2 = d.move_forward((1, 0)) assert l2 == (0, 0) - + + def test_add(): d = Direction(Direction.U) l1 = d + "right" @@ -37,4 +38,4 @@ def test_add(): l1 = d + Direction.R l2 = d + Direction.L assert l1.direction == Direction.U - assert l2.direction == Direction.D + assert l2.direction == Direction.D From 594736d3cb27954e496f3f171fcb41ade76078ca Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 17:38:02 +0530 Subject: [PATCH 21/51] Update test_agents.py --- tests/test_agents.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_agents.py b/tests/test_agents.py index 20aa33af6..2512ccddf 100644 --- a/tests/test_agents.py +++ b/tests/test_agents.py @@ -16,8 +16,8 @@ def test_move_forward(): assert l1 == (-1, 0) l2 = d.move_forward((1, 0)) assert l2 == (0, 0) - - + + def test_add(): d = Direction(Direction.U) l1 = d + "right" From b6f9de464bda1d5bf2ef5c5a16f4da59f9881805 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 17:41:23 +0530 Subject: [PATCH 22/51] Update test_text.py added missing whitespace after comma --- tests/test_text.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_text.py b/tests/test_text.py index d58cd497a..577ad661b 100644 --- a/tests/test_text.py +++ b/tests/test_text.py @@ -54,7 +54,7 @@ def test_viterbi_segmentation(): P = UnigramTextModel(wordseq) text = "itiseasytoreadwordswithoutspaces" - s, p = viterbi_segment(text,P) + s, p = viterbi_segment(text, P) assert s == [ 'it', 'is', 'easy', 'to', 'read', 'words', 'without', 'spaces'] From 7d5dcba1de45cd511e85e44ce197eccf2f717c31 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 17:48:32 +0530 Subject: [PATCH 23/51] Update utils.py added space after comma --- utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils.py b/utils.py index cfdc88d37..73dd63d63 100644 --- a/utils.py +++ b/utils.py @@ -194,7 +194,7 @@ def probability(p): return p > random.uniform(0.0, 1.0) -def weighted_sample_with_replacement(n,seq, weights): +def weighted_sample_with_replacement(n, seq, weights): """Pick n samples from seq at random, with replacement, with the probability of each element in proportion to its corresponding weight.""" From 2783b6a981a4cef8c7f653fe16f4a82092393e82 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 17:49:12 +0530 Subject: [PATCH 24/51] Update search.py added space after comma --- search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search.py b/search.py index c8885a9ed..94f4949d2 100644 --- a/search.py +++ b/search.py @@ -587,7 +587,7 @@ def genetic_algorithm(population, fitness_fn, ngen=1000, pmut=0.1): new_population = [] for i in range(len(population)): fitnesses = map(fitness_fn, population) - p1, p2 = weighted_sample_with_replacement(2,population, fitnesses) + p1, p2 = weighted_sample_with_replacement(2, population, fitnesses) child = p1.mate(p2) if random.uniform(0, 1) < pmut: child.mutate() From 99cbbaf72c3be44c84ed5e0b4a5958934bbb55e6 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 17:49:35 +0530 Subject: [PATCH 25/51] Update probability.py added space after comma --- probability.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/probability.py b/probability.py index fa856c330..1d7992e6d 100644 --- a/probability.py +++ b/probability.py @@ -643,5 +643,5 @@ def particle_filtering(e, N, HMM): w[i] = float("{0:.4f}".format(w[i])) # STEP 2 - s = weighted_sample_with_replacement(N,s,w) + s = weighted_sample_with_replacement(N, s, w) return s From 620cb4182fed8b4fb4af005a69d0e8b6607deb41 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 17:50:29 +0530 Subject: [PATCH 26/51] Update learning.py added space after comma --- learning.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/learning.py b/learning.py index 4917a2cf0..2b86ff8e4 100644 --- a/learning.py +++ b/learning.py @@ -754,7 +754,7 @@ def weighted_replicate(seq, weights, n): wholes = [int(w * n) for w in weights] fractions = [(w * n) % 1 for w in weights] return (flatten([x] * nx for x, nx in zip(seq, wholes)) + - weighted_sample_with_replacement(n - sum(wholes),seq, fractions, )) + weighted_sample_with_replacement(n - sum(wholes), seq, fractions)) def flatten(seqs): return sum(seqs, []) From ab26cd8971b4eaa9cd37dc11781be9507ab62972 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sat, 18 Mar 2017 17:52:40 +0530 Subject: [PATCH 27/51] Update planning.py added double_tennis_problem --- planning.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/planning.py b/planning.py index a17677460..17028e4c6 100644 --- a/planning.py +++ b/planning.py @@ -526,3 +526,34 @@ def spare_tire_graphplan(): graphplan.graph.expand_graph() if len(graphplan.graph.levels)>=2 and graphplan.check_leveloff(): return None + +def double_tennis_problem(): + init = [expr('At(A, LeftBaseLine)'), + expr('At(B, RightNet)'), + expr('Approaching(Ball, RightBaseLine)'), + expr('Partner(A,B)'), + expr('Partner(A,B)')] + + def goal_test(kb): + required = [expr('Goal(Returned(Ball))'), expr('At(a, RightNet)'), expr('At(a, LeftNet)')] + for q in required: + if kb.ask(q) is False: + return False + return True + + ##actions + #hit + precond_pos=[expr("Approaching(Ball,loc)"), expr("At(actor,loc)")] + precond_neg=[] + effect_add=[expr("Returned(Ball)")] + effect_rem = [] + hit = Action(expr("Hit(actor,Ball)"), [precond_pos, precond_neg], [effect_add, effect_rem]) + + #go + precond_pos = [ expr("At(actor,loc)")] + precond_neg = [] + effect_add = [expr("At(actor,to)")] + effect_rem = [expr("At(actor,loc)")] + go = Action(expr("Go(actor,to)"), [precond_pos, precond_neg], [effect_add, effect_rem]) + + return PDLL(init, [hit, go], goal_test) From f69e7c1e7ab1689da33766ae856fb7f55b2ee8ad Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Sun, 19 Mar 2017 12:43:08 +0530 Subject: [PATCH 28/51] Update rl.py In the pseudocode figure 21.8, the first 'if' starts with argument 's', which is the previous state, not s1(i.e, the current state). --- rl.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rl.py b/rl.py index 5241710fe..77a04f98a 100644 --- a/rl.py +++ b/rl.py @@ -154,13 +154,13 @@ def __call__(self, percept): s1, r1 = self.update_state(percept) Q, Nsa, s, a, r = self.Q, self.Nsa, self.s, self.a, self.r alpha, gamma, terminals, actions_in_state = self.alpha, self.gamma, self.terminals, self.actions_in_state - if s1 in terminals: - Q[s1, None] = r1 + if s in terminals: + Q[s, None] = r1 if s is not None: Nsa[s, a] += 1 Q[s, a] += alpha(Nsa[s, a]) * (r + gamma * max(Q[s1, a1] for a1 in actions_in_state(s1)) - Q[s, a]) - if s1 in terminals: + if s in terminals: self.s = self.a = self.r = None else: self.s, self.r = s1, r1 From fce259abe690e0fd7380b1490c3502dfefacf440 Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Sun, 19 Mar 2017 15:05:45 +0530 Subject: [PATCH 29/51] Update search.py the 'uniform_cost_search' in notebook 'search-4e.ipynb' resembles more to the pseudocode in book. --- search.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/search.py b/search.py index 94f4949d2..416855008 100644 --- a/search.py +++ b/search.py @@ -268,9 +268,22 @@ def best_first_graph_search(problem, f): return None -def uniform_cost_search(problem): - "[Figure 3.14]" - return best_first_graph_search(problem, lambda node: node.path_cost) +def uniform_cost_search(problem, costfn=lambda node: node.path_cost): + """[Figure 3.14]""" + frontier = FrontierPQ(Node(problem.initial), costfn) + explored = set() + while frontier: + node = frontier.pop() + if problem.is_goal(node.state): + return node + explored.add(node.state) + for action in problem.actions(node.state): + child = node.child(problem, action) + if child.state not in explored and child not in frontier: + frontier.add(child) + elif child in frontier and frontier.cost[child] < child.path_cost: + frontier.replace(child) + return None def depth_limited_search(problem, limit=50): From 6b82783aebe359b43e11119f942b1ff3ecb38f79 Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Sun, 19 Mar 2017 15:17:16 +0530 Subject: [PATCH 30/51] Update search.py --- search.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/search.py b/search.py index 416855008..342daf13a 100644 --- a/search.py +++ b/search.py @@ -268,9 +268,10 @@ def best_first_graph_search(problem, f): return None -def uniform_cost_search(problem, costfn=lambda node: node.path_cost): - """[Figure 3.14]""" - frontier = FrontierPQ(Node(problem.initial), costfn) +def uniform_cost_search(problem, costfn = lambda node: node.path_cost): + "[Figure 3.14]" + node = Node(problem.initial) + frontier = PriorityQueue(node, costfn) explored = set() while frontier: node = frontier.pop() From 5e628be627aaec90265c66b6c95120532033ecf9 Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Sun, 19 Mar 2017 15:24:37 +0530 Subject: [PATCH 31/51] Update search.py --- search.py | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/search.py b/search.py index 342daf13a..44d6961be 100644 --- a/search.py +++ b/search.py @@ -268,23 +268,9 @@ def best_first_graph_search(problem, f): return None -def uniform_cost_search(problem, costfn = lambda node: node.path_cost): +def uniform_cost_search(problem): "[Figure 3.14]" - node = Node(problem.initial) - frontier = PriorityQueue(node, costfn) - explored = set() - while frontier: - node = frontier.pop() - if problem.is_goal(node.state): - return node - explored.add(node.state) - for action in problem.actions(node.state): - child = node.child(problem, action) - if child.state not in explored and child not in frontier: - frontier.add(child) - elif child in frontier and frontier.cost[child] < child.path_cost: - frontier.replace(child) - return None +return best_first_graph_search(problem, lambda node: node.path_cost) def depth_limited_search(problem, limit=50): From 86f10d5eefacc6d8261a16fe144927b5fb6d3194 Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Sun, 19 Mar 2017 15:28:04 +0530 Subject: [PATCH 32/51] Update search.py --- search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search.py b/search.py index 44d6961be..94f4949d2 100644 --- a/search.py +++ b/search.py @@ -270,7 +270,7 @@ def best_first_graph_search(problem, f): def uniform_cost_search(problem): "[Figure 3.14]" -return best_first_graph_search(problem, lambda node: node.path_cost) + return best_first_graph_search(problem, lambda node: node.path_cost) def depth_limited_search(problem, limit=50): From 1bd46b96024f492afbb9f99c61684ad084de687b Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Thu, 23 Mar 2017 17:26:36 +0530 Subject: [PATCH 33/51] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 08e5e23fd..d1e972197 100644 --- a/README.md +++ b/README.md @@ -76,16 +76,16 @@ Here is a table of algorithms, the figure, name of the code in the book and in t | 9.3 | FOL-FC-Ask | `fol_fc_ask` | [`logic.py`][logic] | | 9.6 | FOL-BC-Ask | `fol_bc_ask` | [`logic.py`][logic] | | 9.8 | Append | | | -| 10.1 | Air-Cargo-problem | | -| 10.2 | Spare-Tire-Problem | | -| 10.3 | Three-Block-Tower | | -| 10.7 | Cake-Problem | | +| 10.1 | Air-Cargo-problem |air_cargo |[planning.py][planning]| +| 10.2 | Spare-Tire-Problem | spare_tire |[planning.py][planning]| +| 10.3 | Three-Block-Tower | three_block_tower |[planning.py][planning]| +| 10.7 | Cake-Problem | have_cake_and_eat_cake_too |[planning.py][planning]| | 10.9 | Graphplan | | | 10.13 | Partial-Order-Planner | | | 11.1 | Job-Shop-Problem-With-Resources | | | 11.5 | Hierarchical-Search | | | 11.8 | Angelic-Search | | -| 11.10 | Doubles-tennis | | +| 11.10 | Doubles-tennis | double_tennis_problem |[planning.py][planning]| | 13 | Discrete Probability Distribution | `ProbDist` | [`probability.py`][probability] | | 13.1 | DT-Agent | `DTAgent` | [`probability.py`][probability] | | 14.9 | Enumeration-Ask | `enumeration_ask` | [`probability.py`][probability] | From 6e3fb8eaed5d0d1d8619b429e58fbb57a2833c6e Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Thu, 23 Mar 2017 17:28:56 +0530 Subject: [PATCH 34/51] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d1e972197..7001c3b95 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Here is a table of algorithms, the figure, name of the code in the book and in t | 10.2 | Spare-Tire-Problem | spare_tire |[planning.py][planning]| | 10.3 | Three-Block-Tower | three_block_tower |[planning.py][planning]| | 10.7 | Cake-Problem | have_cake_and_eat_cake_too |[planning.py][planning]| -| 10.9 | Graphplan | | +| 10.9 | Graphplan | GraphPlan |[planning.py][planning]| | 10.13 | Partial-Order-Planner | | | 11.1 | Job-Shop-Problem-With-Resources | | | 11.5 | Hierarchical-Search | | From 3f3ef6dc47233ccede6fa309a715cbd65e9b6104 Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Thu, 23 Mar 2017 17:30:29 +0530 Subject: [PATCH 35/51] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7001c3b95..7cb796b02 100644 --- a/README.md +++ b/README.md @@ -76,16 +76,16 @@ Here is a table of algorithms, the figure, name of the code in the book and in t | 9.3 | FOL-FC-Ask | `fol_fc_ask` | [`logic.py`][logic] | | 9.6 | FOL-BC-Ask | `fol_bc_ask` | [`logic.py`][logic] | | 9.8 | Append | | | -| 10.1 | Air-Cargo-problem |air_cargo |[planning.py][planning]| -| 10.2 | Spare-Tire-Problem | spare_tire |[planning.py][planning]| -| 10.3 | Three-Block-Tower | three_block_tower |[planning.py][planning]| -| 10.7 | Cake-Problem | have_cake_and_eat_cake_too |[planning.py][planning]| -| 10.9 | Graphplan | GraphPlan |[planning.py][planning]| +| 10.1 | Air-Cargo-problem |`air_cargo` |[`planning.py`][planning]| +| 10.2 | Spare-Tire-Problem | `spare_tire` |[`planning.py`][planning]| +| 10.3 | Three-Block-Tower | `three_block_tower` |[`planning.py`][planning]| +| 10.7 | Cake-Problem | `have_cake_and_eat_cake_too` |[`planning.py`][planning]| +| 10.9 | Graphplan | `GraphPlan` |[`planning.py`][planning]| | 10.13 | Partial-Order-Planner | | | 11.1 | Job-Shop-Problem-With-Resources | | | 11.5 | Hierarchical-Search | | | 11.8 | Angelic-Search | | -| 11.10 | Doubles-tennis | double_tennis_problem |[planning.py][planning]| +| 11.10 | Doubles-tennis | `double_tennis_problem` |[`planning.py`][planning]| | 13 | Discrete Probability Distribution | `ProbDist` | [`probability.py`][probability] | | 13.1 | DT-Agent | `DTAgent` | [`probability.py`][probability] | | 14.9 | Enumeration-Ask | `enumeration_ask` | [`probability.py`][probability] | From 8f0899a0dcf1c367456a7b2e68ed9ade10654156 Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Thu, 23 Mar 2017 19:05:46 +0530 Subject: [PATCH 36/51] Update planning.py --- planning.py | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/planning.py b/planning.py index e31b82f13..6f436fdb8 100644 --- a/planning.py +++ b/planning.py @@ -237,36 +237,6 @@ def goal_test(kb): return PDLL(init, [eat_cake, bake_cake], goal_test) -def double_tennis_problem(): - init = [expr('At(A, LeftBaseLine)'), - expr('At(B, RightNet)'), - expr('Approaching(Ball, RightBaseLine)'), - expr('Partner(A,B)'), - expr('Partner(A,B)')] - - def goal_test(kb): - required = [expr('Goal(Returned(Ball))'), expr('At(a, RightNet)'), expr('At(a, LeftNet)')] - for q in required: - if kb.ask(q) is False: - return False - return True - - ##actions - #hit - precond_pos=[expr("Approaching(Ball,loc)"), expr("At(actor,loc)")] - precond_neg=[] - effect_add=[expr("Returned(Ball)")] - effect_rem = [] - hit = Action(expr("Hit(actor,Ball)"), [precond_pos, precond_neg], [effect_add, effect_rem]) - - #go - precond_pos = [ expr("At(actor,loc)")] - precond_neg = [] - effect_add = [expr("At(actor,to)")] - effect_rem = [expr("At(actor,loc)")] - go = Action(expr("Go(actor,to)"), [precond_pos, precond_neg], [effect_add, effect_rem]) - - return PDLL(init, [hit, go], goal_test) class Level(): """ From 0ed9512ba03d0732bd9e39d60ce4cd01871e7632 Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Thu, 23 Mar 2017 19:32:05 +0530 Subject: [PATCH 37/51] Update planning.py added spaces after comma --- planning.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/planning.py b/planning.py index 6f436fdb8..90e4151bc 100644 --- a/planning.py +++ b/planning.py @@ -532,8 +532,8 @@ def double_tennis_problem(): init = [expr('At(A, LeftBaseLine)'), expr('At(B, RightNet)'), expr('Approaching(Ball, RightBaseLine)'), - expr('Partner(A,B)'), - expr('Partner(A,B)')] + expr('Partner(A, B)'), + expr('Partner(B, A)')] def goal_test(kb): required = [expr('Goal(Returned(Ball))'), expr('At(a, RightNet)'), expr('At(a, LeftNet)')] @@ -544,17 +544,17 @@ def goal_test(kb): ##actions #hit - precond_pos=[expr("Approaching(Ball,loc)"), expr("At(actor,loc)")] + precond_pos=[expr("Approaching(Ball, loc)"), expr("At(actor, loc)")] precond_neg=[] effect_add=[expr("Returned(Ball)")] effect_rem = [] - hit = Action(expr("Hit(actor,Ball)"), [precond_pos, precond_neg], [effect_add, effect_rem]) + hit = Action(expr("Hit(actor, Ball)"), [precond_pos, precond_neg], [effect_add, effect_rem]) #go - precond_pos = [ expr("At(actor,loc)")] + precond_pos = [ expr("At(actor, loc)")] precond_neg = [] - effect_add = [expr("At(actor,to)")] - effect_rem = [expr("At(actor,loc)")] - go = Action(expr("Go(actor,to)"), [precond_pos, precond_neg], [effect_add, effect_rem]) + effect_add = [expr("At(actor, to)")] + effect_rem = [expr("At(actor, loc)")] + go = Action(expr("Go(actor, to)"), [precond_pos, precond_neg], [effect_add, effect_rem]) return PDLL(init, [hit, go], goal_test) From 8845d4ba647a5af7eebb24847305d7f9ea057d15 Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Thu, 23 Mar 2017 19:36:00 +0530 Subject: [PATCH 38/51] Update planning.py --- planning.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planning.py b/planning.py index 90e4151bc..47eae77da 100644 --- a/planning.py +++ b/planning.py @@ -551,7 +551,7 @@ def goal_test(kb): hit = Action(expr("Hit(actor, Ball)"), [precond_pos, precond_neg], [effect_add, effect_rem]) #go - precond_pos = [ expr("At(actor, loc)")] + precond_pos = [expr("At(actor, loc)")] precond_neg = [] effect_add = [expr("At(actor, to)")] effect_rem = [expr("At(actor, loc)")] From da4733f135d204fd9f5d9310576e0474e289766e Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Thu, 23 Mar 2017 19:52:52 +0530 Subject: [PATCH 39/51] Update test_planning.py added double_tennis_problem test --- tests/test_planning.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/test_planning.py b/tests/test_planning.py index 461cdcdbb..6b01c7ca6 100644 --- a/tests/test_planning.py +++ b/tests/test_planning.py @@ -81,3 +81,16 @@ def test_graph_call(): graph() assert levels_size == len(graph.levels) - 1 + + + + +def test_double_tennis_problem(): + p = double_tennis_problem() + assert p.goal_test() is False + solution = [expr("Go(A, RightBaseLine)"), expr("Hit(A, Ball)")] + + for action in solution: + p.act(action) + + assert p.goal_test() From 32cd0e69a24bea3d22409f8912f24ff060e1c307 Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Thu, 23 Mar 2017 19:53:43 +0530 Subject: [PATCH 40/51] Update test_planning.py --- tests/test_planning.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_planning.py b/tests/test_planning.py index 6b01c7ca6..ab6383cf7 100644 --- a/tests/test_planning.py +++ b/tests/test_planning.py @@ -83,12 +83,10 @@ def test_graph_call(): assert levels_size == len(graph.levels) - 1 - - def test_double_tennis_problem(): p = double_tennis_problem() assert p.goal_test() is False - solution = [expr("Go(A, RightBaseLine)"), expr("Hit(A, Ball)")] + solution = [expr('Go(A, RightBaseLine)'), expr('Hit(A, Ball)')] for action in solution: p.act(action) From 7afe3522c2869c8682d4f2386a23c4e831a8c0df Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Sat, 25 Mar 2017 10:39:55 +0530 Subject: [PATCH 41/51] Update logic.py added fol_fc_ask from fig 9.3 --- logic.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/logic.py b/logic.py index 9054cdfc7..6ba95850b 100644 --- a/logic.py +++ b/logic.py @@ -842,7 +842,22 @@ def subst(s, x): def fol_fc_ask(KB, alpha): - raise NotImplementedError + """A simple forward-chaining algorithm. [Figure 9.3]""" + while new is not None: + new = [] + for rule in KB: + p, q = parse_definite_clause(standardize_variables(rule)) + for p_ in random.KB.clauses: + if p != p_: + for theta in (subst(theta, p) == subst(theta, p_)): + q_ = subst(theta, q) + if not unify(q_,KB.sentence in KB) or not unify(q_, new): + new.append(q_) + phi = unify(q_,alpha) + if phi is not None: + return phi + KB.tell(new) + return None def standardize_variables(sentence, dic=None): @@ -875,7 +890,8 @@ class FolKB(KB): >>> kb0.retract(expr('Rabbit(Pete)')) >>> kb0.ask(expr('Hates(Mac, x)'))[x] Flopsie - >>> kb0.ask(expr('Wife(Pete, x)')) + >>> kb0.ask(expr('Wife(Pete, x)'))"""A simple backward-chaining algorithm for first-order logic. [Figure 9.6] + KB should be an instance of FolKB, and query an atomic sentence.""" False """ From 00d29b49d0b8f39f7a3d54636863abb523a6e02f Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Sat, 25 Mar 2017 10:45:52 +0530 Subject: [PATCH 42/51] Update logic.py --- logic.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/logic.py b/logic.py index 6ba95850b..bd9c92334 100644 --- a/logic.py +++ b/logic.py @@ -890,8 +890,7 @@ class FolKB(KB): >>> kb0.retract(expr('Rabbit(Pete)')) >>> kb0.ask(expr('Hates(Mac, x)'))[x] Flopsie - >>> kb0.ask(expr('Wife(Pete, x)'))"""A simple backward-chaining algorithm for first-order logic. [Figure 9.6] - KB should be an instance of FolKB, and query an atomic sentence.""" + >>> kb0.ask(expr('Wife(Pete, x)')) False """ From b5b1b9170865b6689d1c205b77a6ad79af6bff51 Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Sat, 25 Mar 2017 10:47:42 +0530 Subject: [PATCH 43/51] Update test_planning.py --- tests/test_planning.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/test_planning.py b/tests/test_planning.py index ab6383cf7..461cdcdbb 100644 --- a/tests/test_planning.py +++ b/tests/test_planning.py @@ -81,14 +81,3 @@ def test_graph_call(): graph() assert levels_size == len(graph.levels) - 1 - - -def test_double_tennis_problem(): - p = double_tennis_problem() - assert p.goal_test() is False - solution = [expr('Go(A, RightBaseLine)'), expr('Hit(A, Ball)')] - - for action in solution: - p.act(action) - - assert p.goal_test() From aad19c832d89115bb5fa8827227f657c2eeeb760 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sun, 26 Mar 2017 12:12:04 +0530 Subject: [PATCH 44/51] Merge remote-tracking branch 'origin/master' # Conflicts: # planning.py --- logic.ipynb | 328 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 322 insertions(+), 6 deletions(-) diff --git a/logic.ipynb b/logic.ipynb index 079f1170b..2c963462f 100644 --- a/logic.ipynb +++ b/logic.ipynb @@ -22,7 +22,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 11, "metadata": { "collapsed": true }, @@ -306,11 +306,11 @@ "|--------------------------|----------------------|-------------------------|---|---|\n", "| Negation | ¬ P | `~P` | `~P` | `Expr('~', P)`\n", "| And | P ∧ Q | `P & Q` | `P & Q` | `Expr('&', P, Q)`\n", - "| Or | P ∨ Q | `P` | `Q`| `P` | `Q` | `Expr('`|`', P, Q)`\n", + "| Or | P ∨ Q | `P` | `Q`| `P` | `Q` | `Expr('`|`', P, Q)\n", "| Inequality (Xor) | P ≠ Q | `P ^ Q` | `P ^ Q` | `Expr('^', P, Q)`\n", "| Implication | P → Q | `P` |`'==>'`| `Q` | `P ==> Q` | `Expr('==>', P, Q)`\n", "| Reverse Implication | Q ← P | `Q` |`'<=='`| `P` |`Q <== P` | `Expr('<==', Q, P)`\n", - "| Equivalence | P ↔ Q | `P` |`'<=>'`| `Q` |`P <=> Q` | `Expr('<=>', P, Q)`\n", + "| Equivalence | P ↔ Q | `P` |`'<=>'`| `Q` |`P ==> Q` | `Expr('==>', P, Q)`\n", "\n", "Here's an example of defining a sentence with an implication arrow:" ] @@ -412,6 +412,7 @@ "\n", "The class `PropKB` can be used to represent a knowledge base of propositional logic sentences.\n", "\n", + "\n", "We see that the class `KB` has four methods, apart from `__init__`. A point to note here: the `ask` method simply calls the `ask_generator` method. Thus, this one has already been implemented and what you'll have to actually implement when you create your own knowledge base class (if you want to, though I doubt you'll ever need to; just use the ones we've created for you), will be the `ask_generator` function and not the `ask` function itself.\n", "\n", "The class `PropKB` now.\n", @@ -421,6 +422,321 @@ "* `retract(self, sentence)` : This function removes all the clauses of the sentence given, from the knowledge base. Like the `tell` function, you don't have to pass clauses to remove them from the knowledge base; any sentence will do fine. The function will take care of converting that sentence to clauses and then remove those." ] }, + { + "cell_type": "heading", + "metadata": {}, + "level": 6, + "source": [ + "The following gives an idea how the python code works in logic.py:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "KB = PropKB()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "creates an empty knowledge base" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "KB.tell(A & C)\n", + "KB.ask(A) == KB.ask(C) == {}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "adds sentence and checks if KB entails the query." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "KB.ask(E)" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{}" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "kb.tell(E)\n", + "kb.ask(E)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "KB.retract(C)\n", + "KB.ask(C)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "removes all clauses of 'C' from the sentence." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The truth table enumeration algorithm from Figure 7.10 codes as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "def tt_entails(kb, alpha):\n", + " \n", + " assert not variables(alpha)\n", + " return tt_check_all(kb, alpha, prop_symbols(kb & alpha), {})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Example:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tt_entails(expr('P & Q'), expr('Q'))" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tt_check_all(expr('P & Q'), expr('Q'), prop_symbols(expr('Q')), {})" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{B: True, A: True}\n{Q: True}\n" + ] + } + ], + "source": [ + "print (dpll_satisfiable(expr('A & B')))\n", + "print (dpll_satisfiable(expr('P | Q')))" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{x: 2}\n" + ] + } + ], + "source": [ + "print(unify(x, 2, {}))" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{B: True, C: True, A: True}" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "WalkSAT([A & B, A & C], 0.5, 100 )" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['Left', 'Left']" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "transition = {'A': {'Left': 'A', 'Right': 'B'},\n", + " 'B': {'Left': 'A', 'Right': 'C'},\n", + " 'C': {'Left': 'B', 'Right': 'C'}}\n", + "\n", + "SAT_plan('C', transition, 'A', 3)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fol_bc_ask(expr('P & Q'), expr('Q'))" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'Expr' object has no attribute 'clauses'", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mpl_fc_entails\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'P & Q'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mexpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Q'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m/home/ubuntu/PycharmProjects/GSOC_17/sofmonk/aima-python/logic.py\u001b[0m in \u001b[0;36mpl_fc_entails\u001b[0;34m(KB, q)\u001b[0m\n\u001b[1;32m 498\u001b[0m \"\"\"\n\u001b[1;32m 499\u001b[0m count = {c: len(conjuncts(c.args[0]))\n\u001b[0;32m--> 500\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mc\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mKB\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclauses\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 501\u001b[0m if c.op == '==>'}\n\u001b[1;32m 502\u001b[0m \u001b[0minferred\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdefaultdict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbool\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mAttributeError\u001b[0m: 'Expr' object has no attribute 'clauses'" + ], + "output_type": "error" + } + ], + "source": [ + "pl_fc_entails(expr('P & Q'), expr('Q'))" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -701,16 +1017,16 @@ "language_info": { "codemirror_mode": { "name": "ipython", - "version": 3 + "version": 3.0 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.4.3" + "version": "3.5.1" } }, "nbformat": 4, "nbformat_minor": 0 -} +} \ No newline at end of file From 57215282d96be54fe3d7f2a1acddd2fb9a2404cc Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sun, 26 Mar 2017 12:18:54 +0530 Subject: [PATCH 45/51] Merge remote-tracking branch 'origin/master' # Conflicts: # planning.py --- logic.ipynb | 58 +++++++++++------------------------------------------ 1 file changed, 12 insertions(+), 46 deletions(-) diff --git a/logic.ipynb b/logic.ipynb index 2c963462f..b9bd5142d 100644 --- a/logic.ipynb +++ b/logic.ipynb @@ -22,11 +22,20 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 1, "metadata": { "collapsed": true }, - "outputs": [], + "outputs": [ + { + "ename": "IndentationError", + "evalue": "unindent does not match any outer indentation level (logic.py, line 844)", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m\"/home/ubuntu/PycharmProjects/GSOC_17/sofmonk/aima-python/logic.py\"\u001b[0;36m, line \u001b[0;32m844\u001b[0m\n\u001b[0;31m def fol_fc_ask(KB, alpha):\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m unindent does not match any outer indentation level\n" + ], + "output_type": "error" + } + ], "source": [ "from utils import *\n", "from logic import *" @@ -423,9 +432,8 @@ ] }, { - "cell_type": "heading", + "cell_type": "markdown", "metadata": {}, - "level": 6, "source": [ "The following gives an idea how the python code works in logic.py:" ] @@ -695,48 +703,6 @@ "SAT_plan('C', transition, 'A', 3)" ] }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "fol_bc_ask(expr('P & Q'), expr('Q'))" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "metadata": {}, - "outputs": [ - { - "ename": "AttributeError", - "evalue": "'Expr' object has no attribute 'clauses'", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mpl_fc_entails\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'P & Q'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mexpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Q'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m/home/ubuntu/PycharmProjects/GSOC_17/sofmonk/aima-python/logic.py\u001b[0m in \u001b[0;36mpl_fc_entails\u001b[0;34m(KB, q)\u001b[0m\n\u001b[1;32m 498\u001b[0m \"\"\"\n\u001b[1;32m 499\u001b[0m count = {c: len(conjuncts(c.args[0]))\n\u001b[0;32m--> 500\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mc\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mKB\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclauses\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 501\u001b[0m if c.op == '==>'}\n\u001b[1;32m 502\u001b[0m \u001b[0minferred\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdefaultdict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbool\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mAttributeError\u001b[0m: 'Expr' object has no attribute 'clauses'" - ], - "output_type": "error" - } - ], - "source": [ - "pl_fc_entails(expr('P & Q'), expr('Q'))" - ] - }, { "cell_type": "markdown", "metadata": {}, From ae9174e86218ccf2b88ad388e0ef9bee275b9ef0 Mon Sep 17 00:00:00 2001 From: sofmonk Date: Sun, 26 Mar 2017 12:48:26 +0530 Subject: [PATCH 46/51] Merge remote-tracking branch 'origin/master' # Conflicts: # planning.py --- logic.ipynb | 210 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 128 insertions(+), 82 deletions(-) diff --git a/logic.ipynb b/logic.ipynb index b9bd5142d..de9365428 100644 --- a/logic.ipynb +++ b/logic.ipynb @@ -26,16 +26,7 @@ "metadata": { "collapsed": true }, - "outputs": [ - { - "ename": "IndentationError", - "evalue": "unindent does not match any outer indentation level (logic.py, line 844)", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"/home/ubuntu/PycharmProjects/GSOC_17/sofmonk/aima-python/logic.py\"\u001b[0;36m, line \u001b[0;32m844\u001b[0m\n\u001b[0;31m def fol_fc_ask(KB, alpha):\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m unindent does not match any outer indentation level\n" - ], - "output_type": "error" - } - ], + "outputs": [], "source": [ "from utils import *\n", "from logic import *" @@ -330,18 +321,7 @@ "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "(~(P & Q) ==> (~P | ~Q))" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "~(P & Q) |'==>'| (~P | ~Q)" ] @@ -440,7 +420,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -456,7 +436,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -465,7 +445,7 @@ "True" ] }, - "execution_count": 14, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -491,7 +471,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -500,7 +480,7 @@ "False" ] }, - "execution_count": 15, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -511,7 +491,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -520,19 +500,19 @@ "{}" ] }, - "execution_count": 42, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "kb.tell(E)\n", - "kb.ask(E)" + "KB.tell(E)\n", + "KB.ask(E)" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -541,7 +521,7 @@ "False" ] }, - "execution_count": 16, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -562,12 +542,15 @@ "cell_type": "markdown", "metadata": {}, "source": [ + "\n", + "\n", + "\n", "The truth table enumeration algorithm from Figure 7.10 codes as follows:" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -586,7 +569,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -595,7 +578,7 @@ "True" ] }, - "execution_count": 7, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -604,9 +587,16 @@ "tt_entails(expr('P & Q'), expr('Q'))" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The tt_entail algorithm makes use of the tt_check_all() function, which gives results in the following manner." + ] + }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 22, "metadata": {}, "outputs": [ { @@ -615,7 +605,7 @@ "True" ] }, - "execution_count": 27, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -624,53 +614,62 @@ "tt_check_all(expr('P & Q'), expr('Q'), prop_symbols(expr('Q')), {})" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "prop_symbols() is used to give the function argument in the form of symbols." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Example of the DPLL algorithm from Figure 7.17." + ] + }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "{B: True, A: True}\n{Q: True}\n" + "{A: True, B: True}\n{Q: True}\n{Q: False}\n{Q: True}\n" ] } ], "source": [ "print (dpll_satisfiable(expr('A & B')))\n", - "print (dpll_satisfiable(expr('P | Q')))" + "\n", + "print (dpll_satisfiable(expr('P | Q')))\n", + "\n", + "print (dpll_satisfiable(expr('P | ~Q')))\n", + "\n", + "print (dpll_satisfiable(expr('~P | Q')))" ] }, { - "cell_type": "code", - "execution_count": 41, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{x: 2}\n" - ] - } - ], "source": [ - "print(unify(x, 2, {}))" + "Example of the WalkSAT algorithm from Figure 7.18." ] }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{B: True, C: True, A: True}" + "{C: True, A: True, B: True}" ] }, - "execution_count": 46, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -679,9 +678,16 @@ "WalkSAT([A & B, A & C], 0.5, 100 )" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Example of the SATplan algorithm from Figure 7.22." + ] + }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 25, "metadata": {}, "outputs": [ { @@ -690,7 +696,7 @@ "['Left', 'Left']" ] }, - "execution_count": 47, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -703,6 +709,30 @@ "SAT_plan('C', transition, 'A', 3)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The unify() algorithm from Figure 9.1 returns a substitution to make the first 2 arguments identical, and the third argument is the substitution built up so far." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{x: 2}\n" + ] + } + ], + "source": [ + "print(unify(x, 2, {}))" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -723,7 +753,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": { "collapsed": false }, @@ -734,7 +764,7 @@ "(P ==> ~Q)" ] }, - "execution_count": 15, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -752,7 +782,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": { "collapsed": false }, @@ -763,7 +793,7 @@ "(P ==> ~Q)" ] }, - "execution_count": 16, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -781,7 +811,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": { "collapsed": false }, @@ -792,7 +822,7 @@ "PartialExpr('==>', P)" ] }, - "execution_count": 17, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -812,7 +842,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": { "collapsed": false }, @@ -823,7 +853,7 @@ "(P ==> ~Q)" ] }, - "execution_count": 18, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -853,22 +883,11 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "(~(P & Q) ==> (~P | ~Q))" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "expr('~(P & Q) ==> (~P | ~Q)')" ] @@ -882,7 +901,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "metadata": { "collapsed": false }, @@ -912,7 +931,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "metadata": { "collapsed": false }, @@ -941,7 +960,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": null, "metadata": { "collapsed": false }, @@ -961,6 +980,33 @@ "(P & Q) |'==>'| (P | Q)" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "" + ] + }, { "cell_type": "markdown", "metadata": { From 90b48eb77ceb88083129ba9e9d1082f40a80cf33 Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Sun, 26 Mar 2017 12:55:32 +0530 Subject: [PATCH 47/51] Update logic.ipynb --- logic.ipynb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/logic.ipynb b/logic.ipynb index de9365428..7bef657d5 100644 --- a/logic.ipynb +++ b/logic.ipynb @@ -545,7 +545,7 @@ "\n", "\n", "\n", - "The truth table enumeration algorithm from Figure 7.10 codes as follows:" + "# The truth table enumeration algorithm from Figure 7.10 codes as follows:" ] }, { @@ -625,7 +625,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Example of the DPLL algorithm from Figure 7.17." + "# Example of the DPLL algorithm from Figure 7.17." ] }, { @@ -655,7 +655,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Example of the WalkSAT algorithm from Figure 7.18." + "# Example of the WalkSAT algorithm from Figure 7.18." ] }, { @@ -682,7 +682,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Example of the SATplan algorithm from Figure 7.22." + "# Example of the SATplan algorithm from Figure 7.22." ] }, { @@ -713,7 +713,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The unify() algorithm from Figure 9.1 returns a substitution to make the first 2 arguments identical, and the third argument is the substitution built up so far." + "# The unify() algorithm from Figure 9.1 returns a substitution to make the first 2 arguments identical, and the third argument is the substitution built up so far." ] }, { @@ -1041,4 +1041,4 @@ }, "nbformat": 4, "nbformat_minor": 0 -} \ No newline at end of file +} From fa8b0aeb8db512147239b405e072191a5a492115 Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Sun, 26 Mar 2017 12:58:54 +0530 Subject: [PATCH 48/51] Update logic.ipynb --- logic.ipynb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/logic.ipynb b/logic.ipynb index 7bef657d5..f017a15ac 100644 --- a/logic.ipynb +++ b/logic.ipynb @@ -713,7 +713,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# The unify() algorithm from Figure 9.1 returns a substitution to make the first 2 arguments identical, and the third argument is the substitution built up so far." + "# The unify() algorithm from Figure 9.1 \n", + "\n","Returns a substitution to make the first 2 arguments identical, and the third argument is the substitution built up so far." ] }, { From daaf906240a116149efa28a424e0e314e91c562a Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Sun, 26 Mar 2017 13:23:11 +0530 Subject: [PATCH 49/51] Update planning.py --- planning.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/planning.py b/planning.py index e011cf677..866911afd 100644 --- a/planning.py +++ b/planning.py @@ -551,7 +551,7 @@ def double_tennis_problem(): expr('Partner(B, A)')] def goal_test(kb): - required = [expr('Goal(Returned(Ball))'), expr('At(a, RightNet)'), expr('At(a, LeftNet)')] + required = [expr('Goal(Returned(Ball))'), expr('At(a, RightNet)')] or [expr('Goal(Returned(Ball))'), expr('At(a, LeftNet)')] for q in required: if kb.ask(q) is False: return False @@ -573,4 +573,4 @@ def goal_test(kb): effect_rem = [expr("At(actor, loc)")] go = Action(expr("Go(actor, to)"), [precond_pos, precond_neg], [effect_add, effect_rem]) - return PDLL(init, [hit, go], goal_test) \ No newline at end of file + return PDLL(init, [hit, go], goal_test) From 9bd5c7d281630fbebcf9a2e422b849b470321e8b Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Sun, 26 Mar 2017 18:11:44 +0530 Subject: [PATCH 50/51] Add files via upload added blocks_world.png --- images/blocks_world.png | Bin 0 -> 57044 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/blocks_world.png diff --git a/images/blocks_world.png b/images/blocks_world.png new file mode 100644 index 0000000000000000000000000000000000000000..cc772ae3692e5ea8618012a7eb78adaac1d4141e GIT binary patch literal 57044 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 literal 0 HcmV?d00001 From 5b9167cfe7e08966dbf0283c1d9460006dc83522 Mon Sep 17 00:00:00 2001 From: Angira Sharma Date: Sun, 26 Mar 2017 18:17:30 +0530 Subject: [PATCH 51/51] Delete planning.ipynb --- planning.ipynb | 45 --------------------------------------------- 1 file changed, 45 deletions(-) delete mode 100644 planning.ipynb diff --git a/planning.ipynb b/planning.ipynb deleted file mode 100644 index d5a5eb25d..000000000 --- a/planning.ipynb +++ /dev/null @@ -1,45 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "import planning" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.5.1" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy