| |
comp.lang.lisp |
On 22 Feb, 11:49, Mark Tarver <dr.mtar...@ukonline.co.uk> wrote: > 1. The script itself should be changeable by any novice. That is to > 2. The program should receive keyboard input from the user - > During the Harrop Wars on comp.lang.lisp a lot of stuff was thrown > Oh last thing; don't get too uptight about this. It's only a bit of > Mark I looked for a Haskell/ML equivalent and found zilch. Norvig's PAIP Mark (define eliza (define eliza-loop (define respond-with (define no-match? (define user (define whitespace? (define user-loop (define remove-if (define pmatch (define pmatch-help (define nilbind (define consbind (define rep (define value-in
> do some recreational
> hacking and do an old old program I've not looked at for some time -
> Eliza. You all know Eliza well enough for me not to have to spell it
> out. The challenge is to implement or dig up an Eliza program (you
> don't have to write it yourself) in your favourite FPL. Note that the
> script that drives Eliza's responses should not be counted towards the
> LOC count. Some constraints.
> say that it should not
> be a pile of hard-wired code written in the native language of
> the program or require
> deep programming skills.
> including the usual punctuation
> and any characters he wants to enter without crashing.
> around about the desirability of pattern matching. The challenge is
> interesting because it involves a style of pattern-matching called
> 'segment pattern matching' that is not hard-wired into most FPLs and
> I'd like to see how well different FPLs cope with something outside
> the standard.
> fun.
LOC. You should run it under Qi 9.2 (latest release) because the
system function 'read-chars-as-stringlist' had a bug that was patched
in that release. My script is very boring ;).
contains a Lisp version in two files (eliza and eliza1) that is about
150 LOC excluding comments and script.
___________________________________________________________
(set *script* [
[[X "like" Y] ["Why" "do" "you" "like" Y "?"]]
[[X "father" Y] ["Tell me about your father."]]
[[X] ["That's very interesting. Do go on."]]])
-> (do (output "hi~%?- ") (eliza-loop (user) (value *script*))))
User Script -> (let Responses (map (/. S (pmatch User S)) Script)
Interesting (remove-if no-match? Responses)
ScriptError (if (empty? Interesting)
(error "script failure!")
_)
Choice (nth (+ (random (length Interesting)) 1)
Interesting)
Response (respond-with Choice)
Output (output "~{~A ~}~%~%?- " Response)
(eliza-loop (user) Script)))
[[] R] -> R
[[[X V] | B] R] -> (respond-with [B (rep X R V)]))
[#\Escape _] -> true
_ -> false)
-> (read-chars-as-stringlist (user-loop (read-char _)) whitespace?))
#\Space -> true
#\Tab -> true
#\, -> true
#\. -> true
_ -> false)
#\Newline -> []
C -> [C | (user-loop (read-char _))])
_ [] -> []
F [X | Y] -> (if (F X) (remove-if F Y) [X | (remove-if F Y)]))
User [I R] -> [(pmatch-help I User []) R])
X X B -> B
[X | Y] [X | Z] B -> (pmatch-help Y Z B)
[X | Y] Z B <- (let NilBind (nilbind X B)
ValX (value-in X NilBind)
(pmatch-help (rep X Y ValX) Z NilBind))
where (variable? X)
[X | Y] [W | Z] B <- (pmatch-help [X | Y] Z (consbind X W B))
where (variable?
X)
_ _ _ -> #\Escape)
X [] -> [[X []]]
X [[X V] | B] -> [[X V] | B]
X [Y | Z] -> [Y | (nilbind X Z)])
X W [] -> [[X [W]]]
X W [[X V] | B] -> [[X (append V [W])] | B]
X W [Y | B] -> [Y | (consbind X W B)])
_ [] _ -> []
X [X | Y] V -> (append V (rep X Y V))
X [Y | Z] V -> [Y | (rep X Z V)])
X B -> (head (tail (assoc X B))))