In this article, the author solves a logic puzzle with Prolog. The puzzle is as follows:
Mary, Dan, Lisa, and Colin took a test with 10 True/False questions. Here are their answers and scores:
| Name | Answers | Score |
|---|---|---|
| Mary | FFTFTFFTFF |
7/10 |
| Dan | FTTTFTFTTT |
5/10 |
| Lisa | FTTTFFFTFT |
3/10 |
| Colin | FFTTTFFTTT |
?/10 |
Your objective is to find out Colin's score.
The author proceeded to write some Prolog code to solve this.
I don't know Prolog but I was quite fascinated with some of the ideas presented (I can't judge the brilliance of the ideas because of my ignorance; maybe these are standard in the Prolog world).
For example, here's a recursive definition for score which I'll attempt to interpret:
% The student's test score
% score(student answers, answer key, score)
score([], [], 0).
score([A|As], [A|Ks], N) :-
N #= M + 1, score(As, Ks, M).
score([A|As], [K|Ks], N) :-
dif(A, K), score(As, Ks, N).
I think the three terms score(...) set up some sort of predicates that Prolog can evaluate to true or false, and the first one is the base case: for an empty answer sheet and for a test with no questions, the score is 0.
Then, this line:
score([A|As], [A|Ks], N) :-
N #= M + 1, score(As, Ks, M).
Earlier in the article, the author says that you can write “A #= B + 1 to say "A is 1 more than B"”.
And the code [A|As], [A|Ks] seems to do some kind of pattern matching on the first element of both lists when they are the same.
So, this seems to be saying that score([A|As], [K|Ks], N) will be true if:
N is 1 more than M; andscore(As, Ks, M) is true.Similarly,
score([A|As], [K|Ks], N) :-
dif(A, K), score(As, Ks, N).
seems to be saying that the predicate score([A|As], [K|Ks], N) will be true if:
A is different from B; andscore(As, Ks, N) is true.