Prolog GNU - Univ 运算符?其解释

发布于 2024-09-30 21:35:54 字数 286 浏览 1 评论 0原文

所以univ操作员。我不太明白。

例如:

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).

这是做什么的?这会检查另一个谓词是否为真。我不明白“..”的作用。

如果没有 univ 运算符,您将如何重写它?

So the univ operator. I don't exactly understand it.

For example this:

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).

What is this doing? This looks to see if another predicate is true. I don't understand what the ".." does.

How would you rewrite this without the univ operator?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

碍人泪离人颜 2024-10-07 21:35:54

Univ (=..) 将术语分解为成分列表,或从这样的列表构造术语。尝试:

?- 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 似乎在 Item 上调用 PredList 中的每个谓词,并使用 fooItem 上回溯 。 (使用变量作为谓词是不可移植的;应首选 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

Univ (=..) breaks up a term into a list of constituents, or constructs a term from such a list. Try:

?- 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 seems to call each predicate in PredList on Item, with foo backtracking over the Items. (Using a variable as a predicate is not portable; the call predicate should be preferred.)

Edit: Kaarel is right, univ can be replaced by functor/3 and arg/3, as follows:

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
早茶月光 2024-10-07 21:35:54

我认为最合适的重写是:

 bar( [H|_], Item ) :- call(H, Item).

call/n 尚未成为 ISO 核心标准的一部分,但它们可能会在不久的将来 (*)。许多 Prolog 系统已经支持它们。

为什么 call/n 应该优于简单的 (=..)/2functor/3 + arg 是有一个原因的/3 解决方案。 call/n 解决方案能够处理闭包 (**)。

通过简单的 (=..)/2functor/3 + arg/3 解决方案,我们可以调用 bar/2< /code> 仅限第一个列表参数中的原子。例如:

 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

The most appropriate rewrite in my opinion would be:

 bar( [H|_], Item ) :- call(H, Item).

call/n are not yet part of the ISO core standard, but they might become in the near future (*). A lot of Prolog systems already support them.

There is one reason why call/n should be preferred over simple (=..)/2 and functor/3 + arg/3 solutions. The call/n solution is capable to handle closures (**).

With the simple (=..)/2 and functor/3 + arg/3 solution one can invoke bar/2 only with atoms in the first list argument. For example:

 p1(1).
 p2(2).
 ?- bar( [p1, p2], 1 ).
 Yes
 ?- bar( [p1, p2], 2 ).
 Yes
 ?- bar( [p1, p2], 3 ).
 No

With closures we are not restricted to atoms, and we might save some coding effort. For example we can do the following directly:

 ?- bar( [=(1), =(2)], 1 ).
 Yes
 ?- bar( [=(1), =(2)], 2 ).
 Yes
 ?- bar( [=(1), =(2)], 3 ).
 No

Best Regards

(*)
Draft Technical Corrigendum 2
http://www.complang.tuwien.ac.at/ulrich/iso-prolog/dtc2#call

(**)
Who Invented It?: call/n Predicates
http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/naish.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文