Can I define an anonymous predicate in SWI Prolog, bind it to a variable, and call it later? Something like this:
?- F = {(X, Y) :- Y is 2 * X}, call(F, 2.0, Y).
Can I define an anonymous predicate in SWI Prolog, bind it to a variable, and call it later? Something like this:
?- F = {(X, Y) :- Y is 2 * X}, call(F, 2.0, Y).
Alternatively, in SWI-Prolog, you can use library(yall). It can be autoloaded so you don't need to import anything:
?- F = [X, Y]>>( Y is 2*X ), call(F, 2.0, Y).
F = [X, 4.0]>>(4.0 is 2*X),
Y = 4.0.
I think that in the general case it would be better to use a new variable for the result of calling the lambda:
?- F = [X, Y]>>( Y is 2*X ), call(F, 2.0, R).
F = [X, Y]>>(Y is 2*X),
R = 4.0.
That´s what lambdas are for:
?- 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.
lambda
is a community package that can be installed via ?- pack_install('http://www.swi-prolog.org/download/pack/lambda-*.tgz')
. –
Semite Alternatively, in SWI-Prolog, you can use library(yall). It can be autoloaded so you don't need to import anything:
?- F = [X, Y]>>( Y is 2*X ), call(F, 2.0, Y).
F = [X, 4.0]>>(4.0 is 2*X),
Y = 4.0.
I think that in the general case it would be better to use a new variable for the result of calling the lambda:
?- F = [X, Y]>>( Y is 2*X ), call(F, 2.0, R).
F = [X, Y]>>(Y is 2*X),
R = 4.0.
So far no modern lambda libraries support the Hiord syntax, not to be confused with the Hilog syntax. But since in ISO Prolog curly braces are just the functor '{}'/1, one can do his own Hiord with a few rules:
'{}'((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..
Here are some example runs:
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
When working with lambda terms, you will see that there are many issues. For example there is the question of global variables which has different solutions.
Besides that you might be also interested in lambda terms that allow currying. Hiord terms do not allow currying with the above implementation, for example this here fails:
?- G = {Y :- Y is X+1}, F = {X :- G}, call(F, 1, R).
Error: Undefined or inaccesible predicate {}/1.
{}/1
{}/3
You would have more luck with Jekejeke Prologs library(experiment/abstract) which can also do currying:
?- G = Y\(Y is X+1), F = X\G, call(F, 1, R).
R = 2
SWI-Prologs lambda library can also do currying:
?- G = [Y]>>(Y is X+1), F = [X]>>G, call(F, 1, R).
R = 2.
And Ulrich Neumerkels library can also do currying:
?- G = \Y^(Y is X+1), F = \X^G, call(F, 1, R).
R = 2
© 2022 - 2024 — McMap. All rights reserved.