不确定为什么代码片段有效/它用逻辑谜语做什么



我正在浏览一些prolog示例,偶然发现了 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= 的用途。似乎它正在设置三个根本没有引用的变量?

感谢您的帮助!

我已经从您提供的链接下载了代码,以使用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=[...],我认为这只是作者的美学选择,因为 F 它在 start/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]]

相关内容

  • 没有找到相关文章

最新更新