因此,大学运营商。我不完全理解。

例如,

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 似乎在调用每个谓词 PredListItem, , 和 foo 回溯 Items。 (使用变量作为谓词是不可移植的; call 谓词应该是首选。)

编辑: :Kaarel是对的,可以将Univ取代 functor/3arg/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 应该优先于简单 (=..)/2functor/3 + arg/3 解决方案。这 call/n 解决方案能够处理封闭(**)。

与简单 (=..)/2functor/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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top