This is a very simple puzzle I found on the web, I don't find any solution on internet. The rules are simples:
We know that: - M.Meatman's son is baker - M.Baker do the same job than M.Carpenter's son
I implemented this predicates:
% swipl prolog
% M.Meatman's son is baker
% M. Baker do job of M. Carpenter's son
% jobs
job(baker).
job(meatman).
job(carpenter).
% fathers
artisan(fatherbaker).
artisan(fathercarpenter).
artisan(fathermeatman).
% sons
artisan(sonbaker).
artisan(soncarpenter).
artisan(sonmeatman).
% some links
father(fatherbaker, sonbaker).
father(fathermeatman, sonmeatman).
father(fathercarpenter, soncarpenter).
son(S, F) :- father(F, S).
same_name(fathercarpenter, soncarpenter, carpenter).
same_name(fathermeatman, sonmeatman, meatman).
same_name(fatherbaker, sonbaker, baker).
% rules:
do_job(Artisan, Job) :-
Artisan==sonmeatman,!,
artisan(Artisan),
job(Job),
Job=baker. % M.Meatman's son is baker (rule 1)
do_job(Artisan, Job) :-
Artisan==fatherbaker,!,
artisan(Artisan),
job(Job),
do_job(soncarpenter, Job). % M.Baker do M.Carpenter's son job
% not relevant...
%do_job(Artisan, Job) :-
% Artisan == soncarpenter,!,
% job(Job),
% artisan(Artisan),
% do_job(fatherbaker, Job). % rule 2 inverted
% checking if father job is not the same and name are not forgotten
do_job(Artisan, Job) :-
artisan(Artisan),
job(Job),
father(Father, Artisan),
do_job(Father, JobFather),
Job \== JobFather,
not(same_name(Artisan,_,Job)).
% checking if son job is not the same and name are not forgotten
do_job(Artisan, Job) :-
artisan(Artisan),
job(Job),
son(Artisan, Son),
do_job(Son, JobSon),
Job \== JobSon,
not(same_name(_, Artisan, Job)).
Then I try:
swipl
?- do_job(sonmeatman, X).
X = baker ;
false.
?- do_job(fatherbaker, X).
false.
Can you please tell me where I'm wrong.
You're overengineering, and reifying too much of the problem (a typical Prolog beginner's error). What you need to write is a six-argument predicate
jobs(BakerSrJob, BakerJrJob,
CarpenterSrJob, CarpenterJrJob,
MeatmanSrJob, MeatmanJrJob) :-
...
and in the body, constraints on those variables. E.g.
member(BakerJrJob, [carpenter, meatman])
expresses that Baker jr. is either a carpenter or a meatman, and
BakerJrJob \= BakerSrJob
expresses that father and son Baker have different jobs. A couple of these member
calls and \=
constraints should be enough to encode all the knowledge necessary. (Just hardcode the identity of the persons in the variable name, instead of representing and inspecting the names as atoms. Don't try to write a generic puzzle solver if you're just starting out.)