< Previous | Next >
February 6, 2009 1:18 AM CST by psilord in category Unfinished Junk

That worked?

Today I tripped over a piece of garbage I wrote around 10 years ago.

Those of you who have attended those high powered team motivational/building retreats probably have a good understanding of the intelligence level of your coworkers often found at large souless companies. Of course you are different, but that is neither here nor there... You would probably classify the intelligence level of the majority of your coworkers as solidly between a broken differential planetary gear and a bent nail clipper or, in other words, about average.

In fact, for you cog in the machine programmers out there, I bet a lot of your conversations around the Mountain Dew cooler go like this:

Linux black > ./eliza
eliza> hello
How do you do? Please state your problem.
eliza> I hate computers.
Why do you hate computers?
eliza> They make me angry.
Please continue.
eliza> I feel a terrible rage when using computers.
Do you often feel a terrible rage when using computers?
eliza> yes
Good for you!
eliza> I want to break them into pieces.
Why do you want to break them into pieces?
eliza> I feel better when I do.
Do you often feel better when you do?
eliza> yes.
Excellent.
eliza> I hate you too.
Do you often hate me too?
eliza> I want to stomp you into dust.
What would it mean if you got to stomp me into dust?
eliza> I feel complete.
Do you often feel complete?
eliza> No.
Are you saying "NO" just to be negative?
eliza> I hate you.
Why do you hate me?
eliza> Where is my ax?
Do you feel strongly about discussing such things?
eliza> Come here, stupid machine.
What does that suggest to you?
eliza> I want to smash you.
Why do you want to smash me?
eliza> bye
Good bye.

That spine tingling wail I just heard, wherever I am, is the rememberance of those AI students who had to write the above in LISP. Ahh, good old LISP, how I miss thee! I've gotten huge into scheme of late and am writing a compiler for it and all that (I mean, who doesn't?!?). But no, the above beauty wasn't written in LISP, it was written in BOURNE SHELL!

This code was the prolegomena to the depth of my hate.

#!/bin/sh

# ELIZA for sh, written by psilord 1997
# This engine is only a left/right matcher, aka it only can match to the
# left and to the right of a given pattern, pretty limited, but good enough.
# This is under the BSD license, and God help you if you tinker with it, this
# code is bug riddled garbage.

# the results of a particular match '_' delimited
response0="How do you do? Please state your problem."
response1="What would it mean if you got RRR?_Why do you want RRR?_Suppose you got RRR soon?"
response2="Do you really think it's likely that RRR?_Do you wish that RRR?_What do you think about RRR?_Really? if RRR?"
response3="Why not?_You are being a bit negative._Are you saying \"NO\" just to be negative?"
response4="Were you really?_Perhaps I already knew you were RRR._Why do you tell me you were RRR now?"
response5="Do you often feel RRR?"
response6="Good bye."
response7="Very Interesting!_I am not sure I understand you fully._What does that suggest to you?_Please continue._Go on._Do you feel strongly about discussing such things?"
response8="Why are you RRR?_Are you sure that you are RRR?_Why do you think that you are RRR?"
response9="I am glad to hear that._Good for you!_Excellent."
response10="Why do you hate RRR?_Do you often hate RRR?"


# the patterns to match against along with the responses for that match
rule0="hello&$response0"
rule1="I want&$response1"
rule2="if&$response2"
rule3="no&$response3"
rule4="I was&$response4"
rule5="I feel&$response5"
rule6="bye&$response6"
rule7="exit&$response6"
rule8="quit&$response6"
rule9=" &$response7"
rule10="I am&$response8"
rule11="yes&$response9"
rule12="I hate&$response10"

# this is the data structure that holds EVERYTHING, rule9 is always last
metarule="$rule0#$rule1#$rule2#$rule3#$rule4#$rule5#$rule6#$rule7#$rule8#$rule10#$rule11#$rule12#$rule9"

# BSD & SYS5 compatible printline with no newline
write ()
{
        if [ "`echo -n`" = "-n" ]; then
                echo "$@\c"
        else
                echo -n "$@"
        fi
}


# $1 is the line to calculate
# $2 is the pattern I want to match
# left and right are the output
match()
{
    # see if the match takes place for this line...
    if [ `echo $1 | grep $2 -i` ]
    then
        left=`echo $1 | sed -e "s/$2.*//" -e "s/^[ \t]*//" -e "s/[ ]*$//"`
        right=`echo $1 | sed -e "s/$2/QQQQQQQQ/" -e "s/.*QQQQQQQQ//" \
                            -e "s/[ ]*$//" -e "s/^[ ]*//" -e "s/[.?!]$//"`
        return 0
    else
        return 1
    fi
}

# $1 is the response part of a rule, pick one of the answers and return it.
# damn shell forking piece of garbage.....this is a hack, the process forks
# in a *strange* way and doesn't wanna allow me to send a signal to the right
# thing. I'll beat it into submission later.
# select_result contains the answer to the query
select_response()
{
    select_work=$1
    select_ifs=$IFS
    IFS="_"

    # set up my random number generator... hehehehe
    trap 'IFS=$select_ifs; trap 2; return 0' 2
    pid=$$;
    (sleep 1; kill -2 $pid)&

    # do forever until the I get the signal...
    while :
    do
        # do the lookup
        for select_result in $select_work
        do
            echo $select_result > /dev/null 2>&1  # need this for timing...
        done
    done
}

# $1 is the pattern I want for $3(which is known)
# $2 is the line that contains $3 to be substituted
resolve()
{
    echo `echo $2 | sed -e "s/$3/$1/g"`
}

# this function takes the part to be substituted as the final answer and then
# changes it's point of view from a person talking to the computer to a
# computer talking to a person
switchpov()
{
    var=$1
    var=`switchpov_gears "$var" "you" "me"`
    var=`switchpov_gears "$var" "I" "you"`
    var=`switchpov_gears "$var" "am" "are"`
    var=`switchpov_gears "$var" "was" "were"`
    var=`switchpov_gears "$var" "mine" "yours"`
    var=`switchpov_gears "$var" "yourself" "myself"`
    echo $var
}

# a helper program for the above function
# $1 is the line in question
# $2 is the new pattern
# $3 is the old pattern
switchpov_gears()
{
    echo `echo $1 | sed -e "s/$3/ZZZZ/g" -e "s/$2/$3/g" -e "s/ZZZZ/$2/g"`
}

# start the madness

oldifs=$IFS
while :
do
    IFS=
    write "eliza> "
    read line

    if [ ! "$line" = "" ]; then
        IFS="#"
        for rule in $metarule
        do
            #echo "Rule-> $rule"
            pat=`echo $rule | cut -d'&' -f1`
    
            if match $line $pat
            then
                responses=`echo $rule | cut -d'&' -f2`
                select_response "$responses"
                response=$select_result
                right=`switchpov "$right"`
                left=`switchpov "$left"`
                response=`resolve "$right" "$response" "RRR"`
                response=`resolve "$left" "$response" "LLL"`
                echo $response
                if [ `echo $line | egrep -e '(bye|exit|quit)'` ]; then
                    exit 0;
                fi
                break;
            fi

        done
    fi

    IFS=$oldifs
done

exit 0;

End of Line.

< Previous | Next >