Prolog GNU-大学运营商?解释它
-
29-09-2019 - |
题
因此,大学运营商。我不完全理解。
例如,
foo(PredList,[H|_]) :- bar(PredList,H).
foo(PredList,[_|T]) :- foo(PredList,T),!.
bar([H|_],Item) :- G =.. [H,Item],G.
bar([_|T],Item) :- bar(T,Item).
这在做什么?这看起来看看另一个谓词是否为真。我不明白“ ..”做什么。
没有大学运营商,您将如何重写?
解决方案
大学(=..
)将一个术语分解为选民列表,或从该列表中构造一个术语。尝试:
?- f(x,y) =.. L.
L = [f, x, y].
?- f(x,y,z) =.. [f|Args].
Args = [x, y, z].
?- Term =.. [g,x,y].
Term = g(x, y).
bar
似乎在调用每个谓词 PredList
在 Item
, , 和 foo
回溯 Item
s。 (使用变量作为谓词是不可移植的; call
谓词应该是首选。)
编辑: :Kaarel是对的,可以将Univ取代 functor/3
和 arg/3
, , 如下:
bar([H|_],Item) :-
functor(Goal,H,1), % unifies Goal with H(_)
arg(1,Goal,Item), % unifies first argument of Goal with Item
call(Goal). % use this for portability
其他提示
我认为最合适的重写是:
bar( [H|_], Item ) :- call(H, Item).
call/n
尚不是ISO核心标准的一部分,但它们可能会在不久的将来(*)。许多序言系统已经支持它们。
有一个原因 call/n
应该优先于简单 (=..)/2
和 functor/3
+ arg/3
解决方案。这 call/n
解决方案能够处理封闭(**)。
与简单 (=..)/2
和 functor/3
+ arg/3
解决方案可以调用 bar/2
仅在第一个列表参数中具有原子。例如:
p1(1).
p2(2).
?- bar( [p1, p2], 1 ).
Yes
?- bar( [p1, p2], 2 ).
Yes
?- bar( [p1, p2], 3 ).
No
关闭我们不仅限于原子,我们可能会节省一些编码工作。例如,我们可以直接执行以下操作:
?- bar( [=(1), =(2)], 1 ).
Yes
?- bar( [=(1), =(2)], 2 ).
Yes
?- bar( [=(1), =(2)], 3 ).
No
最好的祝福
(*)
技术折叠草案2
http://www.complang.tuwien.ac.at/ulrich/iso-prolog/dtc2#call
(**)
谁发明了? call/n
谓词
http://www.complang.tuwien.ac.at/ulrich/prolog-inedit/naish.html
不隶属于 StackOverflow