Prolog
Bill Clementson writes about Allegro Prolog, a Prolog embedded in Allegro CL, by way of solving Einstein's riddle.
Here's the solution to Einstein's riddle in SWI Prolog, a straight port of Bill Clementson's code.
next_to(X, Y, List) :- iright(X, Y, List). next_to(X, Y, List) :- iright(Y, X, List). iright(L, R, [L | [R | _]]). iright(L, R, [_ | Rest]) :- iright(L, R, Rest). einstein(Houses, Fish_Owner) :- =(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), next_to([house, _, _, dunhill, _, _], [house, _, horse, _, _, _], Houses), member([house, _, _, _, milk, _], Houses), next_to([house, _, _, marlboro, _, _], [house, _, cat, _, _, _], Houses), next_to([house, _, _, marlboro, _, _], [house, _, _, _, water, _], Houses), member([house, _, _, winfield, beer, _], Houses), member([house, german, _, rothmans, _, _], Houses), next_to([house, norwegian, _, _, _, _], [house, _, _, _, _, blue], Houses), member([house, Fish_Owner, fish, _, _, _], Houses).
Here's a run through the Prolog REPL. I pretty-printed the output by hand so as to not run off the right side of the screen.
1 ?- consult('einstein').
% /tmp/einstein compiled 0.00 sec, 4,740 bytes
Yes
2 ?- einstein(Houses, Fish_Owner).
Houses = [[house, norwegian, cat, dunhill, water, yellow],
[house, dane, horse, marlboro, tea, blue],
[house, brit, bird, pallmall, milk, red],
[house, german, fish, rothmans, coffee|...],
[house, swede, dog, winfield|...]]
Fish_Owner = german
Yes
3 ?-
The German owns the fish!
So why does one program in an embedded Prolog, as compared to doing so in "pure" Prolog? For starters, there's the "it looks alien" thing: if Common Lisp or Smalltalk are strange to the "average hacker" steeped in Algol-family languages, Prolog will require even more rewiring of the mind. Programming Prolog embedded in a host language allows the programmer to use Prolog for what it is good at, without him attempting to also write a GUI or serve content over HTTP in Prolog.
A capable host language like Common Lisp can implement Prolog in itself and provide seamless bidirectional interfacing, make Prolog facts and rules persistent in "native" format, operate on the tuples in an SQL database directly as if they are Prolog facts without a whole lot of extra infrastructure, compile to native code, etc.
Lesser languages make do with C/C++ interfaces.