Saturday, November 22, 2025

Another weekend goes by in the life of my Prolog interpreter

I don't want to give the impression that I do nothing else but work on this Prolog interpreter. I am still employed full-time and have been working on many things (some of which found their way to 'the other blog') but there's been nothing to write about here.

After the problems of last week, I decided it would be better to take a step back in order to take a step forward. So all the code that is connected to infix operators (basically the arithmetic operators) was removed, and we (CoPilot and I) wrote a new and cleaner parser that works on prefix operators. Both the parsing and the displaying are now clear, clean, elegant and recursive. No changes were required in the goal solver.

Previously I showed a database that earlier versions were not capable of parsing.
owns (noam, cd (unhalfbricking, 'Fairport Convention')). owns (sarit, cd ('Best of', 'Dire straits')). owns (noam, book ('Programming in Prolog', 'Clocksin and Mellish')). owns (noam, book ('The double helix', 'James D. Watson')).

This week's goals were to handle quoted names and to handle nested clauses, as shown in the above database. This wasn't particularly difficult, requiring only a few additions in the parser. But once this was done, I started thinking about how these facts could be queried. For example, I can see which items I own by means of the simple query, ?- owns (noam, X). But a more interesting query would be to list all the people who own a book. A naive query would be ?- owns (noam, book (_,_)). The underscore character, _, means that it doesn't matter what the title of the book or its author are; this is called the anonymous variable. Unfortunately when I issue this query, I get two results, both of which are noam.

In order to get only one solution, I could use the cut (!) operator, with which I never really got to grips with when I was learning Prolog. It's true that appending the cut to the book query gives me only one result, but when running the equivalent query with cd, only one result is returned, because of the cut.

The sophisticated way of doing this is via the intrinsic setof operator that takes three arguments. The query to show who owns a cd would be ?- setof (P, owns (P, cd (_, _)), People). The result of this is People = [noam, sarit]. Implementing this operator required a new unit as well as making a change in the code that decides to show the values of which variables after solutions are found. 

Once this was under my belt, it occurred to me that it would be good if there were a rule such as who_owns (What, X):- setof (P, owns (P, What (_,_)), People). In other words, to parametrise the internal functor. This is possible but requires a whole load of fiddly code that I am not interested in, to be honest. So that is tabled for a later date. The solution also requires handling an infix operator, and at the moment, infix operators are out of scope. 

Previously I might have compared Prolog with SQL; apart from anything else, both are declarative languages. SQL would have no problem in showing who owns what, primarily by means of the 'group by' directive, but this is much harder to do in Prolog.

The next stage obviously will be restoring the infix operators with all their attendant problems.



This day in blog history:

Blog #Date TitleTags
14622/11/2008Surreal momentKing Crimson
30822/11/2010The road to AntibesMIDI, Song writing, Soundclick, Antibes
65222/11/2013Nostalgia (song festival)MIDI, Kibbutz, Song writing
109222/11/2017One more instrument in the developer's toolkitPriority tips

No comments: