如何解决如何在Prolog中返回列表?
| 假设我有以下事实:parent(bob,sam). %bob is sam\'s parent
parent(sara,sam). %sara is sam\'s parent
我想找出谁是山姆的父母,并以清单的形式将其归还:
list_parents(P,L) :- findall(Parent,parent(Parent,P),L).
我现在想做的是问同样的问题,但只有一个这样的论点:
findParents(sam).
我试过了:
findParents(Name) :- list_parents(Name,L).
但是Prolog这样只回答了\"True\"
。
解决方法
与序言有关的是,它与大多数语言略有不同(轻描淡写,如果每种语言都有):
所有变量都是本地范围的。
变量值一旦绑定(统一)就不变,除非回溯将其绑定。
谓词不返回常规意义上的值。他们要么成功要么失败。
为了从测试谓词中获取价值,您可以对谓词进行评估,并从谓词中传递一些东西。传递一个变量或绑定值都没有关系:被调用的谓词将成功,或者如果调用者将其与您传递的内容统一在一起则赋值。如果您传递了一个变量,并且被调用谓词将其与一个非变量值统一起来,则您的变量将绑定到该值。考虑一下(某种程度上),就好像您有一种过程语言,其中每个函数都返回bool,并且所有参数值都通过引用传递。
您尝试过的工作:
findParents(Name) :- list_parents(Name,L).
变量L与findall/3
返回的列表统一(绑定)。然后它超出了范围。
如果您想对返回的(绑定)值进行实际操作,则需要在其作用域内对其进行处理,或者将其与调用谓词的内容统一,从而将其传递给调用堆栈。或者,您可以将其声明为事实数据库并保存以备后用。
序言的工作方式是,用于启动\“ program \”的根谓词根据数据库中的谓词定义了搜索树。然后Prolog的\“ engine \”对树进行深度优先,从左到右的搜索。当引擎到达您定义的搜索树的叶节点时,您的谓词成功。回溯谓词会使引擎在搜索树中寻找下一个解决方案。
结果,您想要以持久方式完成的任何事情都必须作为序言“引擎”评估谓词的副作用而发生。例如,print()
总是成功一次(当您输入框时)...并且作为副作用打印您要打印的内容。回溯到打印文件不会“撤消”打印文件,但是print()
不会再次成功。
,如果只希望用户看到列表,则可以打印列表
就像是:
findParents(Name):-
list_parents(Name,L),print(L).
但这并没有完全恢复。请记住,序言中没有功能,因此没有“返回值”。您可以通过编写foo(Args,Return)来模拟函数,但始终可以像foo(X,sam)一样调用它-有时它将提供您想要的内容,有时不会,有时会崩溃。
,func库为SWI-Prolog中具有返回值的函数提供了一种语法。在此示例中,您可以通过写writeln(list_parents $ sam)
来打印sam
的所有父母:
:- initialization(main).
:- use_module(library(func)).
main :- writeln(list_parents $ sam).
list_parents(P,L) :- findall(Parent,parent(Parent,P),L).
parent(bob,sam). %bob is sam\'s parent
parent(sara,sam). %sara is sam\'s parent
同样,您可以定义具有多个参数的函数,如下所示:
% return a item at an index in a list.
nth0((Index,List),ToReturn) :-
nth0(Index,List,ToReturn).
...然后像这样使用它:
example :-
ListIndex = (nth0 $(0,[1,2,3,4])),%returns 1,which is the first item in this list
writeln(ListIndex).
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。