Friday, July 23, 2010

Porting the Amateur Reasoner/2

I didn't sleep too well last night, probably because I was very excited. Yesterday evening I was rummaging around old (paper) files which I had stored and I came across program listings for several versions of the Amateur Reasoner. I found the same listing that I downloaded a few days ago, but I also found later versions; the final version was v1.7.1 dated 1 May 1991.

In this version I see that I had addressed some of the problems in earlier versions: there is use of a generic list object (and all the pointer records are now objects), there is use of variable length strings, there is no hash table, tokens are concatenated making longer strings (and so the introduction text is a few strings instead of many tokens), and the tokeniser seems to have been rewritten and improved. I suppose that when I next get a block of free time, I'll make a Delphi port of this version. I found some correspondence regarding the program which stated that, as I had suspected, the program began on the PDP which had fixed length strings.

But wait! There's more: further looking through this file found various attempts at Prolog-like interpreters and query systems, all of which are less important to me today than what they were. YAPI (Yet Another Prolog Interpreter) was very interesting: I had almost all of the parts assembled including the recursive query solver and resolution (matching) although the unification part wasn't quite right. But the program was still missing the final key, which would allow the use of variables in rules.

I found  the complete documentation to an expert system called ESIE, which contained a knowledge base called 'animals' which looked extremely familiar. I obviously used this as the demonstration database for the Amateur Reasoner, although my program used a slightly different syntax, viz
(ESIE) goal is type.animal
legalanswers are yes no *
if backbone is yes then superphylum is backbone
if backbone is no then superphylum is jellyback
question backbone is "Does your animal have a backbone"?

(AR) goal (animal)
if backbone= yes then superphylum = backbone
if backbone = no then superphylum = jellyback
prompt (backbone) = Does your animal have a backbone?

Earlier versions of the AR required the 'legalvalues' (aka legalanswers) keyword, which later turned into 'values' which later became unnecessary as I realised that this information was redundant.

Right at the end of the file, I find a photocopy of an article which appeared in the April 1985 edition of BYTE magazine entitled "Inside an expert system: from index cards to Pascal program" written by Beverly A. Thompson and William A. Thompson - yes, the same authors who wrote the 'Very Tiny Prolog'! This article was accompanied by source code which I must have obtained from the magazine; I also found my port to PDP Pascal. Looking back on things now, this article must have made a very strong impression on me, although the Prolog interpreter would have made an even stronger impression, had I known about it at the time.

And as for the Prolog interpreter, whilst I couldn't find online the original articles referenced by the program, I was able to find the email of Bill Thompson. I wrote to him, saying how pleased I was to find this program, even if it was 25 years after the event (!) and asking whether he could send me an offprint of the two articles. Lo and behold, yesterday I received a reply, including an url where I could download them (thank you!). The first article was more or less an introduction to Prolog, including vague hints about how the language might be implemented in Pascal. This was the kind of material which I had read previously which had left me to fill in the blanks. The second article, though, was the real thing: explanations on how to implement Prolog. Linked lists, parser, solving queries by solving the head and then attaching the rest of the rule to the end of the queue of clauses to be solved, etc. The program also showed the missing link: how to handle variables in rules.

This key sentence actually appears in the first article, when Mr Thompson is writing about solving rules by making copies of them: The copy will be exactly the same as the original rule in the data base but all variables in the rule will be tagged by appending the recursion level to them. Maybe this sentence doesn't make too much sense on its own, but in the context of the article, it is gold.

Apart from the intrinsic values of these programs, it also gives me a clue what I was programming at the turn of the 90s. We moved from one kibbutz to another in September 1989, which is when I started working in the furniture factory. Shortly after, I began rewriting an application which someone had developed there which dealt with an online data collection system from the factory floor. This involved many new ideas and techniques with which I had not dealt before. None of that code survives.

At the time, I was coming to grips with Turbo Pascal 5.5, with its object orientated extensions, and then Turbo Pascal 6 with Turbo Vision - an almost fully fledged GUI for DOS. This latter system was incredibly difficult to grasp, not least for want of proper documentation and example programs, but mastering it made the transition to Windows very easy.

I remember writing a series of quasi database programs, in which the data was stored in a collection; at the beginning of the program, the data would be read via a stream into the collection, and at the end of the program the data would be written via a stream to disk. During the program's invocation, all the data was held in memory, which made accessing it very fast, although a program crash would lose all changes. I remember being very excited about Turbo (or was it Borland?) Pascal 7, which came with a memory manager which allowed DOS programs to use much more memory than before; such a database program could now hold 700+ records whereas previously it could only hold about 250.

Such concepts seem terribly quaint now.

No comments: