New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Psychotherapy Of Racter Or The Descent Into Madness Of Dr. Eliza #184

Open
spc476 opened this Issue Nov 30, 2015 · 11 comments

Comments

Projects
None yet
7 participants
@spc476

spc476 commented Nov 30, 2015

What happens when you have a plodding, rather unimaginative psychiatrist talking to an extroverted, manic and possibly dangerous patient? An insane project of a lot of work for a lot of nothing.

What I did was take Racter, the AI (Artificial Insanity) program from the mid 80s that supposedly wrote The Policeman's Beard Is Half Constructed, and have it talk to Eliza, a program from the mid 60s that is the first "chatterbot" to have been written. You would think this would be an easy task. You would be wrong.

I did not finish. I came close. Around 16,000 words. And given another couple of hours, I might have even gotten 50,000 words. But it wasn't easy. It's not easy. And I want to stop my own descent into madness over this project.

The code: https://github.com/spc476/NaNoGenMo-2015
The "novel" (or rather, what I have of it): https://github.com/spc476/NaNoGenMo-2015/tree/master/novel
And some additional notes about the project during the month: http://boston.conman.org/2015/11/11.1
http://boston.conman.org/2015/11/16-19

Somehow, it's always the "easy" projects that wipe you out ...

@tra38

This comment has been minimized.

tra38 commented Dec 1, 2015

It is weird reading Eliza itself being driven into insanity by a chatter bot that seems surprisingly intelligent (even if it is just the templates talking).

@MichaelPaulukonis

This comment has been minimized.

MichaelPaulukonis commented Dec 1, 2015

Nothing like some good ol' fashioned applied digital archaeology to finish things off.

@spc476

This comment has been minimized.

spc476 commented Dec 1, 2015

The issue I have, I'm sure, is that, under Unix, I'm ... well, it's kind of like

% eliza | racter | eliza

Only the two eliza programs are the same program, so it's more like:

% eliza >< racter

If that makes any sense with a made up symbol to pipe eliza:stdout to racter:stdin and racter:stdout to eliza:stdin. The issue that makes this hard---I mean, it's not that difficult to to set this up, but you have to have a third program to create the pipes and execute the two programs, and each program has to be mindful of any buffering that, say, the standard C library imposes. And the MS-DOS version of Racter I have uses INT 21h, function 6, which is the MS-DOS version of direct console I/O (so not only does it not handle redirection that well, it's constantly polling for Ctrl-C because this is a compiled BASIC program). You can see the tortuous logic I had to go through starting here: https://github.com/spc476/NaNoGenMo-2015/blob/master/C/msdos.c#L447

I may not even have the proper use of CR and LF down right (MS-DOS uses both, but my MS-DOS development system is fifteen years in storage ... ). So that leaves Eliza looking for the Racter prompt to know when to stop reading, parse the input, and send more output. I wouldn't be surprised if there's some bizarre race condition lurking in this.

@spc476

This comment has been minimized.

spc476 commented Dec 1, 2015

Oh, another thing I forgot to take into account by Eliza (which frankly, probably helped the output)---Racter echos what it receives. So each statement by Racter actually starts with what Eliza already said (the reason you don't see that is I'm using the output that Racter itself saves).

@hugovk

This comment has been minimized.

Collaborator

hugovk commented Dec 1, 2015

@cpressey

This comment has been minimized.

cpressey commented Dec 1, 2015

the MS-DOS version of Racter I have uses INT 21h, function 6 [...] it not handle redirection that well

Holy crap. OK...

My main thought about the race condition or whatever it is that is preventing this thing from getting to 50,000 words is, instead of thinking of the problem as "piping eliza:stdout to racter:stdin and racter:stdout to eliza:stdin", what if you think of it as introducing a third program which opens two pipes, one to eliza and one to racter, and which "brokers" the responses between the two?

That seems like it ought to be a bit cleaner; the lovely weird ugly I/O experience with racter could be isolated instead of trying to make eliza deal with it. For instance, giving it a timeout, and/or detect if it's not responding and just restart it.

It would mean using select() on the two pipes I guess, but for someone who just wrote their own baling-wire-and-chewing-gum MS-DOS emulator for NaNoGenMo(!!!), I don't expect that to be an advanced topic :)

(EDIT: I guess it's more fair to call it an MS-DOS emulator than an x86 emulator.)

@enkiv2

This comment has been minimized.

enkiv2 commented Dec 1, 2015

Sean,
You could just do:

mkfifo .tmp
tail -f .tmp | eliza | tee -a eliza_out.txt | racter | tee -a
racter_out.txt > .tmp
join <(sed 's/^$/\r/g' < eliza_out.txt | tr '\n' ' '| tr '\r' \n' | sed
's/^/eliza: /') <(sed 's/^$/\r/g' < racter_out.txt | tr '\n' ' '| tr '\r'
\n' | sed 's/^/racter: /') | tr '\t' '\n'

Horray for pipes!

On Tue, Dec 1, 2015 at 7:19 AM Chris Pressey notifications@github.com
wrote:

the MS-DOS version of Racter I have uses INT 21h, function 6 [...] it not
handle redirection that well

Holy crap. OK...

My main thought about the race condition or whatever it is that is
preventing this thing from getting to 50,000 words is, instead of thinking
of the problem as "piping eliza:stdout to racter:stdin and racter:stdout to
eliza:stdin", what if you think of it as introducing a third program which
opens two pipes, one to eliza and one to racter, and which "brokers" the
responses between the two?

That seems like it ought to be a bit cleaner; the lovely weird ugly I/O
experience with racter could be isolated instead of trying to make eliza
deal with it. For instance, giving it a timeout, and/or detect if it's not
responding and just restart it.

It would mean using select() on the two pipes I guess, but for someone
who just wrote their own baling-wire-and-chewing-gum x86 emulator for
NaNoGenMo(!!!), I don't expect that to be an advanced topic :)


Reply to this email directly or view it on GitHub
#184 (comment)
.

@greg-kennedy

This comment has been minimized.

greg-kennedy commented Dec 1, 2015

To me, the easiest solution was to write enough of a MS-DOS emulator to run Racter and to allow me to pipe data into and out of it.

It does appear Racter has succeeded in his goal to drive you certifiably insane.

@enkiv2

This comment has been minimized.

enkiv2 commented Dec 1, 2015

This is the int 21h printing call that is unable to print dollar signs
because it uses them as a string terminator, right?

On Tue, Dec 1, 2015 at 11:07 AM Greg Kennedy notifications@github.com
wrote:

To me, the easiest solution was to write enough of a MS-DOS emulator to
run Racter and to allow me to pipe data into and out of it.

It does appear Racter has succeeded in his goal to drive you certifiably
insane.


Reply to this email directly or view it on GitHub
#184 (comment)
.

@spc476

This comment has been minimized.

spc476 commented Dec 1, 2015

@enkiv2 INT 21h, function 9 is the function that prints a string ending with '$'. The function I had to deal with is INT 21h, function 6, or "Direction Console IO". In modern parlance, this is a non-blocking read or write of one character (byte) from the console device (depending upon the parameters its called with).

Also, I tried that crazy command line you gave---nice try, but it didn't work out of the box (Eliza would need some modification to deal with Racter, who actually starts the conversation). I'm not entirely convinced it would work in any case, as the version of tee I have can't be told to not buffer anything.

@cpressey That is a thought, and had I not come down with a upper respiratory infection, I might have had time to implement such a program (in retrospect, that is probably the cleanest way to deal with this, as it mimics the "hand copy-n-paste" I did a few weeks earlier). And yes, it's more of an MS-DOS emulator as I don't have to emulate an 8088.

@greg-kennedy

This comment has been minimized.

greg-kennedy commented Dec 1, 2015

FYI now you've got me spending my free time today using your INRAC notes:
http://boston.conman.org/2008/06/18.2

to implement Racter in a Perl module, so I can easily pit two of them against one another.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment