Есть ли что-то вроде анонимных предикатов в прологе SWI? - PullRequest
3 голосов
/ 19 июня 2019

Могу ли я определить анонимный предикат в SWI Prolog, связать его с переменной и вызвать позже?Как то так:

?- F = {(X, Y) :- Y is 2 * X}, call(F, 2.0, Y).

Ответы [ 3 ]

5 голосов
/ 19 июня 2019

Вот для чего лямбды :

?- use_module(library(lambda)).
true.

?- F_2 = (\X^Y^ ( Y is 2*X )), call(F_2,2.0,Y).
F_2 = \X^4.0^(4.0 is 2*X),
Y = 4.0.
4 голосов
/ 19 июня 2019

Пока что ни одна современная лямбда-библиотека не поддерживает синтаксис Hiord , его не следует путать с синтаксисом Hilog.Но поскольку в ISO Prolog фигурные скобки являются просто функтором '{}' / 1, можно создать свой собственный Hiord с несколькими правилами:

'{}'((Formal :- Body), Actual) :-
   copy_term(Formal-Body, Actual-Call),
   Call.
'{}'((Formal1,Formal2 :- Body), Actual1, Actual2) :-
   copy_term(Formal1-Formal2-Body, Actual1-Actual2-Call),
   Call.
'{}'((Formal1,Formal2,Formal3 :- Body), Actual1, Actual2, Actual3) :-
   copy_term(Formal1-Formal2-Formal3-Body, Actual1-Actual2-Actual3-Call),
   Call.
 Etc..

Вот несколько примеров выполнения:

Jekejeke Prolog 3, Runtime Library 1.3.8 (May 23, 2019)
(c) 1985-2019, XLOG Technologies GmbH, Switzerland

?- F = {X :- write(X), nl}, call(F, hello).
hello

?- F = {X,Y :- Y is X+1}, call(F, 1, R).
R = 2

?- F = {X,Y,Z :- Z is X+Y}, call(F, 1, 2, R).
R = 3

При работе с лямбда-терминами вы увидите, что существует много проблем.Например, существует вопрос о глобальных переменных, которые имеют разные решения.

Кроме того, вас могут заинтересовать лямбда-выражения, которые разрешают карри.Термины Hiord не позволяют каррировать с вышеприведенной реализацией, например, здесь это терпит неудачу:

?- G = {Y :- Y is X+1},  F = {X :- G}, call(F, 1, R).
Error: Undefined or inaccesible predicate {}/1.
    {}/1
    {}/3   

Вам бы больше повезло с библиотекой Jekejeke Prologs ( эксперимент / реферат ), которая также может сделатьcurry:

?- G = Y\(Y is X+1), F = X\G, call(F, 1, R).
R = 2

Лямбда-библиотека SWI-Prologs также может выполнять каррирование:

?- G = [Y]>>(Y is X+1), F = [X]>>G, call(F, 1, R).
R = 2.

И библиотека Ulrich Neumerkels также может выполнять каррирование:

?- G = \Y^(Y is X+1), F = \X^G, call(F, 1, R).
R = 2
4 голосов
/ 19 июня 2019

Кроме того, в SWI-Prolog вы можете использовать библиотеку (yall). Его можно загрузить автоматически, поэтому вам не нужно ничего импортировать:

?- F = [X, Y]>>( Y is 2*X ), call(F, 2.0, Y).
F = [X, 4.0]>>(4.0 is 2*X),
Y = 4.0.

Я думаю , что в общем случае было бы лучше использовать новую переменную для результата вызова лямбды:

?- F = [X, Y]>>( Y is 2*X ), call(F, 2.0, R).
F = [X, Y]>>(Y is 2*X),
R = 4.0.
...