I've got a simple puzzle: We've got 2 people, Zod and Jenk. Each of them is either Truthful and always making true statements, or Lying and always making false statements. Zod says: "We are both truthful". Jenk says: "At lease one of us is lying".
The solution is that Zod is lying and Jenk is truthful.
I'm trying to solve it using Prolog but somehow it comes to a conclusion that both are Truthful. Here's the program:
% Define the possible states for each person
state(zod, truthful).
state(zod, lying).
state(jenk, truthful).
state(jenk, lying).
% Zod says: "We are both truthful".
zod_statement :- state(zod, truthful), state(jenk, truthful).
% Jenk says: "At least one of us is lying".
jenk_statement :- state(zod, lying); state(jenk, lying).
% Check if a person's statement is true based on their state
statement(zod) :-
state(zod, truthful), zod_statement;
state(zod, lying), \+ zod_statement.
statement(jenk) :-
state(jenk, truthful), jenk_statement;
state(jenk, lying), \+ jenk_statement.
% The solution must satisfy both statements
solution(ZodState, JenkState) :-
state(zod, ZodState),
state(jenk, JenkState),
statement(zod),
statement(jenk).
If I comment out state(zod, truthful)
and leave the only possibility for Zod as lying
it works, but if it's got both options for Zod it comes back with JenkState = ZodState, ZodState = truthful
which is incorrect.
What's wrong with my code?
Can reify this, so that the person's variable is whether they are telling the truth.
truthful(true).
truthful(false).
zod_jenk(Z, J) :-
person_truthful(zod, Z, J),
% Only this Jenk rule is actually needed
person_truthful(jenk, J, Z),
% Ensuring that Z and J are ground
truthful(Z),
truthful(J).
% Zod is telling the truth if Jenk is telling the truth
person_truthful(zod, true, true).
% If Zod is lying, don't know about Jenk
person_truthful(zod, false, _J).
% If Jenk is truthful then Zod must be lying (to be the "at least 1")
person_truthful(jenk, true, false).
% If Jenk is lying, then at least one of them is lying - contradiction
Result in swi-prolog:
?- zod_jenk(Z, J).
Z = false,
J = true.
The Zod rule isn't even needed.