不确定为什么代码片段工作/它与逻辑谜语做什么

时间:2014-11-17 10:44:55

标签: prolog zebra-puzzle

我正在查看一些序言,并偶然发现http://www.anselm.edu/internet/compsci/faculty_staff/mmalita/HOMEPAGE/logic/bufalo.txt

first_names([keith,libby,margo,nora,otto]).
last_names([fell,grant,hall,ivey,jule]).
ages([2,3,4,5,6]).

start(Sol):- first_names(F),last_names(L),ages(A),
         Sol=[[F1,L1,A1],[F2,L2,A2],[F3,L3,A3],[F4,L4,A4],[F5,L5,A5]],
                F=[F1,F2,F3,F4,F5],             % if order is not important!
        member([libby,jule,_],Sol), % 1
        set_equal([L1,L2,L3,L4,L5],L),  % write correspondence
        set_equal([A1,A2,A3,A4,A5],A),
                member([keith,_,AgeK],Sol),     % 2
        member([_,ivey,AgeI],Sol),AgeK is AgeI+1,
        member([nora,_,AgeN],Sol),AgeI is AgeN+1,
        member([margo,_,AgeM],Sol),
        member([_,fell,AgeF],Sol),AgeF is 3+AgeM,
        member([otto,_,AgeO],Sol),member([_,hall,AgeH],Sol).

在这个代码示例中,我对它是如何工作有一个大概的了解,但我真的不确定具体细节

我理解将提示定义为原子列表,第一个字段是名字,第二个字段是姓氏,第三个字段是年龄,下划线显示缺少的信息。但是我不确定为什么要将成员调用到Sol数组上。不确定它在这种情况下的作用

此外,我并不真正理解set_equal的目的和此代码中的F =。似乎它设置了三个根本没有引用的变量?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我已经从你提供的链接下载了代码,用SWI-Prolog进行测试:bibmm.pl中存在一些语法问题,至少set_equal / 3必须改为:

set_equal([H|T],R):- member(H,R),select(H,R,Rez),set_equal(T,Rez).

更正后,它确实产生:

?- start(X).
X = [[keith, fell, 5], [libby, jule, 6], [margo, grant, 2], [nora, hall, 3], [otto, ivey, 4]] ;
X = [[keith, fell, 6], [libby, jule, 2], [margo, grant, 3], [nora, hall, 4], [otto, ivey, 5]] ;
X = [[keith, fell, 5], [libby, jule, 6], [margo, hall, 2], [nora, grant, 3], [otto, ivey, 4]] ;
X = [[keith, fell, 6], [libby, jule, 2], [margo, hall, 3], [nora, grant, 4], [otto, ivey, 5]] ;
X = [[keith, grant, 4], [libby, jule, 5], [margo, ivey, 3], [nora, hall, 2], [otto, fell, 6]] ;
X = [[keith, hall, 4], [libby, jule, 5], [margo, ivey, 3], [nora, grant, 2], [otto, fell, 6]] ;
false.

现在,

  

为什么使用成员调用Sol数组

member / 2会将插槽绑定到可接受的值,因此部分指定的行将获得临时值,而Prolog的回溯将提供对适当排列的搜索,如bibmm.pl中所述,由set_equal /生成2。

关于F = [...],我认为这只是作者的美学选择,因为它在开始/ 1程序中不再使用。可写和

start(Sol):- first_names([F1,F2,F3,F4,F5]),last_names(L),ages(A),
...

编辑我没有注意到,但是有一个错误,即缺少最后一个约束。添加后

...
member([otto,_,AgeO],Sol),member([_,hall,AgeH],Sol),
AgeO is AgeH * 2.

结果可以说更好

?- start(X).
X = [[keith, fell, 5], [libby, jule, 6], [margo, hall, 2], [nora, grant, 3], [otto, ivey, 4]]