
Logic Puzzles with Prolog (2017) - YeGoblynQueenne
https://www.metalevel.at/prolog/puzzles
======
umvi
Prolog really blows my mind.

I recently released a match-burning logic puzzle app[1] based on a mensa
calendar puzzle I saw and it took me a while to develop an (imperfect) solver
algorithm in C#. Someone then told me that the general class of these puzzles
is called "Thermometer Puzzles" and that there are a ton of Prolog-based
solvers[2] out there.

This class of puzzle is not mentioned in the article, but I'm truly amazed at
how versatile Prolog is at solving logic puzzles with so little code. I'm
guessing the Prolog compiler is super complex compared to, say, a C compiler
to be able to give developers that much power.

[1]
[https://play.google.com/store/apps/details?id=com.umvirate.e...](https://play.google.com/store/apps/details?id=com.umvirate.embergram)

[2]
[https://github.com/zettca/ist.lp.thermometers/blob/master/th...](https://github.com/zettca/ist.lp.thermometers/blob/master/thermometers.pl)

~~~
DannyB2
If you want to know how to build a Prolog . . .

When I learned Common Lisp, I devoured the available textbooks in 1989 and for
a few years after. A book from the early 1990s is: Paradigms of AI
Programming: Case Studies in Common Lisp. By Peter Norvig (now employed by
Google)

The book first teaches you Common Lisp, which isn't that difficult to pick up.
But that itself is a transformative experience.

Then the book shows you how to build a number of amazing things using Common
Lisp. It starts IIRC, with pattern matching. Term rewriting. Unification
matching.

Then you proceed to build a few things like:

1\. A program that solves high school style algebra word problems.

2\. A "prolog" (but expressed in Lisp syntax) that is a "hair's breadth" (in
the author's words) from real prolog.

This book was mind blowing. A revelation. Insightful.

Learning Lisp (even from other textbooks before the one I mention here) was a
transformative experience. But this single book stands out in providing so
many amazing ideas expressed in Lisp.

Other Lisp texts I had read taught me things like playing two-player zero sum
games (TicTacToe, Checkers, Reversi). I abstracted the technique to have a
single re-usable AI engine implementing the Minimax with Alpha-Beta pruning,
and then different layers on top of that which implemented different games (as
listed earlier) by defining a game board, move generator and board scoring
function.

One Lisp textbook I had from the late 1980s showed a program to plan movements
of a robot arm to manipulate blocks according to english like commands.

All of these amazingly sophisticated things take up very little Lisp code.
Often only a few pages.

The journey of learning Lisp, with a really good textbook, is an amazing
learning experience. Learning Lisp will change the way you think about code
for the rest of your entire life. I can confidently say that having learned
Lisp starting in about 1986 and dabbling with it through 1993. The initial
learning comes quickly. But you will play with this new toy for a long time.

Another book (The Elements of Artificial Intelligence Using Common Lisp)
introduced me to the A-star search. I've used that technique, in Java, to
build a "solver" for a game sometimes called "Traffic Jam" or "Unblock Me".

~~~
dhconnelly
What a great book! I translated most of the Lisp code into Python a while
back. You can find it on Github: [https://github.com/dhconnelly/paip-
python](https://github.com/dhconnelly/paip-python)

The logic programming bits in particular (the core of the Prolog interpreter)
can be read in a maybe-nicer way here: [http://dhconnelly.com/paip-
python/docs/paip/logic.html](http://dhconnelly.com/paip-
python/docs/paip/logic.html)

------
girzel
I've been reading this book to get an overview of Prolog:
[http://www.learnprolognow.org/](http://www.learnprolognow.org/). It's much
better than most of the tutorials I found out there, and provides a very
gentle, very thorough introduction to what might be some fairly alien
programming ideas (at least, they were to me).

I'm still chewing over the fact that a Prolog term looks exactly the same
whether it's in a knowledge base (ie it's true), or whether you're feeding it
to the prompt (ie you're asking if it's true or not). Maybe I'm just spooking
myself out, but the identity of facts and queries feels reminiscent of Lisp's
homoiconicity between code and data.

~~~
tom_mellior
> Maybe I'm just spooking myself out, but the identity of facts and queries
> feels reminiscent of Lisp's homoiconicity between code and data.

Wait until you discover Prolog's homoiconicity ;-)

You can treat Prolog terms as data and also add them to the database as code
and call the resulting goals like all others:

    
    
        ?- MyFact = f(x), assert(MyFact).
        MyFact = f(x).
    
        ?- f(A).
        A = x.
    
        ?- MyRule = (f(g(X)) :- f(X)), assert(MyRule).
        MyRule = (f(g(X)):-f(X)).
    
        ?- f(A).
        A = x ;
        A = g(x) ;
        A = g(g(x)) .
    

That is, asserting the "data" "f(x)" and "f(g(X)) :- f(X)" behaves the same as
putting the identical-looking "code" in a source file.

You can also query the code and get back it back as identical-looking "data":

    
    
        ?- Head = f(_), clause(Head, Body).
        Head = f(x),
        Body = true ;
        Head = f(g(_G1014)),
        Body = f(_G1014).
    

(The first of these represents the fact "f(X)." as "f(X) :- true." to make
things more uniform internally.)

As for what this is good for, you can use it to write your own
metainterpreters that execute Prolog code in the normal way, or in some
nonstandard or enhanced way, recording tracing data for example. There is a
good writeup on metainterpreters at
[https://www.metalevel.at/acomip/](https://www.metalevel.at/acomip/)

------
ThePadawan
> Example 2: A says: "I am a knave, but B isn't."

> (...code here...)

>

> Thus, in this example, both A and B are knaves.

Under the premise that knaves always lie, if A is a knave, then their
statement "I am a knave" must have been a lie, thus this solution cannot be
correct.

~~~
timon999
A isn't making two statements. The (single) statement "I am a knave, but B
isn't." is a conjunction that is false because it's right hand side is false.

~~~
ThePadawan
Thank you for the clarification!

Still, makes me think that this could have been stated clearly instead of
relying on the reader interpreting it in that manner.

~~~
carapace
I find the biggest challenge with these kinds of logic puzzles is in
translating from the English (or other human language) into symbolic logic.
It's not well-documented and bug-prone. Er, (not well-documented) /\ bug-
prone. Not (not (well-documented /\ bug-prone)).

Like the famous Two Guardians riddle: one always lies, the other always tells
the truth, you get one question, etc. There's a translation that starts "You
have a wire and a NOT gate..." in which the puzzle becomes blindingly obvious.
(Details omitted so as not to spoil the puzzle for anyone.)

Once you have developed a facility with the special jargon of logic puzzles
and know Prolog, I've found that, while some puzzles become boring (
[https://swish.swi-prolog.org/p/Boring%20Sudoku.swinb](https://swish.swi-
prolog.org/p/Boring%20Sudoku.swinb) ), many are still interesting as an art
form, much like _le_ demo scene you could imaging puzzle scene and not be too
far off metaphorically.

