

==================================================

                    WATSON.PRO

==================================================



             player(P):-     member(P, [p1,p2,p3]).

             type(C,suspect):- member(C, [s1,s2,s3,s4,s5,s6]).
             type(C,location):- member(C, [l1,l2,l3,l4,l5,l6,l7,l8,l9]).
             type(C,weapon):- member(C, [w1,w2,w3,w4,w5,w6]).
             card(C):- type(C,suspect).
             card(C):- type(C,location).
             card(C):- type(C,weapon). 
               
             may_be_in_the_box(C):- card(C),
                                    not (owns(p1,C)), 
                                    not (owns(p2,C)), 
                                    not (owns(p3,C)), 
                                    not (( type(C,T), 
                                           type(C1,T), 
                                           not (C=C1), 
                                           is_in_the_box(C1))).
               
             is_in_the_box(C):-  owns_not(p1,C), 
                                 owns_not(p2,C), 
                                 owns_not(p3,C). 
               
             owns_not(P,C):- has_not(P,C).
             owns_not(p1,C):- not (has(p1,C)).
             owns_not(P,C):- (has_not_both(P,C,C1); 
                              has_not_both(P,C1,C) ),
                              has(P,C1),
                              asserta( has_not(P,C) ).
               
             owns(P,C):- has(P,C).
             owns(P,C):- (has_at_least_one(P,C,C1); 
                          has_at_least_one(P,C1,C) ),
                          has_not(P,C1),
                          asserta( has(P,C) ).
               
             has_at_least_one(P,C1,C2):- 
                       (has_at_least_one_of_three(P,C,C1,C2); 
                        has_at_least_one_of_three(P,C1,C,C2);
                        has_at_least_one_of_three(P,C1,C2,C)),
                        has_not(P,C).
               
             ask(C):- may_be_in_the_box(C), !.
               
             request(C1,C2,C3):- type(C1,suspect), ask(C1), 
                                 type(C2,location),ask(C2),
                                 type(C3,weapon),  ask(C3).
               
             member(X,[X|_]).
             member(X,[_|Y]):- member(X,Y).




==================================================

                    WT.LOG

==================================================


?((P "~L") (PP))
?((CRWIND "" 8 6 14 66) (CURSOR "" 0 0)
  (PP)
  (P "                     - WATSON EXPERT SYSTEM -")
  (PP) (PP)
  (P "                    based on the BYTE article ")        (PP) (PP)
  (P "                    Elementary, My Dear Watson ")            (PP)
  (P "                                by            ")            (PP) 
  (P "          J-C. EMOND  (Belgium) and A. PAULISSEN (Holland)") (PP)
  (P "                          (November 1986)")             (PP) (PP)
  (P "                For private, non-commercial use only. ") (PP)
  (PP) (PP)
  (P "                July 1986, micro-PROLOG version 1.21"))
?((CRWIND "loading system components" 0 0 6 78))
?((CURSOR "loading system components" 0 0))
?((P " loading WATSON knowledge base       <KB.MIC>") (PP) (LOAD "KB.MIC"))
?((P " loading WATSON user interface       <UI.MIC>") (PP) (LOAD "UI.MIC"))
?((P " loading WATSON justification engine <JE.MIC>") (PP) (LOAD "JE.MIC"))
?((P " loading WATSON consistency checker  <CC.MIC>") (PP) (LOAD "CC.MIC"))
?((P " loading general purpose predicates <GP.MIC>") (PP) (LOAD "GP.MIC"))
?((CUWIND "") (CLOSE "loading system components"))
?((C))




==================================================

                    CC.MIC

==================================================


((CHECK ((HAS _p _c)) )
   (NOT HAS-NOT _p _c)
   (NOT IS-IN-THE-BOX _c)
   (FORALL ((PLAYER _p-other) (NOT EQ _p _p-other)) ((NOT HAS _p-other _c)))
   (OR ((HAS _p _c)) ((ADDCL ((HAS _p _c)) 1)
                      (ROUND _round)
                      (ADDCL ((HISTORY _round ((HAS _p _c)))))))
   /)
((CHECK ((IS-IN-THE-BOX _c)) )
   (FORALL ((PLAYER _p)) ((NOT HAS _p _c)))
   (OR ((IS-IN-THE-BOX _c)) ((ADDCL ((IS-IN-THE-BOX _c)) 1)
                             (ROUND _round)
                             (ADDCL ((HISTORY _round ((IS-IN-THE-BOX _c)))))))
   /)
((CHECK ((HAS-NOT-ALL-THREE _p _c1 _c2 _c3)))
   (IS-PLAYERS-LIST (_p1|_rest))
   (NOT ? ((HAS _p _c1) (HAS _p _c2) (HAS _p _c3)))
   (OR ((HAS-NOT-ALL-THREE _p _c1 _c2 _c3))
       ((ADDCL ((HAS-NOT-ALL-THREE _p _c1 _c2 _c3)) 1)
        (ROUND _round)
        (OR ((EQ _p _p1))
        ((ADDCL ((HISTORY _round ((HAS-NOT-ALL-THREE _p _c1 _c2 _c3)))))))))
   /)
((CHECK ((HAS-NOT-BOTH _p _c1 _c2)))
   (IS-PLAYERS-LIST (_p1|_rest))
   (NOT ? ((HAS _p _c1) (HAS _p _c2)))
   (OR ((HAS-NOT-BOTH _p _c1 _c2)) ((ADDCL ((HAS-NOT-BOTH _p _c1 _c2)) 1)
                                    (ROUND _round)
                    (OR ((EQ _p _p1))
                    ((ADDCL ((HISTORY _round ((HAS-NOT-BOTH _p _c1 _c2)))))))))
   /)
((CHECK ((HAS-AT-LEAST-ONE _p _s _l _w)))
   (IS-PLAYERS-LIST (_p1|_rest))
   (NOT ? ((HAS-NOT _p _s) (HAS-NOT _p _l) (HAS-NOT _p _w)))
   (OR ((HAS-AT-LEAST-ONE _p _s _l _w))
            ((ADDCL ((HAS-AT-LEAST-ONE _p _s _l _w)) 1)
             (ROUND _round)
             (OR ((EQ _p _p1))
             ((ADDCL ((HISTORY _round ((HAS-AT-LEAST-ONE _p _s _l _w)))))))))
   /)
((CHECK ((HAS-AT-LEAST-ONE _p _c1 _c2)))
   (IS-PLAYERS-LSIT (_p1|_rest))
   (NOT ? ((HAS-NOT _p _c1) (HAS-NOT _p _c2)))
   (OR ((HAS-AT-LEAST-ONE _p _c1 _c2))
       ((ADDCL ((HAS-AT-LEAST-ONE _p _c1 _c2)) 1)
        (ROUND _round)
        (OR ((EQ _p _p1))
        ((ADDCL ((HISTORY _round ((HAS-AT-LEAST-ONE _p _c1 _c2)))))))))
   /)
((CHECK ((HAS-NOT _p _c)))
   (IS-PLAYERS-LIST (_p1|_rest))
   (NOT HAS _p _c)
   (OR ((HAS-NOT _p _c)) ((ADDCL ((HAS-NOT _p _c)) 1)
                          (ROUND _round)
                          (OR ((EQ _p _p1))
                          ((ADDCL ((HISTORY _round ((HAS-NOT _p _c)))))))))
   /)
((CHECK ((AT-LEAST-ONE-IS-IN-THE-BOX _s _l _w)))
   (NOT ? ((PLAYER _p1) (HAS _p1 _s)
           (PLAYER _p2) (HAS _p2 _l)
           (PLAYER _p3) (HAS _p3 _w)))
   (OR ((AT-LEAST-ONE-IS-IN-THE-BOX _s _l _w))
          ((ADDCL ((AT-LEAST-ONE-IS-IN-THE-BOX _s _l _w)) 1)
           (ROUND _round)
           (ADDCL ((HISTORY _round ((AT-LEAST-ONE-IS-IN-THE-BOX _s _l _w)))))))
   /)
((CHECK ((AT-LEAST-ONE-IS-IN-THE-BOX _c1 _c2)))
   (NOT ? ((PLAYER _p1) (HAS _p1 _c1)
           (PLAYER _p2) (HAS _p2 _c2)))
   (OR ((AT-LEAST-ONE-IS-IN-THE-BOX _c1 _c2))
          ((ADDCL ((AT-LEAST-ONE-IS-IN-THE-BOX _c1 _c2)) 1)
           (ROUND _round)
           (ADDCL ((HISTORY _round ((AT-LEAST-ONE-IS-IN-THE-BOX _c1 _c2)))))))
   /)
((CHECK (_clause)) (INCONSISTENCY _clause) /)
((INCONSISTENCY _clause)
   (CUWIND WATSON)
   (CURSOR WATSON 3 3)
   (P "Inconsistency detected !!!!!!!!!! ")
   (CURSOR WATSON 5 3)
   (P "Somebody has asked three cards s/he holds her/himself,")
   (CURSOR WATSON 6 3)
   (P "or gave false information (by mistake or by intension).")
   (CURSOR WATSON 7 3)
   (P "WATSON cannot deal with irrational behaviour !")
   (CURSOR WATSON 16 3)
   (P "The inconsistency was detected")
   (CURSOR WATSON 17 3)
   (P "by trying to process the clause:")
   (CURSOR WATSON 19 3)
   (PCLAUSE _clause)
   (INMENU _option ("  no" "  yes") " justify ? " 17 40 13)
   (JUSTIFY _option)
   (STOP) /)
((FINAL-CHECK _s _l _w)
 (NOT AT-LEAST-ONE-IS-IN-THE-BOX _s1 _l1 _w1)
 /)
((FINAL-CHECK _s _l _w)
 (FORALL ((AT-LEAST-ONE-IS-IN-THE-BOX _s1 _l1 _w1))
         ((INTERSECT (_s1 _l1 _w1) (_s _l _w))))
 /)
((FINAL-CHECK _s _l _w)
 (INCONSISTENCY (Final check)))
((INTERSECT (_x|_rest) _secondlist)
 (OR ((ON _x _secondlist))
     ((INTERSECT _rest _secondlist)))
 /)




==================================================

                    GP.MIC

==================================================


((INMENU _select _menu _wind _startrow _startcol _width)
    (LST _menu)
    (NOT EQ _menu ())
    (SUM _startrow _rowsleft 21)
    (STRINGOF _window _wind)
    (splitmenu _rowsleft _menu _spltmenu)
    (showmenu _select () _spltmenu _window _startrow _startcol _width)/)
((showmenu _select _oldmenus (_menu|_rest) _wind _startrow _startcol _width)
  (CUWIND _curwind)
  (W _curwind ("~N"))
  (getwindname _oldmenus _rest _wind _window)
  (length-of _menu _menulen)
  (CRWIND _window _startrow _startcol _menulen _width 1 0)
  (W _window ("~]"))
  (CUWIND _curwind)
  (FORALL ((ON _entry _menu)) ((FWRITE _window ((CON _width)) (_entry))))
  (peruse _window _sel _menu _width)
  (validselect _sel _oldmenus _rest)
  /
  (CLOSE _window)
  (NOT EQ _sel "...break")
  (IF (EQ _sel "...next")
        ((showmenu _select (_menu|_oldmenus) _rest _wind _startrow _startcol _width))
        ((IF (EQ _sel "...prev")
               ((EQ _oldmenus (_prevmenu|_oldrest))
                (showmenu _select _oldrest (_prevmenu _menu|_rest) _wind _startrow _startcol _width))
               ((EQ _sel _select))))))
((validselect "...next" _prevmenus _nextmenus)
    /
    (NOT EQ _nextmenus ()))
((validselect "...prev" _prevmenus _nextmenus)
    /
    (NOT EQ _prevmenus ()))
((validselect|_args))
((getwindname _prevmenu _nextmenu _wind _window)
    (extendname _prevmenu _nextmenu _ext)
    (APPEND _wind _ext _wind2)
    (STRINGOF _wind2 _window))
((extendname () () ())/)
((extendname () (_menu|_rest) (" " " " "+"))/)
((extendname (_menu|_rest) () (" " " " "-"))/)
((extendname _prevmenu _nextmenu (" " " " "-" "+")))
((splitmenu _numentries _menu (_submenu|_restmenu))
  (split _numentries _menu _submenu _rest)
  /
  (splitmenu _numentries _rest _restmenu))
((splitmenu _numentries () ())/)
((splitmenu _numentries _menu (_menu)))
((split 0 _menu () _menu)
  /)
((split _numrows (_ent|_restmenu) (_ent|_reststart) _endmenu)
  (SUM _numrows-1 1 _numrows)
  (split _numrows-1 _restmenu _reststart _endmenu))
((length-of () 0))
((length-of (_A|_B) _C)
    (length-of _B _D)
    (SUM _D 1 _C))
((APPEND () _A _A))
((APPEND (_A|_B) _C (_A|_D))
  (APPEND _B _C _D))
((peruse _A _B (_C|_D) _E)
    (CURSOR _A 0 0)
    (choose _A _B (_C|_D) () _E))
((peruse|_A)
   (peruse|_A))
((choose _wind _select (_ent|_below) _above _width)
    (IF (EOF "TRM:")
          ((FWRITE _wind ((CON 3) (CON _width) (CON 1)) ("~]~M~R" _ent "~D"))
           (GETB "TRM:" _char)
           (FWRITE _wind ((CON 1) (CON _width) (CON 1)) ("~M" _ent "~M")))
          ((GETB "TRM:" _char)))
    (pick _char _wind _select (_ent|_below) _above _width))
((choose | _args)
    (choose | _args))
((pick 13 _wind _ent (_ent|_below) _above _width)
    (OR ((FWRITE _wind ((CON 2) (CON _width)) ("~M~B" _ent))
         (handle-printer _wind))
        ((W _wind ("~N"))
         (choose _wind _ent (_ent|_below) _above _width))))
((pick 45 _wind "...prev"|_rest))
((pick 43 _wind "...next"|_rest))
((pick 127 _wind "...break"|_rest))
((pick 80|_args)
    (movedown|_args))
((pick 32| _args)
    (movedown|_args))
((pick 24|_args)
    (movedown|_args))
((pick 72|_args)
    (moveup|_args))
((pick 8|_args)
    (moveup|_args))
((pick 5|_args)
    (moveup|_args))
((pick 14 _wind|_rest)
    (change-printer off)
    FAIL)
((pick 16 _wind|_rest)
    (change-printer on)
    FAIL)
((pick 15 _wind|_rest)
    (W _wind ("~O"))
    FAIL)
((pick 23 _wind|_rest)
    (W _wind ("~W"))
    FAIL)
((movedown _wind _select (_ent _nextent|_below) _above _width)
    /
    (W _wind ("~J"))
    (choose _wind _select (_nextent|_below) (_ent|_above) _width))
((movedown|_args)
    (choose|_args))
((moveup _wind _select _below (_prevent|_above) _width)
    /
    (W _wind ("~H~M"))
    (choose _wind _select (_prevent|_below) _above _width))
((moveup|_args)
    (choose|_args))
((printer off))
((change-printer _state)
    (KILL printer)
    (ADDCL ((printer _state))))
((handle-printer _wind)
    (IF (printer off)
           ((W _wind ("~N")))
           ((W _wind ("~P")))))




==================================================

                    JE.MIC

==================================================


((JUSTIFY "  no"))
((JUSTIFY "  yes")
  (GIVE-HISTORY-FACTS))
((EXPL _card _type _line)
  (IS-IN-THE-BOX _card)
  (CURSOR explanations _line 0)
  (P " I know that <" _card "> is in the box. So I don't need any")
  (SUM _line 1 _line1)
  (CURSOR explanations _line1 0)
  (P " information about type <" _type ">! By asking <" _card "> I")
  (SUM _line1 1 _line2)
  (CURSOR explanations _line2 0)
  (P " force opponents to reveal information about one of the")
  (SUM _line2 1 _line3)
  (CURSOR explanations _line3 0)
  (P " other proposed cards. But if you like, you may ask any card")
  (SUM _line3 1 _line4)
  (CURSOR explanations _line4 0)
  (P " of type <" _type "> you hold yourself instead of <" _card ">!") /)
((EXPL _card _type _line)
  (CURSOR explanations _line 0)
  (P " I have no conclusive information about card <" _card ">. As far")
  (SUM _line 1 _line1)
  (CURSOR explanations _line1 0)
  (P " as I know, it may be in the box. By asking <" _card "> I will")
  (SUM _line1 1 _line2)
  (CURSOR explanations _line2 0)
  (P " find out about it or about one of the other uncertain")
  (SUM _line2 1 _line3)
  (CURSOR explanations _line3 0)
  (P " cards I propose you to ask.") /)
((EXPLAINING "  no"|_rest))
((EXPLAINING "  yes" _s _l _w)
  (CRWIND explanations 0 0 18 78)
  (EXPL _s suspect 1)
  (EXPL _l location 6)
  (EXPL _w weapon 11)
  (CURSOR explanations 17 0)
  (P " Hit any key when you're ready...")
  (GETB "TRM:" _x)
  (CUWIND table)
  (CLOSE explanations) /)
((EXPLAIN _s _l _w)
  (INMENU _option ("  no" "  yes") " explain? " 17 50 12)
  (EXPLAINING _option _s _l _w) /)
((ADVISE-TO-SHOW _p1 _s _w _l)
 (HAS _p1 _s) (HAS _p1 _w) (HAS _p1 _l)
 (ADVISE-TO-HIDE-LOCATION _s)
 /)
((ADVISE-TO-SHOW _p1 _s _w _l)
 (HAS _p1 _s) (HAS _p1 _l)
 (ADVISE-TO-HIDE-LOCATION _s)
 /)
((ADVISE-TO-SHOW _p1 _s _w _l)
 (HAS _p1 _w) (HAS _p1 _l)
 (ADVISE-TO-HIDE-LOCATION _w)
 /)
((ADVISE-TO-SHOW _p1 _s _w _l)
 (HAS _p1 _s) (HAS _p1 _w)
 (ADVISE-TO-SHOW-SYSTEMATICLY _s)
 /)
((ADVISE-TO-SHOW _p1 _s _w _l)
 (ON _x (_s _w _l))
 (HAS _p1 _x)
 (P "You must show" _x ",you have no choice")
 (TERMINATE)
 /)
((ADVISE-TO-SHOW-SYSTEMATICLY _s)
 (P "WATSON advises you to show" _s)
 (CURSOR table 17 1)
 (P "because it is sensible to show as far")
 (CURSOR table 18 1)
 (P "as possible always the same card.")
 (TERMINATE)
 /)
((ADVISE-TO-HIDE-LOCATION _s)
 (P "WATSON advises you to show" _s)
 (CURSOR table 17 1)
 (P "because it is sensible to: ")
 (CURSOR table 18 1)
 (P "1. hide cards of the type location")
 (CURSOR table 19 1)
 (P "2. show always the same card if possible")
 (TERMINATE)
 /)
((TERMINATE)
 (CURSOR table 21 1)
 (P "Hit any key to continue...")
 (GETB "TRM:" _x)
 (CUWIND WATSON)
 (CLOSE table)
 /)



==================================================

                    KB.MIC

==================================================


((IS-IN-THE-BOX))
((AT-LEAST-ONE-IS-IN-THE-BOX))
((HAS-NOT-ALL-THREE))
((HAS-NOT-BOTH))
((HAS-AT-LEAST-ONE-OF-THREE))
((HAS-AT-LEAST-ONE))
((THE-BOX-OWNS-AT-LEAST-ONE _c1 _c2)
 (AT-LEAST-ONE-IS-IN-THE-BOX _c1 _c2))
((THE-BOX-OWNS-AT-LEAST-ONE _c1 _c2)
 (AT-LEAST-ONE-IS-IN-THE-BOX _c2 _c1))
((THE-BOX-OWNS-AT-LEAST-ONE _c1 _c2)
  (AT-LEAST-ONE-IS-IN-THE-BOX _c1 _c2 _c3)
  (PLAYER _p)
  (OWNS _p _c3)
  (CHECK ((AT-LEAST-ONE-IS-IN-THE-BOX _c1 _c2)) ) /)
((THE-BOX-OWNS-AT-LEAST-ONE _c1 _c2)
  (AT-LEAST-ONE-IS-IN-THE-BOX _c1 _c3 _c2)
  (PLAYER _p)
  (OWNS _p _c3)
  (CHECK ((AT-LEAST-ONE-IS-IN-THE-BOX _c1 _c2)) ) /)
((THE-BOX-OWNS-AT-LEAST-ONE _c1 _c2)
  (AT-LEAST-ONE-IS-IN-THE-BOX _c3 _c1 _c2)
  (PLAYER _p)
  (OWNS _p _c3)
  (CHECK ((AT-LEAST-ONE-IS-IN-THE-BOX _c1 _c2)) ) /)
((OWNS-AT-LEAST-ONE _p _c1 _c2)
  (HAS-AT-LEAST-ONE _p _c1 _c2))
((OWNS-AT-LEAST-ONE _p _c1 _c2)
  (HAS-AT-LEAST-ONE-OF-THREE _p _c1 _c _c2)
  (HAS-NOT _p _c)
  (CHECK ((HAS-AT-LEAST-ONE _p _c1 _c2)) ) /)
((OWNS-AT-LEAST-ONE _p _c1 _c2)
  (HAS-AT-LEAST-ONE-OF-THREE _p _c1 _c2 _c)
  (HAS-NOT _p _c)
  (CHECK ((HAS-AT-LEAST-ONE _p _c1 _c2)) ) /)
((OWNS-AT-LEAST-ONE _p _c1 _c2)
  (HAS-AT-LEAST-ONE-OF-THREE _p _c _c1 _c2)
  (HAS-NOT _p _c)
  (CHECK ((HAS-AT-LEAST-ONE _p _c1 _c2)) ) /)
((HAS-NOT))
((OWNS-NOT-BOTH _p _c1 _c2)
  (HAS-NOT-BOTH _p _c1 _c2))
((OWNS-NOT-BOTH _p _c1 _c2)
  (HAS-NOT-ALL-THREE _p _c1 _c _c2)
  (HAS _p _c)
  (CHECK ((HAS-NOT-BOTH _p _c1 _c2)) ) /)
((OWNS-NOT-BOTH _p _c1 _c2)
  (HAS-NOT-ALL-THREE _p _c1 _c2 _c)
  (HAS _p _c)
  (CHECK ((HAS-NOT-BOTH _p _c1 _c2)) ) /)
((OWNS-NOT-BOTH _p _c1 _c2)
  (HAS-NOT-ALL-THREE _p _c _c1 _c2)
  (HAS _p _c)
  (CHECK ((HAS-NOT-BOTH _p _c1 _c2)) ) /)
((HAS))
((OWNS-NOT _p1 _c)
  (IS-PLAYERS-LIST (_p1|_rest))
  (NOT HAS _p1 _c))
((OWNS-NOT _p _c)
  (HAS-NOT _p _c))
((OWNS-NOT _p _c)
  (OWNS-NOT-BOTH _p _c1 _c)
  (HAS _p _c1)
  (CHECK ((HAS-NOT _p _c)) ) /)
((OWNS-NOT _p _c)
  (OWNS-NOT-BOTH _p _c _c1)
  (HAS _p _c1)
  (CHECK ((HAS-NOT _p _c)) ) /)
((OWNS-NOT _p _c)
  (PLAYER _other-p)
  (NOT EQ _other-p _p)
  (HAS _other-p _c)
  (CHECK ((HAS-NOT _p _c)) ) /)
((OWNS _p _c)
  (HAS _p _c))
((OWNS _p _c)
  (OWNS-AT-LEAST-ONE _p _c1 _c)
  (OWNS-NOT _p _c1)
  (CHECK ((HAS _p _c)) ) /)
((OWNS _p _c)
  (OWNS-AT-LEAST-ONE _p _c _c1)
  (OWNS-NOT _p _c1)
  (CHECK ((HAS _p _c)) ) /)
((OWNED-BY-THE-BOX _c)
  (IS-IN-THE-BOX _c))
((OWNED-BY-THE-BOX _c)
  (TYPE _c _type)
  (FORALL ((TYPE _card _type) (NOT EQ _card _c))
          ((PLAYER _p) (OWNS _p _card)))
  (CHECK ((IS-IN-THE-BOX _c)) ) /)
((OWNED-BY-THE-BOX _c)
  (FORALL ((PLAYER _p)) ((OWNS-NOT _p _c)))
  (CHECK ((IS-IN-THE-BOX _c)) ) /)
((OWNED-BY-THE-BOX _c)
  (THE-BOX-OWNS-AT-LEAST-ONE _c _c1)
  (PLAYER _p)
  (OWNS _p _c1)
  (CHECK ((IS-IN-THE-BOX _c)) ) /)
((OWNED-BY-THE-BOX _c)
  (THE-BOX-OWNS-AT-LEAST-ONE _c1 _c)
  (PLAYER _p)
  (OWNS _p _c1)
  (CHECK ((IS-IN-THE-BOX _c)) ) /)
((MAY-BE-IN-THE-BOX _c)
  (IS-IN-THE-BOX _c))
((MAY-BE-IN-THE-BOX _c)
  (OWNED-BY-THE-BOX _c))
((MAY-BE-IN-THE-BOX _c)
  (FORALL ((PLAYER _p)) ((NOT OWNS _p _c)))
  (NOT ? ((TYPE _c _type) (IS-IN-THE-BOX _other-c) (TYPE _other-c _type))))
((CARD _c)
  (TYPE _c suspect))
((CARD _c)
  (TYPE _c location))
((CARD _c)
  (TYPE _c weapon))
((TYPE _c suspect)
  (IS-SUSPECTS-LIST _slist)
  (ON _c _slist))
((TYPE _c location)
  (IS-LOCATIONS-LIST _llist)
  (ON _c _llist))
((TYPE _c weapon)
  (IS-WEAPONS-LIST _wlist)
  (ON _c _wlist))
((PLAYER _p)
  (IS-PLAYERS-LIST _plist)
  (ON _p _plist))
((IS-WEAPONS-LIST (letter-opener cable phone-cord screwdriver poison-coffee stapler)))
((IS-LOCATIONS-LIST (computer-room hall washroom cafeteria conference-room closet elevator office library)))
((IS-SUSPECTS-LIST ("Miss Doss" "Mrs. Mips " "Mrs. Deadlines" "Rev. Reedright" "Dr. Fosfer" "Lt. Bixer")))
((IS-PLAYERS-LIST ()))




==================================================

                    UI.MIC

==================================================


((INTRODUCE)
   (CRWIND introduction 0 0 22 78)
(PP)
(P "      WATSON is an expert system for use in a card-based") (PP)
(P "   murder mystery game. WATSON will advise you at every") (PP)
(P "   stage of the game and in all decisions you have to") (PP)
(P "   make. If you desire, WATSON will explain and justify the") (PP)
(P "   advice that it provides.") (PP)
(P "      WATSON also checks the consistency of the information ") (PP)
(P "   it obtains during the game and prints an error message") (PP)
(P "   if consistency is lost due to irrational behaviour or") (PP)
(P "   cheating.") (PP)
(P "      WATSON is easy to use because it is almost entirely") (PP)
(P "   menu-driven. The system communicates with you by means ") (PP)
(P "   of windows and menus. By using the up and down cursor") (PP)
(P "   arrow keys, you  can choose the appropriate option,") (PP)
(P "   which you then confirm by hitting the <carriage return>") (PP)
(P "   key.") (PP)
(P "      Before starting the game, WATSON needs to know a few ") (PP)
(P "   facts about the players involved, the order they will  ") (PP)
(P "   play, and the cards held by the user of WATSON.") (PP) (PP)
(P "      Hit any key when you are ready to start...")
   (GETB "TRM:" _x)
   (CRWIND WATSON 0 0 22 78)
   (CLOSE introduction)
   /)
((C)
  (INTRODUCE)
  (PLAYER-NAMES-ASKED)
  (ADDCL ((ROUND 0)))
  (ADDCL ((HISTORY 0 ((" in round" 0 "the following facts were deduced:")))) 1)
  (CARDS-ASKED)
  (BEGUN _p)
  /
  (PLAYED _p)
  (STOP) /)
((CONTEMPLATED _c _line)
  (CURSOR " just a moment...." _line 0)
  (P "                    ")
  (CURSOR " just a moment...." _line 0)
  (P _c))
((REQUEST _c1 _c2 _c3)
  (CRWIND " just a moment...." 5 20 5 20)
  (TYPE _c1 suspect)
  (CONTEMPLATED _c1 2)
  (MAY-BE-IN-THE-BOX _c1)
  (TYPE _c2 location)
  (CONTEMPLATED _c2 3)
  (MAY-BE-IN-THE-BOX _c2)
  (TYPE _c3 weapon)
  (CONTEMPLATED _c3 4)
  (MAY-BE-IN-THE-BOX _c3)
  (CUWIND WATSON)
  (CLOSE " just a moment....") /)
((THREE-CARDS-ASKED _s _l _w)
  (IS-SUSPECTS-LIST _slist)
  (INMENU _s _slist suspect 0 10 40)
  (IS-LOCATIONS-LIST _llist)
  (INMENU _l _llist location 0 10 40)
  (IS-WEAPONS-LIST _wlist)
  (INMENU _w _wlist murderweapon 0 10 40) /)
((EXECUTED _p "asking three cards")
  (CRWIND table 0 10 22 58)
  (CURSOR table 20 1)
  (P  _p "asks ?")
  (THREE-CARDS-ASKED _s _l _w)
  (CHECK ((HAS-NOT-ALL-THREE _p _s _l _w)))
  (CUWIND WATSON)
  (CLOSE table)
  (REQUEST-ANSWERED _p _s _l _w)
  (IS-PLAYERS-LIST _list)
  (SUCCESSOR _p _pnext _list)
  /
  (PLAYED _pnext) /)
((EXECUTED _p "giving suspicion")
  (INMENU _answer (correct incorrect) "suspicion is:" 2 0 30)
  (EXECUTED _p _answer) /)
((EXECUTED _p correct)
  (CURSOR WATSON 8 28)
  (P "** Congratulations ")
  (P _p) /)
((EXECUTED _p incorrect)
  (CRWIND table 0 10 22 58)
  (CURSOR table 20 1)
  (P "What cards has ")
  (P _p)
  (P " mentioned in his/her suspicion ?")
  (THREE-CARDS-ASKED _s _l _w)
  (CHECK ((HAS-NOT _p _s)) )
  (CHECK ((HAS-NOT _p _l)) )
  (CHECK ((HAS-NOT _p _w)) )
  (ADDCL ((DISQUALIFIED _p)))
  (IS-PLAYERS-LIST _list)
  (SUCCESSOR _p _pnext _list)
  (CUWIND WATSON)
  (CLOSE table)
  /
  (PLAYED _pnext) /)
((EXECUTED nobody _p _s _l _w)
  (CHECK ((AT-LEAST-ONE-IS-IN-THE-BOX _s _l _w)) )
  (IS-PLAYERS-LIST (_p1|_rest))
  (FORALL ((ON _player _rest) (NOT EQ _player _p))
          ((CHECK ((HAS-NOT _player _s)))
           (CHECK ((HAS-NOT _player _l)))
           (CHECK ((HAS-NOT _player _w)))))
  /)
((EXECUTED _p1 _p _s _l _w)
 (IS-PLAYERS-LIST (_p1|_rest))
 (CRWIND table 0 10 22 58)
 (CURSOR table 16 1)
 (ADVISE-TO-SHOW _p1 _s _w _l)
 /)
((EXECUTED _p-answered _p1 _s _l _w)
  (IS-PLAYERS-LIST (_p1 _p2|_rest))
  (INMENU _card (_s _l _w) "Which card has been shown?" 2 0 30)
  (CHECK ((HAS _p-answered _card)) )
  (EXECUTED "no answer" _p-answered _p2 _s _l _w) /)
((EXECUTED _p1-answered _p _s _l _w)
  (IS-PLAYERS-LIST (_p1-answered|_rest)) /)
((EXECUTED _p-answered _p _s _l _w)
  (CHECK ((HAS-AT-LEAST-ONE _p-answered _s _l _w)) )
  (IS-PLAYERS-LIST _list)
  (SUCCESSOR _p _pnext _list)
  (EXECUTED "no answer" _p-answered _pnext _s _l _w) /)
((EXECUTED "no answer" _p-answered _p _s _l _w)
  (EQ _p _p-answered) /)
((EXECUTED "no answer" _p-answered _p _s _l _w)
  (CHECK ((HAS-NOT _p _s)) )
  (CHECK ((HAS-NOT _p _l)) )
  (CHECK ((HAS-NOT _p _w)) )
  (IS-PLAYERS-LIST _list)
  (SUCCESSOR _p _pnext _list)
  (EXECUTED "no answer" _p-answered _pnext _s _l _w) /)
((REQUEST-ANSWERED _p1 _s _l _w)
 (IS-PLAYERS-LIST (_p1|_rest))
 (ASK-WHO _p1 _rest _s _l _w) /)
((REQUEST-ANSWERED _p _s _l _w)
  (IS-PLAYERS-LIST (_p1|_rest))
  (SUCCESSOR _p _p1 (_p1|_rest))
  (ON _x (_s _l _w))
  (HAS _p1 _x)
  (CRWIND table 0 10 22 58)
  (CURSOR table 16 1)
  (ADVISE-TO-SHOW _p1 _s _w _l)
  /)
((REQUEST-ANSWERED _p _s _l _w)
  (IS-PLAYERS-LIST (_p1|_rest))
  (NOT HAS _p1 _s) (NOT HAS _p1 _l) (NOT HAS _p1 _w)
  (APPEND _front (_p|_end) _rest)
  (APPEND _end _front _actuallist)
  (ASK-WHO _p _actuallist _s _l _w) /)
((REQUEST-ANSWERED _p _s _l _w)
  (IS-PLAYERS-LIST _list)
  (APPEND _front (_p|_end) _list)
  (APPEND _end _front _actuallist)
  (ASK-WHO _p _actuallist _s _l _w) /)
((ASK-WHO _p _list _s _l _w)
 (APPEND _list (nobody) _menulist)
 (INMENU _p-answered _menulist "Who answers ?" 2 0 30)
 /
 (EXECUTED _p-answered _p _s _l _w) /)
((REQUEST-PRESENTED (_s _l _w))
  (CRWIND table 0 10 22 58)
  (CURSOR table 17 1)
  (P "*** WATSON advises you to ask for: ")
  (CURSOR table 19 5)
  (P _s)
  (CURSOR table 20 5)
  (P _l)
  (CURSOR table 21 5)
  (P _w)
  (EXPLAIN _s _l _w) /)
((SOLUTION-PRESENTED (_s _l _w))
  (CURSOR WATSON 16 1)
  (P "*** The solution is : ")
  (CURSOR WATSON 18 5)
  (P _s)
  (CURSOR WATSON 19 5)
  (P _l)
  (CURSOR WATSON 20 5)
  (P _w)
  (INMENU _option ("  no" "  yes") " justify ? " 17 40 13)
  (JUSTIFY _option) /)
((IS-SOLUTION (_s _l _w))
  (IS-IN-THE-BOX _s)
  (IS-IN-THE-BOX _l)
  (IS-IN-THE-BOX _w)
  (FINAL-CHECK _s _l _w)
  /)
((SUCCESSOR _p1 _p2 _list)
  (IS-PLAYERS-LIST (_p1 _p2|_rest)) /)
((SUCCESSOR _p _p1 (_p))
  (IS-PLAYERS-LIST (_p1|_rest)) /)
((SUCCESSOR _p _pnext (_p _pnext|_rest)) /)
((SUCCESSOR _p _pnext (_h|_t))
  (SUCCESSOR _p _pnext _t) /)
((DISQUALIFIED))
((REMOVED (_p|_rest) _p _rest) /)
((REMOVED (_h|_rest) _p _resultlist)
  (REMOVED _rest _p _templist)
  (APPEND (_h) _templist _resultlist) /)
((REMOVED (_p) _p ()) /)
((WEAPONS-ASKED (stop _last-item|())))
((WEAPONS-ASKED _menulist)
  (INMENU _s _menulist " murderweapons " 0 18 30)
  (OR ((EQ _s stop) /)
      ((IS-PLAYERS-LIST (_p1|_rest))
       (CHECK ((HAS _p1 _s)))
       (REMOVED _menulist _s _newmenulist)
       (WEAPONS-ASKED _newmenulist)))
  /)
((LOCATIONS-ASKED (stop _last-item|())))
((LOCATIONS-ASKED _menulist)
  (INMENU _s _menulist " locations " 0 18 30)
  (OR ((EQ _s stop) /)
      ((IS-PLAYERS-LIST (_p1|_rest))
       (CHECK ((HAS _p1 _s)))
       (REMOVED _menulist _s _newmenulist)
       (LOCATIONS-ASKED _newmenulist)))
  /)
((SUSPECTS-ASKED (stop _last-item|())))
((SUSPECTS-ASKED _menulist)
  (INMENU _s _menulist " suspects " 0 18 30)
  (OR ((EQ _s stop) /)
      ((IS-PLAYERS-LIST (_p1|_rest))
       (CHECK ((HAS _p1 _s)))
       (REMOVED _menulist _s _newmenulist)
       (SUSPECTS-ASKED _newmenulist)))
  /)
((STOP)
  (CURSOR WATSON 21 0)
  (P "Type any key to return to DOS")
  (GETB "TRM:" _x)
  (EXIT 0.))
((PLAYED _p)
  (IS-PLAYERS-LIST _list)
  (FORALL ((ON _player _list)) ((DISQUALIFIED _player))) /)
((PLAYED _p)
  (DISQUALIFIED _p)
  (IS-PLAYERS-LIST _list)
  (SUCCESSOR _p _pnext _list)
  /
  (PLAYED _pnext) /)
((PLAYED _p1)
  (IS-PLAYERS-LIST (_p1 _p2|_rest))
  (ROUND _round)
  (SUM _round 1 _nextround)
  (CURSOR WATSON 1 70)
  (P "ROUND")
  (CURSOR WATSON 2 70)
  (P "  " _nextround)
  (ADDCL ((ROUND _nextround)) 1)
  (ADDCL ((HISTORY _nextround
    ((" in round" _nextround "the following facts were deduced:")))) 1)
  (REQUEST _s _l _w)
  (OR ((IS-SOLUTION (_s _l _w)) (SOLUTION-PRESENTED (_s _l _w)) /)
      ((REQUEST-PRESENTED (_s _l _w))
       (REQUEST-ANSWERED _p1 _s _l _w)
       (CUWIND WATSON)
       (CLOSE table)
       (PLAYED _p2)))
  /)
((PLAYED _p)
  (INMENU _answer ("asking three cards" "giving suspicion") _p 2 0 30)
  (EXECUTED _p _answer) /)
((BEGUN _p)
  (IS-PLAYERS-LIST _list)
  (INMENU _p _list "Who starts the game ?" 2 0 30) /)
((CARDS-ASKED)
  (CRWIND table 0 10 22 58)
  (CURSOR table 20 1)
  (IS-PLAYERS-LIST (_p1|_rest))
  (P _p1)
  (P " please show WATSON your cards ")
  (IS-SUSPECTS-LIST _slist)
  (APPEND (stop) _slist _sstoplist)
  (SUSPECTS-ASKED _sstoplist)
  (IS-LOCATIONS-LIST _llist)
  (APPEND (stop) _llist _lstoplist)
  (LOCATIONS-ASKED _lstoplist)
  (IS-WEAPONS-LIST _wlist)
  (APPEND (stop) _wlist _wstoplist)
  (WEAPONS-ASKED _wstoplist)
  (CUWIND WATSON)
  (CLOSE table) /)
((ADD-NEXT-NAME-TO _list _line)
  (R|_name)
  (OR ((EQ _name (stop)) /)
      ((APPEND _list _name _newlist)
       (SUM 1 _line _newline)
       (DELCL ((IS-PLAYERS-LIST _list)))
       (ADDCL ((IS-PLAYERS-LIST _newlist)))
       (CURSOR table _newline 0)
       (P " next player is: ")
       (ADD-NEXT-NAME-TO _newlist _newline)))
  /)
((PLAYER-NAMES-ASKED)
  (CRWIND table 0 10 22 58)
  (CURSOR table 1 0)
  (P " Give WATSON the names of the players ")
  (CURSOR table 2 0)
  (P " in order, beginning with the player")
  (CURSOR table 3 0)
  (P " who is using WATSON.")
  (CURSOR table 4 0)
  (P " Avoid duplicate names and terminate")
  (CURSOR table 5 0)
  (P " name listing by typing <stop> ")
  (EQ _line 7)
  (CURSOR table _line 0)
  (P " user of WATSON: ")
  (IS-PLAYERS-LIST _list)
  (ADD-NEXT-NAME-TO _list _line)
  (INMENU _option ("  yes" "  no") " names allright ?" 18 59 18)
  (NAME-LISTING-ALLRIGHT _option)
  (CUWIND WATSON)
  (OR ((IS-PLAYERS-LIST (_p1 _p2|_more)))
      ((PROBLEM-IS-TRIVIAL)))
  (CLOSE table) /)
((NAME-LISTING-ALLRIGHT "  yes"))
((NAME-LISTING-ALLRIGHT "  no")
   (DELCL ((IS-PLAYERS-LIST _list)))
   (ADDCL ((IS-PLAYERS-LIST ())))
   (CUWIND WATSON)
   (CLOSE table)
   (PLAYER-NAMES-ASKED)
   /)
((PROBLEM-IS-TRIVIAL)
   (CLOSE table)
   (CURSOR WATSON 2 2) (P "You don't need an expert when playing ")
   (CURSOR WATSON 3 2) (P "with less than two players!!")
   (CURSOR WATSON 4 2) (P "In this case you should work it out yourself.")
   (STOP) /)
((PCLAUSE (" in round" _i _heading))
    (P "IN ROUND" _i _heading))
((PCLAUSE _clause)
 (IS-PLAYERS-LIST (_p1|_rest))
 (ON _p1 _clause)
 (NOT ON HAS _clause) /)
((PCLAUSE (IS-IN-THE-BOX _c))
    (P _c "is in the box"))
((PCLAUSE (HAS _p _c))
    (P _p " has" _c))
((PCLAUSE (HAS-NOT _p _c))
    (P _p " has not" _c))
((PCLAUSE (HAS-NOT-ALL-THREE _p _c1 _c2 _c3))
    (P _p "has not" _c1 "," _c2 "and" _c3 "all three"))
((PCLAUSE (HAS-NOT-BOTH _p _c1 _c2))
    (P _p " has not both" _c1 "and" _c2))
((PCLAUSE (AT-LEAST-ONE-IS-IN-THE-BOX _s _l _w))
    (P "at least one of" _s "," _l "and" _w "is in the box"))
((PCLAUSE (AT-LEAST-ONE-IS-IN-THE-BOX _c1 _c2))
   (P "at least one of" _c1 "and" _c2 "is in the box"))
((PCLAUSE (HAS-AT-LEAST-ONE _p _c1 _c2))
   (P _p "has at least one of" _c1 "and" _c2))
((PCLAUSE (HAS-AT-LEAST-ONE _p _s _l _w))
    (P _p "has at least one of" _s "," _l "and" _w))
((PCLAUSE _clause)
    (PCLAUSE-UNFORMATTED _clause)
    /)
((PCLAUSE-UNFORMATTED (_atom|()))
    (P _atom)
    /)
((PCLAUSE-UNFORMATTED (_atom1|_restclause))
    (P _atom1 " ")
    (PCLAUSE-UNFORMATTED _restclause)
    /)
((PRCL _round _clause)
    (NEXT-FREE-PAGE _nextpage)
    (SUM 1 _page _nextpage)
    (CHAROF _pagename _page)
    (CURSOR _pagename _row _col)
    (OR ((EQ _row 16)
          (CURSOR _pagename _row 73)
          (P "--->")
          (CREATE-WINDOW _nextpage _newpagename)
          (DELCL ((NEXT-FREE-PAGE _nextpage)))
          (SUM 1 _nextpage _nextnewpage)
          (ADDCL ((NEXT-FREE-PAGE _nextnewpage)))
          (CURSOR _newpagename 0 0)
          (P "ROUND " _round "CONTINUED:")
          (PP))
         ((SUM 1 _row _nextrow)
          (CURSOR _pagename _nextrow 0)))
    (PCLAUSE _clause)
    /)
((PAGE-TO " stop justifying")
    (CUWIND WATSON)
    /)
((PAGE-TO " next window")
    (CUWIND _pagename)
    (CHAROF _pagename _page)
    (SUM _page-prev 1 _page)
    (OR ((EQ _page-prev 96))
        ((CHAROF _pagename-prev _page-prev)
         (CUWIND _pagename-prev)))
    (PAGING)
    /)
((PAGE-TO " previous window")
    (CUWIND _pagename)
    (CHAROF _pagename _page)
    (SUM _page 1 _page-next)
    (NEXT-FREE-PAGE _upperbound)
    (OR ((EQ _page-next _upperbound))
        ((CHAROF _pagename-next _page-next)
         (CUWIND _pagename-next)))
    (PAGING)
    /)
((PAGING)
    (INMENU _option (" next window" " previous window" " stop justifying")
            " proven facts on " 18 50 25)
    (PAGE-TO _option)
    /)
((GIVE-HISTORY-FACTS)
    (ADDCL ((NEXT-FREE-PAGE 97)))
    (FORALL ((ROUND _i))
            ((GIVE-HISTORY-PAGE _i)))
    (PAGING)
    /)
((GIVE-HISTORY-PAGE _round)
    (NEXT-FREE-PAGE _page)
    (CREATE-WINDOW _page _pagename)
    (SUM 1 _page _nextfreepage)
    (DELCL ((NEXT-FREE-PAGE _page)))
    (ADDCL ((NEXT-FREE-PAGE _nextfreepage)))
    (CURSOR _pagename 0 0)
    (FORALL ((HISTORY _round (_clause)))
            ((PRCL _round _clause)))
    /)
((CREATE-WINDOW _page _pagename)
    (CHAROF _pagename _page)
    (CRWIND _pagename 0 0 17 78))


