Prolog GNU - Univ operator? Explanation of it

本秂侑毒 提交于 2019-11-27 21:26:58

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
j4n bur53

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!