Prolog In Smalltalk
While playing with Smalltalk/X, I noticed it comes with an implementation of Prolog in Smalltalk by Aoki Atsushi, who also wrote Lisp in Smalltalk. (Not a Common Lisp, though.)
This implementation executes regular Prolog code, so let's try it with my solution to Einstein's riddle.
| prologCode prolog result |
prologCode := '
?- remove. % clear Prolog database.
nextto(X, Y, List) :- iright(X, Y, List).
nextto(X, Y, List) :- iright(Y, X, List).
iright(L, R, [L | [R | _]]).
iright(L, R, [_ | Rest]) :- iright(L, R, Rest).
einstein(Houses, FishOwner) :-
=(Houses, [[house, norwegian, _, _, _, _], _, [house, _, _, _, milk, _], _, _]),
member([house, brit, _, _, _, red], Houses),
member([house, swede, dog, _, _, _], Houses),
member([house, dane, _, _, tea, _], Houses),
iright([house, _, _, _, _, green], [house, _, _, _, _, white], Houses),
member([house, _, _, _, coffee, green], Houses),
member([house, _, bird, pallmall, _, _], Houses),
member([house, _, _, dunhill, _, yellow], Houses),
nextto([house, _, _, dunhill, _, _], [house, _, horse, _, _, _], Houses),
member([house, _, _, _, milk, _], Houses),
nextto([house, _, _, marlboro, _, _], [house, _, cat, _, _, _], Houses),
nextto([house, _, _, marlboro, _, _], [house, _, _, _, water, _], Houses),
member([house, _, _, winfield, beer, _], Houses),
member([house, german, _, rothmans, _, _], Houses),
nextto([house, norwegian, _, _, _, _], [house, _, _, _, _, blue], Houses),
member([house, FishOwner, fish, _, _, _], Houses).
?- einstein(Houses, FishOwner).
'.
prolog := Prolog::PrologInterpreter new.
prolog textCollector: Transcript.
result := prolog
refute: prologCode
action: [ :answer | Transcript showCR: answer. true ].
Transcript show: result printString; cr.
In a workspace, enter the above code, select and do it:
?- remove. yes ?- einstein(Houses,FishOwner). no false
Ho-ho! Wrong answer! Look-see look-see... nope, I don't think I've transcribed the Prolog wrongly. I removed the underscores in next_to and Fish_Owner because the Smalltalk Prolog parser chokes on them.
Be that as it may ;-) let's take a peek at the implementation itself. It appears this particular Prolog uses operators like CAR, CDR, CONSP, etc. in its implementation, i.e., this is a Prolog written in Smalltalk using Lisp operators. Speculating wildly (I haven't gone through the code) this implementation may even be based on Peter Norvig's or Paul Graham's Common Lisp Prologs. If indeed so, it won't be too difficult to make it give the correct answer to Einstein's riddle, then.
Anyone looking for a programming project? Fixing this Prolog will give you the triple whammy of doing Smalltalk, Prolog and Lisp in one shot!
On reflection, personally I wouldn't attempt to fix it. I'd do this: figure out how the Smalltalk Lisp operators work, then write some Common Lisp macros to walk an existing known-good Prolog-in-Lisp and render it in Smalltalk. Worth a try...