Talk About Network



Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > Functional > Re: a golden ol...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 18 of 40 Topic 2778 of 2841
Post > Topic >>

Re: a golden oldie challenge: Eliza

by Rainer Joswig <joswig@[EMAIL PROTECTED] > Feb 24, 2008 at 06:29 PM

In article 
<d27c55f3-4ee0-41a6-9974-8009d818cdc9@[EMAIL PROTECTED]
>,
 Mark Tarver <dr.mtarver@[EMAIL PROTECTED]
> wrote:

> > e:{$[(#b)=i:(|/'b:(w@[EMAIL PROTECTED]
(w:(`$" "\:x@[EMAIL PROTECTED]
".?"))in`)in\:/:A)?1b;E@[EMAIL PROTECTED]
> >      " "~n:c@[EMAIL PROTECTED]
(c:{x@[EMAIL PROTECTED]
 i)ss/:N;c
> >      .q.ssr[c;n;" "/:$(),P'(w[k],p:1_'(0,1+k:b[i]?1b)_`,w)"I"$n]]}
> >
> 
> Wow, looks like APL - also famous for inscrutable 1 liners.
> 
> Nothing from the big players Haskell, O'Caml & ML so far.
> 
> So far I've got
> 
> Lisp                       150 LOC  ................ Peter Norvig
> Qi (slightly revised)  63 LOC   .................Mark Tarver
> Ruby                      53 LOC   .................William James
> Q                           10 LOC   ..................Steven Apter
> K                             3 LOC  ...................Steven Apter
> 
> Mark

Below is the Common Lisp version from Norvig.

I have removed the duplicated definitions from his code.
He is developing the code in his book (especially the pattern
matcher), so he has more than one version of several functions.
The code is also written in a very readable style,
to support the educational purpose of his book.

When the comments and the rules are removed, the code
is about 110 lines.


;;; ==============================

;;; -*- Mode: Lisp; Syntax: Common-Lisp; -*-
;;; Code from Paradigms of Artificial Intelligence Programming
;;; Copyright (c) 1991 Peter Norvig

(defun starts-with (list x)
  "Is x a list whose first element is x?"
  (and (consp list) (eql (first list) x)))

(defun flatten (the-list)
  "Append together elements (or lists) in the list."
  (mappend #'mklist the-list))

(defun mklist (x)
  "Return x if it is a list, otherwise (x)."
  (if (listp x)
      x
      (list x)))

(defun mappend (fn the-list)  
  "Apply fn to each element of list and append the results."
  (apply #'append (mapcar fn the-list)))

(defun random-elt (choices)
  "Choose an element from a list at random."
  (elt choices (random (length choices))))

(defun variable-p (x)
  "Is x a variable (a symbol beginning with `?')?"
  (and (symbolp x) (equal (char (symbol-name x) 0) #\?)))

(defconstant fail nil "Indicates pat-match failure")

(defconstant no-bindings '((t . t))
  "Indicates pat-match success, with no variables.")

(defun get-binding (var bindings)
  "Find a (variable . value) pair in a binding list."
  (assoc var bindings))

(defun binding-val (binding)
  "Get the value part of a single binding."
  (cdr binding))

(defun lookup (var bindings)
  "Get the value part (for var) from a binding list."
  (binding-val (get-binding var bindings)))

(defun match-variable (var input bindings)
  "Does VAR match input?  Uses (or updates) and returns bindings."
  (let ((binding (get-binding var bindings)))
    (cond ((not binding) (extend-bindings var input bindings))
          ((equal input (binding-val binding)) bindings)
          (t fail))))

(defun extend-bindings (var val bindings)
  "Add a (var . value) pair to a binding list."
  (cons (cons var val)
        ;; Once we add a "real" binding,
        ;; we can get rid of the dummy no-bindings
        (if (and (eq bindings no-bindings))
            nil
            bindings)))

(defun pat-match (pattern input &optional (bindings no-bindings))
  "Match pattern against input in the context of the bindings"
  (cond ((eq bindings fail) fail)
        ((variable-p pattern)
         (match-variable pattern input bindings))
        ((eql pattern input) bindings)
        ((segment-pattern-p pattern)
         (segment-match pattern input bindings))
        ((and (consp pattern) (consp input)) 
         (pat-match (rest pattern) (rest input)
                    (pat-match (first pattern) (first input) 
                               bindings)))
        (t fail)))

(defun segment-pattern-p (pattern)
  "Is this a segment matching pattern: ((?* var) . pat)"
  (and (consp pattern)
       (starts-with (first pattern) '?*)))

(defun segment-match (pattern input bindings &optional (start 0))
  "Match the segment pattern ((?* var) . pat) against input."
  (let ((var (second (first pattern)))
        (pat (rest pattern)))
    (if (null pat)
        (match-variable var input bindings)
        ;; We assume that pat starts with a constant
        ;; In other words, a pattern can't have 2 consecutive vars
        (let ((pos (position (first pat) input
                             :start start :test #'equal)))
          (if (null pos)
              fail
              (let ((b2 (pat-match
                          pat (subseq input pos)
                          (match-variable var (subseq input 0 pos)
                                          bindings))))
                ;; If this match failed, try another longer one
                (if (eq b2 fail)
                    (segment-match pattern input bindings (+ pos 1))
                    b2)))))))

(defun rule-pattern (rule) (first rule))
(defun rule-responses (rule) (rest rule))

(defun use-eliza-rules (input)
  "Find some rule with which to transform the input."
  (some #'(lambda (rule)
            (let ((result (pat-match (rule-pattern rule) input)))
              (if (not (eq result fail))
                  (sublis (switch-viewpoint result)
                          (random-elt (rule-responses rule))))))
        *eliza-rules*))

(defun switch-viewpoint (words)
  "Change I to you and vice versa, and so on."
  (sublis '((I . you) (you . I) (me . you) (am . are))
          words))

(defun read-line-no-punct ()
  "Read an input line, ignoring punctuation."
  (read-from-string
    (concatenate 'string "(" (substitute-if #\space #'punctuation-p
                                            (read-line))
                 ")")))

(defun punctuation-p (char) (find char ".,;:`!?#-()\\\""))

(defun print-with-spaces (list)
  (format t "~{~a ~}" list))

(defun eliza ()
  "Respond to user input using pattern matching rules."
  (loop
    (print 'eliza>)
    (let* ((input (read-line-no-punct))
           (response (flatten (use-eliza-rules input))))
      (print-with-spaces response)
      (if (equal response '(good bye)) (RETURN)))))

(defparameter *eliza-rules*
 '((((?* ?x) hello (?* ?y))      
    (How do you do.  Please state your problem.))
   (((?* ?x) I want (?* ?y))     
    (What would it mean if you got ?y)
    (Why do you want ?y) (Suppose you got ?y soon))
   (((?* ?x) if (?* ?y)) 
    (Do you really think its likely that ?y) (Do you wish that ?y)
    (What do you think about ?y) (Really-- if ?y))
   (((?* ?x) no (?* ?y))
    (Why not?) (You are being a bit negative)
    (Are you saying "NO" just to be negative?))
   (((?* ?x) I was (?* ?y))       
    (Were you really?) (Perhaps I already knew you were ?y)
    (Why do you tell me you were ?y now?))
   (((?* ?x) I feel (?* ?y))     
    (Do you often feel ?y ?))
   (((?* ?x) I felt (?* ?y))     
    (What other feelings do you have?))))

;;; ==============================




 40 Posts in Topic:
a golden oldie challenge: Eliza
Mark Tarver <dr.mtarve  2008-02-22 03:49:44 
Re: a golden oldie challenge: Eliza
Mark Tarver <dr.mtarve  2008-02-22 03:59:02 
Re: a golden oldie challenge: Eliza
William James <w_a_x_m  2008-02-22 14:09:58 
Re: a golden oldie challenge: Eliza
"John Thingstad"  2008-02-23 13:00:30 
Re: a golden oldie challenge: Eliza
"Stevan Apter"   2008-02-23 13:21:00 
Re: a golden oldie challenge: Eliza
Ken Tilton <kennytilto  2008-02-23 15:24:42 
Re: a golden oldie challenge: Eliza
"Stevan Apter"   2008-02-23 16:42:31 
Re: a golden oldie challenge: Eliza
Ken Tilton <kennytilto  2008-02-23 20:55:56 
Re: a golden oldie challenge: Eliza
"Stevan Apter"   2008-02-24 07:44:32 
Re: a golden oldie challenge: Eliza
Mark Tarver <dr.mtarve  2008-02-22 17:12:49 
Re: a golden oldie challenge: Eliza
William James <w_a_x_m  2008-02-22 19:19:31 
Re: a golden oldie challenge: Eliza
Szabolcs <szhorvat@[EM  2008-02-23 14:12:17 
Re: a golden oldie challenge: Eliza
Szabolcs <szhorvat@[EM  2008-02-23 14:26:03 
Re: a golden oldie challenge: Eliza
Ben Bacarisse <ben.use  2008-02-24 00:01:08 
Re: a golden oldie challenge: Eliza
William James <w_a_x_m  2008-02-23 20:14:36 
Re: a golden oldie challenge: Eliza
Szabolcs <szhorvat@[EM  2008-02-24 01:51:00 
Re: a golden oldie challenge: Eliza
Mark Tarver <dr.mtarve  2008-02-24 03:59:56 
Re: a golden oldie challenge: Eliza
Rainer Joswig <joswig@  2008-02-24 18:29:12 
Re: a golden oldie challenge: Eliza
Neelakantan Krishnaswami   2008-02-24 18:03:20 
Re: a golden oldie challenge: Eliza
Mark Tarver <dr.mtarve  2008-02-24 04:06:09 
Re: a golden oldie challenge: Eliza
William James <w_a_x_m  2008-02-24 05:30:38 
Re: a golden oldie challenge: Eliza
"Stevan Apter"   2008-02-24 08:59:51 
Re: a golden oldie challenge: Eliza
William James <w_a_x_m  2008-02-24 06:22:31 
Re: a golden oldie challenge: Eliza
"Stevan Apter"   2008-02-24 09:37:17 
Re: a golden oldie challenge: Eliza
William James <w_a_x_m  2008-02-24 06:42:47 
Re: a golden oldie challenge: Eliza
"Stevan Apter"   2008-02-24 10:56:28 
Re: a golden oldie challenge: Eliza
William James <w_a_x_m  2008-02-24 06:57:22 
Re: a golden oldie challenge: Eliza
Dimitre Liotev <notmy@  2008-02-24 10:00:29 
Re: a golden oldie challenge: Eliza
"Stevan Apter"   2008-02-24 10:49:22 
Re: a golden oldie challenge: Eliza
Arved Sandstrom <asand  2008-02-24 17:28:25 
Re: a golden oldie challenge: Eliza
"Stevan Apter"   2008-02-24 13:03:11 
Re: a golden oldie challenge: Eliza
Ken Tilton <kennytilto  2008-02-24 13:59:55 
Re: a golden oldie challenge: Eliza
Dimitre Liotev <notmy@  2008-02-24 11:18:27 
Re: a golden oldie challenge: Eliza
William James <w_a_x_m  2008-02-24 12:36:12 
Re: a golden oldie challenge: Eliza
William James <w_a_x_m  2008-02-24 13:11:47 
Re: a golden oldie challenge: Eliza
William James <w_a_x_m  2008-02-24 13:26:38 
Re: a golden oldie challenge: Eliza
Arved Sandstrom <asand  2008-02-25 17:16:43 
Re: a golden oldie challenge: Eliza
William James <w_a_x_m  2008-02-24 13:35:20 
Re: a golden oldie challenge: Eliza
Brian Adkins <lojicdot  2008-02-25 09:52:13 
Re: a golden oldie challenge: Eliza
"Stevan Apter"   2008-02-25 16:58:13 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Fri May 16 4:52:19 CDT 2008.