Пролог GNU - оператор Univ?Объяснение этого - PullRequest
13 голосов
/ 09 ноября 2010

Итак, унив оператор.Я не совсем понимаю.

Например, это:

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?

Ответы [ 2 ]

15 голосов
/ 09 ноября 2010

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, кажется, вызывает каждый предикат в PredList на Item с foo возвратом в течение Item с. (Использование переменной в качестве предиката непереносимо; предикат call должен быть предпочтительным.)

Редактировать : Каарел прав, унив можно заменить на 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
2 голосов
/ 14 декабря 2011

На мой взгляд, наиболее подходящей перепиской будет:

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

call/n еще не являются частью основного стандарта ISO, но они могут стать в ближайшем будущем (*).Многие системы Prolog уже поддерживают их.

Есть одна причина, по которой 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

...