Google Mail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
Message from discussion a golden oldie challenge: Eliza

View Parsed - Show only message text

Path: g2news1.google.com!postnews.google.com!k2g2000hse.googlegroups.com!not-for-mail
From: William James <w_a_x_...@yahoo.com>
Newsgroups: comp.lang.lisp,comp.lang.functional
Subject: Re: a golden oldie challenge: Eliza
Date: Fri, 22 Feb 2008 14:09:58 -0800 (PST)
Organization: http://groups.google.com
Lines: 127
Message-ID: <c4d42479-42ea-4238-afaa-72517bf00d3b@k2g2000hse.googlegroups.com>
References: <a6732a9b-6628-481a-b1cd-c19f4e46936c@d5g2000hsc.googlegroups.com> 
	<bbd09f92-0661-41fa-83ee-4d5a1c884472@u72g2000hsf.googlegroups.com>
NNTP-Posting-Host: 170.142.158.4
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-Trace: posting.google.com 1203718199 20538 127.0.0.1 (22 Feb 2008 22:09:59 GMT)
X-Complaints-To: groups-abuse@google.com
NNTP-Posting-Date: Fri, 22 Feb 2008 22:09:59 +0000 (UTC)
Complaints-To: groups-abuse@google.com
Injection-Info: k2g2000hse.googlegroups.com; posting-host=170.142.158.4; 
	posting-account=vf5QpQoAAADgh9WOa2uZtoS1yoyJdEBw
User-Agent: G2/1.0
X-HTTP-UserAgent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) 
	Gecko/20080201 Firefox/2.0.0.12,gzip(gfe),gzip(gfe)

On Feb 22, 5:59 am, Mark Tarver <dr.mtar...@ukonline.co.uk> wrote:
> On 22 Feb, 11:49, Mark Tarver <dr.mtar...@ukonline.co.uk> wrote:
>
> > Having got 3936 LOC through a 4000 LOC implementation, I thought I'd
> > 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.
>
> > 1.  The script itself should be changeable by any novice.  That is to
> > 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.
>
> > 2.  The program should receive keyboard input from the user -
> > including the usual punctuation
> >      and any characters he wants to enter without crashing.
>
> > During the Harrop Wars on comp.lang.lisp a lot of stuff was thrown
> > 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.
>
> > Oh last thing; don't get too uptight about this.  It's only a bit of
> > fun.
>
> > Mark
>
> Well here is my shot at it in Qi.  Total LOC excluding script is 70
> LOC.

I added some features and wrote it in Ruby.

Sample session:

? Hi. I'm going to be your worst nightmare.
Why are you going to be my worst nightmare?
? I think you're full of it.
Why do you think I am full of it?
? My mother told me so.
Tell me about your mother.
? No. You tell me about yours.
We're talking about you, not me.
? You're obviously retarded.
Please don't be so personal.
? Damn your eyes!
I'm not sure that I understand you fully.
? Understand a kick in the pants?
Can you elaborate on that?
? I always ignore idiots.
Why do you always ignore idiots?
? I am afraid of dinosaurs.
Have you always been afraid of dinosaurs?
? quit

Script =
  [[:x, ["father",'mother','brother','sister'], :y],
    ["Tell me about your ", :_, "."]],
  [[:x, ["am", "i'm"], :y], [["Why are you", :y, "?"],
                             ["Have you always been", :y, "?"]]],
  [[:x, "I", :y], ["Why do you", :y, "?"]],
  [[:x, 'you', :y], [["We're talking about you, not me."],
             ["Please don't be so personal."]]],
  [[:x], [["That's very interesting. Do go on."],
        ["Tell me more."],
        ["I'm not sure that I understand you fully."],
        ["Can you elaborate on that?"] ]]

def change_person s
  h = { 'I','you',  'my','your', 'myself','yourself',
    'you are','I am', "you're", 'I am' }
  tmp = s.scan(/you are|you're|\w+|\W+/).map{|s|
    h[s] or h.invert[s] or s }
  tmp[-1] = "me"  if "I" == tmp[-1]
  tmp.join
end

patterns, symbols, replies = [], [], []

Script.each{|ary|
  syms = []
  patterns <<  Regexp.new( "^" +
    ary[0].map{|x|
      case x
        when Symbol
          syms << x
          "(.*?)"
        when String
          "\\b#{ x }\\b"
        when Array
          syms << :_
          "\\b(#{ x.join('|') })\\b"
        else
          ".*?"
      end
    }.join + "$", true ) # Case-insensitive.
  symbols << syms
  ary[1] = ary[1].sort_by{ rand }  if ary[1][0].is_a? Array
  replies << ary[1]
}

while true
  print "? "
  resp = gets.strip.sub(/[.!?,;]+$/, "")
  break if 'quit' == resp
  patterns.each_with_index{|pat,i|
    if match_data = resp.match( pat )
      reply = replies[i]
      if reply[0].is_a? Array
        # Rotate replies for variety.
        reply.push( reply.shift )
        reply = reply[0]
      end
      captures = match_data.captures.map{|s| change_person s}
      # Create associative array mapping symbols to values.
      t = Hash[ *symbols[i].zip( captures ).flatten ]
      puts reply.map{|x| x.is_a?(Symbol) ? t[x] : x }.join
      break
    end
  }
end

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google