# Basic logic problem in Prolog

I thought it would be a good idea to take some easy to solve (by hand) problems and model them in Prolog for practice. Here is a problem I modeled in Prolog:

A messy kid wrote a multiplication problem.

1. Alice saw 100 x 6.
2. Bob saw 101 x 6.
3. Dan saw 102 x 9.

Each one only misread one digit. What is the real solution to the problem?

It proved to be (much) trickier to model than solve by hand, but here is what I came up with:

%- Read person saw number at position.
saw(alice, 1, 0).
saw(alice, 0, 1).
saw(alice, 0, 2).
saw(alice, 6, 3).

saw(bob, 1, 0).
saw(bob, 0, 1).
saw(bob, 1, 2).
saw(bob, 6, 3).

saw(dan, 1, 0).
saw(dan, 0, 1).
saw(dan, 2, 2).
saw(dan, 9, 3).

%- Consider the case when two people see one number and one person saw a anoth-
% er number. This doesnt actually mean the person "definitely" misread the nu-
% mber, but if the problem can be solved it measns they definitely did.
saw(Person, Digit, Position),
saw(Q, D, Position), Q \== Person, D \== Digit,
saw(R, D, Position), R \== Q, R \== Person.

saw(Person, Digit, Position),
not((definitely_misread(Person, D, P), D \== Digit, P \== Position)),
(saw(Q, D1, Position), Q \== Person, D1 \== Digit),
(saw(R, D2, Position), R \== Q, R \== Person, D2 \== Digit).

%- Resolve if the question is actually the correct digit at that position.
correct(Digit, Position) :-
(saw(alice, Digit, Position), not(misread(alice, Digit, Position)));
(saw(bob, Digit, Position), not(misread(bob, Digit, Position)));
(saw(dan, Digit, Position), not(misread(dan, Digit, Position))).


And thus one can get the correct solutions by calling correct (although, it displays some digit position pairings multiple times):

?- correct(D, P).
D = 1,
P = 0 ;
D = 0,
P = 1 ;
D = 6,
P = 3 ;
D = 1,
P = 0 ;
D = 0,
P = 1 ;
D = 6,
P = 3 ;
D = 1,
P = 0 ;
D = 0,
P = 1 ;
D = P, P = 2 ;
false.