;            ************    ELIZA   *******************
; 
;  This program is taken from Sterling & Shapiro 14.4


 
? seeing(This_program), assert([anew, cls, new(This_program)]).
? qjump, window(400,120,50,50), paper(4), ink(0), cls.

eliza <- welcome, repeat, read_word_list (Input), eliza (Input), !, fail.

welcome <- writeln(["Hello! Please tell me about yourself"]).

eliza (["bye"])  <-
     writeln (["Goodbye. I hope I have helped you"]).

eliza (Input)  <-
     pattern (Stimulus, Response),             ; try a pattern
     match (Stimulus, Dictionary, Input),      ; does it match?
     match (Response, Dictionary, Output),     ; find corresponding output
     reply (Output),                           ; say it!
     !, fail.

; match (Pattern, Dictionary, Words)   Pattern matches the list of words
; Words and matchings are recorded in the Dictionary (which may look
; something like: [1 has "can, 2 has "help"]).

match ([N|Pattern], Dictionary, Target)  <-
     integer (N), lookup (N, Dictionary, Left_Target),
     append (Left_Target, Right_Target, Target),
     match (Pattern, Dictionary, Right_Target).

match ([Word |Pattern], Dictionary, [Word|Target])  <-
     atom (Word), match (Pattern, Dictionary, Target).
     match ([], Dictionary, []).

?op (1, "has").

lookup (Key, [Key has Value|Dictionary], Value).
lookup (Key, [Key' has Value'|Dictionary], Value) <-
     Key \= Key', lookup (Key, Dictionary, Value).

; Try to make your own patterns!!

pattern (["i", "am", 1],["how", "long", "have", "you", "been",1,"?"]).
pattern ([1, "you", 2, "me"], ["what makes you think I", 2, "you?"]).
pattern(["i",X,1,"my",2],["does anyone else in your family", X ,1,"your",2,"?"]) <- 
     emotion(X).
pattern(["i",X,1],["does anyone else in your family", X ,1,"?"]) <- 
     emotion(X).
pattern(["i",1,X,2],["Tell me more about your", Xness]) <- 
     symptom(X),  
     stringsum(X, "ness",Xness).
pattern([1,X,2], ["Do you also",X , 2,"?"]) <- emotion (X).
pattern(["i", "feel", 1], ["Do you often feel that way?"]).
pattern([1,X,2],["Can you tell me more about your",X,"?"]) <- 
     important (X).
pattern([1,"are","you",2],["What makes you think I am",2]).
pattern([ 1,"do","you",2],["I don't know really. What do y–u think?"]). 
pattern(["i",1],["really?"]).
pattern([1,"she",2], ["Tell me more about her"]). 
pattern([1,"he",2], ["Tell me more about him"]). 
pattern(["you", 1],["Why do you think so?"]).
pattern(["yes",1],["Why?"]).
pattern([1,X,2],[X,"?"])<-   keyword(X). 
pattern([1],["Please go on."]).

important ("father").  important("mother"). important("son"). important ("sister").
important("ql").  important ("brother"). important ("daughter").

emotion("love"). emotion ("hate"). emotion ("like").

symptom("angry"). symptom("tired"). symptom("nervous"). symptom("sad").

keyword("good"). keyword("bad"). keyword("never"). 
keyword("always"). keyword("strange"). keyword("stupid").

; reply (Word_list) is a kind of writeln adding spaces between words

reply ([Head|Tail]) <- write (Head), write(" "), reply(Tail).
reply([])  <- nl.

; read_word_list reads a list of words using the system predicate get(X)
read_word_list (Ws) <- lget(C), read_word_list (C,Ws).

read_word_list (C,[W|Ws]) <-
     word_char(C), 
     read_word(C, W, C'),
     read_word_list (C', Ws).

read_word_list (C, Ws)  <-
     space (C),
     lget (C'),
     read_word_list (C',Ws).

read_word_list (C,[]) <- period(C).

read_word (C, W, C') <-
     word_chars (C, Cs, C'),
     string (W, Cs).

word_chars (C,[C|Cs],C0) <-
     word_char (C),!,
     lget (C'),
     word_chars(C', Cs, C0).
word_chars(C,[],C) <-
     not word_char (C).

word_char(C) <-  lower (C).
word_char(C) <-  upper (C).
word_char (C) <- apostrophe(C).

lower (C) <- 97 <= C, C <= 122.
upper(C) <- 65 <= C, C <= 90.

space(32) . space (44). space (10).          ; space, comma, newline
period(46).  period(63). period (33).        ; period, question mark, !
apostrophe(39).

lget(C) <- get(C'), tolower (C', C).

tolower (Upper, Lower) <- upper (Upper),!, Lower := Upper + 32.
tolower (Rest, Rest).
 
stringsum(X,Y,Xy) <- 
     string(X,X'),
     string(Y,Y'), 
     append(X',Y',Xy'),
     string(Xy,Xy'). 

?writeln(["start the session by aking ? eliza."]).
 
 
