Skip to content

Commit 49adcdb

Browse files
kunwar31norvig
authored andcommitted
Implemented HybridWumpusAgent (#842)
* Added WumpusKB for use in HybridWumpusAgent * Implemented HybridWumpusAgent added WumpusPosition helping class.
1 parent e245a64 commit 49adcdb

File tree

1 file changed

+306
-1
lines changed

1 file changed

+306
-1
lines changed

logic.py

Lines changed: 306 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,16 +690,321 @@ def sat_count(sym):
690690
# ______________________________________________________________________________
691691

692692

693+
class WumpusKB(PropKB):
694+
"""
695+
Create a Knowledge Base that contains the atemporal "Wumpus physics" and temporal rules with time zero.
696+
"""
697+
def __init__(self,dimrow):
698+
super().__init__()
699+
self.dimrow = dimrow
700+
self.tell('( NOT W1s1 )')
701+
self.tell('( NOT P1s1 )')
702+
for i in range(1, dimrow+1):
703+
for j in range(1, dimrow+1):
704+
bracket = 0
705+
sentence_b_str = "( B" + i + "s" + j + " <=> "
706+
sentence_s_str = "( S" + i + "s" + j + " <=> "
707+
if i > 1:
708+
sentence_b_str += "( P" + (i-1) + "s" + j + " OR "
709+
sentence_s_str += "( W" + (i-1) + "s" + j + " OR "
710+
bracket += 1
711+
712+
if i < dimRow:
713+
sentence_b_str += "( P" + (i+1) + "s" + j + " OR "
714+
sentence_s_str += "( W" + (i+1) + "s" + j + " OR "
715+
bracket += 1
716+
717+
if j > 1:
718+
if j == dimRow:
719+
sentence_b_str += "P" + i + "s" + (j-1) + " "
720+
sentence_s_str += "W "+ i + "s" + (j-1) + " "
721+
else:
722+
sentence_b_str += "( P" + i + "s" + (j-1) + " OR "
723+
sentence_s_str += "( W" + i + "s" + (j-1) + " OR "
724+
bracket += 1
725+
726+
if j < dimRow:
727+
sentence_b_str += "P" + i + "s" + (j+1) + " "
728+
sentence_s_str += "W" + i + "s" + (j+1) + " "
729+
730+
731+
for _ in range(bracket):
732+
sentence_b_str += ") "
733+
sentence_s_str += ") "
734+
735+
sentence_b_str += ") "
736+
sentence_s_str += ") "
737+
738+
self.tell(sentence_b_str)
739+
self.tell(sentence_s_str)
740+
741+
742+
## Rule that describes existence of at least one Wumpus
743+
sentence_w_str = ""
744+
for i in range(1, dimrow+1):
745+
for j in range(1, dimrow+1):
746+
if (i == dimrow) and (j == dimrow):
747+
sentence_w_str += " W" + dimRow + "s" + dimrow + " "
748+
else:
749+
sentence_w_str += "( W" + i + "s" + j + " OR "
750+
for _ in range(dimrow**2):
751+
sentence_w_str += ") "
752+
self.tell(sentence_w_str)
753+
754+
755+
## Rule that describes existence of at most one Wumpus
756+
for i in range(1, dimrow+1):
757+
for j in range(1, dimrow+1):
758+
for u in range(1, dimrow+1):
759+
for v in range(1, dimrow+1):
760+
if i!=u or j!=v:
761+
self.tell("( ( NOT W" + i + "s" + j + " ) OR ( NOT W" + u + "s" + v + " ) )")
762+
763+
## Temporal rules at time zero
764+
self.tell("L1s1s0")
765+
for i in range(1, dimrow+1):
766+
for j in range(1, dimrow + 1):
767+
self.tell("( L" + i + "s" + j + "s0 => ( Breeze0 <=> B" + i + "s" + j + " ) )")
768+
self.tell("( L" + i + "s" + j + "s0 => ( Stench0 <=> S" + i + "s" + j + " ) )")
769+
if i != 1 or j != 1:
770+
self.tell("( NOT L" + i + "s" + j + "s" + "0 )")
771+
self.tell("WumpusAlive0")
772+
self.tell("HaveArrow0")
773+
self.tell("FacingEast0")
774+
self.tell("( NOT FacingWest0 )")
775+
self.tell("( NOT FacingNorth0 )")
776+
self.tell("( NOT FacingSouth0 )")
777+
778+
779+
def make_action_sentence(self, action, time):
780+
self.tell(action + time)
781+
782+
783+
def make_percept_sentence(self, percept, time):
784+
self.tell(percept + time)
785+
786+
def add_temporal_sentences(self, time):
787+
if time == 0:
788+
return
789+
t = time - 1
790+
791+
## current location rules (L2s2s3 represent tile 2,2 at time 3)
792+
## ex.: ( L2s2s3 <=> ( ( L2s2s2 AND ( ( NOT Forward2 ) OR Bump3 ) )
793+
## OR ( ( L1s2s2 AND ( FacingEast2 AND Forward2 ) ) OR ( L2s1s2 AND ( FacingNorth2 AND Forward2 ) ) )
794+
for i in range(1, self.dimrow+1):
795+
for j in range(1, self.dimrow+1):
796+
self.tell("( L" + i + "s" + j + "s" + time + " => ( Breeze" + time + " <=> B" + i + "s" + j + " ) )")
797+
self.tell("( L" + i + "s" + j + "s" + time + " => ( Stench" + time + " <=> S" + i + "s" + j + " ) )")
798+
s = "( L" + i + "s" + j + "s" + time + " <=> ( ( L" + i + "s" + j + "s" + t + " AND ( ( NOT Forward"\
799+
+ t + " ) OR Bump" + time + " ) )"
800+
801+
count = 2
802+
if i != 1:
803+
s += " OR ( ( L" + (i - 1) + "s" + j + "s" + t + " AND ( FacingEast" + t + " AND Forward" + t\
804+
+ " ) )"
805+
count += 1
806+
if i != self.dimrow:
807+
s += " OR ( ( L" + (i + 1) + "s" + j + "s" + t + " AND ( FacingWest" + t + " AND Forward" + t\
808+
+ " ) )"
809+
count += 1
810+
if j != 1:
811+
if j == self.dimrow:
812+
s += " OR ( L" + i + "s" + (j - 1) + "s" + t + " AND ( FacingNorth" + t + " AND Forward" + t\
813+
+ " ) )"
814+
else:
815+
s += " OR ( ( L" + i + "s" + (j - 1) + "s" + t + " AND ( FacingNorth" + t + " AND Forward" \
816+
+ t + " ) )"
817+
count += 1
818+
if j != self.dimrow:
819+
s += " OR ( L" + i + "s" + (j + 1) + "s" + t + " AND ( FacingSouth" + t + " AND Forward" + t\
820+
+ " ) )"
821+
822+
for _ in range(count):
823+
s += " )"
824+
825+
## add sentence about location i,j
826+
self.tell(s)
827+
828+
## add sentence about safety of location i,j
829+
self.tell("( OK" + i + "s" + j + "s" + time + " <=> ( ( NOT P" + i + "s" + j + " ) AND ( NOT ( W" + i\
830+
+ "s" + j + " AND WumpusAlive" + time + " ) ) ) )")
831+
832+
## Rules about current orientation
833+
## ex.: ( FacingEast3 <=> ( ( FacingNorth2 AND TurnRight2 ) OR ( ( FacingSouth2 AND TurnLeft2 )
834+
## OR ( FacingEast2 AND ( ( NOT TurnRight2 ) AND ( NOT TurnLeft2 ) ) ) ) ) )
835+
a = "( FacingNorth" + t + " AND TurnRight" + t + " )"
836+
b = "( FacingSouth" + t + " AND TurnLeft" + t + " )"
837+
c = "( FacingEast" + t + " AND ( ( NOT TurnRight" + t + " ) AND ( NOT TurnLeft" + t + " ) ) )"
838+
s = "( FacingEast" + (t + 1) + " <=> ( " + a + " OR ( " + b + " OR " + c + " ) ) )"
839+
this.tell(s)
840+
841+
a = "( FacingNorth" + t + " AND TurnLeft" + t + " )"
842+
b = "( FacingSouth" + t + " AND TurnRight" + t + " )"
843+
c = "( FacingWest" + t + " AND ( ( NOT TurnRight" + t + " ) AND ( NOT TurnLeft" + t + " ) ) )"
844+
s = "( FacingWest" + (t + 1) + " <=> ( " + a + " OR ( " + b + " OR " + c + " ) ) )"
845+
this.tell(s)
846+
847+
a = "( FacingEast" + t + " AND TurnLeft" + t + " )"
848+
b = "( FacingWest" + t + " AND TurnRight" + t + " )"
849+
c = "( FacingNorth" + t + " AND ( ( NOT TurnRight" + t + " ) AND ( NOT TurnLeft" + t + " ) ) )"
850+
s = "( FacingNorth" + (t + 1) + " <=> ( " + a + " OR ( " + b + " OR " + c + " ) ) )"
851+
this.tell(s)
852+
853+
a = "( FacingWest" + t + " AND TurnLeft" + t + " )"
854+
b = "( FacingEast" + t + " AND TurnRight" + t + " )"
855+
c = "( FacingSouth" + t + " AND ( ( NOT TurnRight" + t + " ) AND ( NOT TurnLeft" + t + " ) ) )"
856+
s = "( FacingSouth" + (t + 1) + " <=> ( " + a + " OR ( " + b + " OR " + c + " ) ) )"
857+
this.tell(s)
858+
859+
## Rules about last action
860+
self.tell("( Forward" + t + " <=> ( NOT TurnRight" + t + " ) )")
861+
self.tell("( Forward" + t + " <=> ( NOT TurnLeft" + t + " ) )")
862+
863+
##Rule about the arrow
864+
self.tell("( HaveArrow" + time + " <=> ( HaveArrow" + (time - 1) + " AND ( NOT Shot" + (time - 1) + " ) ) )")
865+
866+
##Rule about Wumpus (dead or alive)
867+
self.tell("( WumpusAlive" + time + " <=> ( WumpusAlive" + (time - 1) + " AND ( NOT Scream" + time + " ) ) )")
868+
869+
870+
# ______________________________________________________________________________
871+
872+
873+
class WumpusPosition():
874+
def __init__(self, X, Y, orientation):
875+
self.X = X
876+
self.Y = Y
877+
self.orientation = orientation
878+
879+
880+
def get_location(self):
881+
return self.X, self.Y
882+
883+
def get_orientation(self):
884+
return self.orientation
885+
886+
def equals(self, wumpus_position):
887+
if wumpus_position.get_location() == self.get_location() and \
888+
wumpus_position.get_orientation()==self.get_orientation():
889+
return True
890+
else:
891+
return False
892+
893+
# ______________________________________________________________________________
894+
895+
693896
class HybridWumpusAgent(agents.Agent):
694897
"""An agent for the wumpus world that does logical inference. [Figure 7.20]"""
695898

696899
def __init__(self):
697-
raise NotImplementedError
900+
super().__init__()
901+
self.dimrow = 3
902+
self.kb = WumpusKB(self.dimrow)
903+
self.t = 0
904+
self.plan = list()
905+
self.current_position = WumpusPosition(1, 1, 'UP')
906+
907+
908+
def execute(self, percept):
909+
self.kb.make_percept_sentence(percept, self.t)
910+
self.kb.add_temporal_sentences(self.t)
911+
912+
temp = list()
913+
914+
for i in range(1, self.dimrow+1):
915+
for j in range(1, self.dimrow+1):
916+
if self.kb.ask_with_dpll('L' + i + 's' + j + 's' + self.t):
917+
temp.append(i)
918+
temp.append(j)
919+
920+
if self.kb.ask_with_dpll('FacingNorth' + self.t):
921+
self.current_position = WumpusPosition(temp[0], temp[1], 'UP')
922+
elif self.kb.ask_with_dpll('FacingSouth' + self.t):
923+
self.current_position = WumpusPosition(temp[0], temp[1], 'DOWN')
924+
elif self.kb.ask_with_dpll('FacingWest' + self.t):
925+
self.current_position = WumpusPosition(temp[0], temp[1], 'LEFT')
926+
elif self.kb.ask_with_dpll('FacingEast' + self.t):
927+
self.current_position = WumpusPosition(temp[0], temp[1], 'RIGHT')
928+
929+
safe_points = list()
930+
for i in range(1, self.dimrow+1):
931+
for j in range(1, self.dimrow+1):
932+
if self.kb.ask_with_dpll('OK' + i + 's' + j + 's' + self.t):
933+
safe_points.append([i, j])
934+
935+
if self.kb.ask_with_dpll('Glitter' + self.t):
936+
goals = list()
937+
goals.append([1, 1])
938+
self.plan.append('Grab')
939+
actions = plan_route(self.current_position,goals,safe_points)
940+
for action in actions:
941+
self.plan.append(action)
942+
self.plan.append('Climb')
943+
944+
if len(self.plan) == 0:
945+
unvisited = list()
946+
for i in range(1, self.dimrow+1):
947+
for j in range(1, self.dimrow+1):
948+
for k in range(1, self.dimrow+1):
949+
if self.kb.ask_with_dpll("L" + i + "s" + j + "s" + k):
950+
unvisited.append([i, j])
951+
unvisited_and_safe = list()
952+
for u in unvisited:
953+
for s in safe_points:
954+
if u not in unvisited_and_safe and s == u:
955+
unvisited_and_safe.append(u)
956+
957+
temp = plan_route(self.current_position,unvisited_and_safe,safe_points)
958+
for t in temp:
959+
self.plan.append(t)
960+
961+
if len(self.plan) == 0 and self.kb.ask_with_dpll('HaveArrow' + self.t):
962+
possible_wumpus = list()
963+
for i in range(1, self.dimrow+1):
964+
for j in range(1, self.dimrow+1):
965+
if not self.kb.ask_with_dpll('W' + i + 's' + j):
966+
possible_wumpus.append([i, j])
967+
968+
temp = plan_shot(self.current_position, possible_wumpus, safe_points)
969+
for t in temp:
970+
self.plan.append(t)
971+
972+
if len(self.plan) == 0:
973+
not_unsafe = list()
974+
for i in range(1, self.dimrow+1):
975+
for j in range(1, self.dimrow+1):
976+
if not self.kb.ask_with_dpll('OK' + i + 's' + j + 's' + self.t):
977+
not_unsafe.append([i, j])
978+
temp = plan_route(self.current_position, not_unsafe, safe_points)
979+
for t in temp:
980+
self.plan.append(t)
981+
982+
if len(self.plan) == 0:
983+
start = list()
984+
start.append([1, 1])
985+
temp = plan_route(self.current_position, start, safe_points)
986+
for t in temp:
987+
self.plan.append(t)
988+
self.plan.append('Climb')
989+
990+
991+
992+
action = self.plan[1:]
993+
994+
self.kb.make_action_sentence(action, self.t)
995+
self.t += 1
996+
997+
return action
698998

699999

7001000
def plan_route(current, goals, allowed):
7011001
raise NotImplementedError
7021002

1003+
1004+
def plan_shot(current, goals, allowed):
1005+
raise NotImplementedError
1006+
1007+
7031008
# ______________________________________________________________________________
7041009

7051010

0 commit comments

Comments
 (0)