这是我在网上找到的一个非常简单的难题,我在网上找不到任何解决方案。规则很简单:
- 有6个工匠,M.Baker和他的儿子,M.Carpenter和他的儿子,M.Meatman和他的儿子
- 每个工匠可以是面包师、木匠或肉工
- 儿子和父亲不能做同样的工作
- 姓不能是工作名称(M.Baker 和他的儿子不能是面包师)
我们知道: - M.Meatman 的儿子是面包师 - M.Baker 和 M.Carpenter 的儿子做同样的工作
我实现了这个谓词:
% 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)).
然后我尝试:
swipl
?- do_job(sonmeatman, X).
X = baker ;
false.
?- do_job(fatherbaker, X).
false.
你能告诉我我错在哪里吗?
- 注意:我是 Prolog 的新手。我以前从未使用过这种语言(我是 Golang、Python、C 程序员......)。
- 注2:对不起,我的英语,我刚刚翻译了我的法语例子,也许工作名称或动词不正确......
- 注意 3:我已经尝试过实现斑马拼图,我意识到这比这个更容易解决......奇怪吗?