@@ -690,16 +690,321 @@ def sat_count(sym):
690
690
# ______________________________________________________________________________
691
691
692
692
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
+
693
896
class HybridWumpusAgent (agents .Agent ):
694
897
"""An agent for the wumpus world that does logical inference. [Figure 7.20]"""
695
898
696
899
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
698
998
699
999
700
1000
def plan_route (current , goals , allowed ):
701
1001
raise NotImplementedError
702
1002
1003
+
1004
+ def plan_shot (current , goals , allowed ):
1005
+ raise NotImplementedError
1006
+
1007
+
703
1008
# ______________________________________________________________________________
704
1009
705
1010
0 commit comments