Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambdas in Prolog?

I normally was able to figure out some usages of Lambda with maplist, but in general have hard time using lambda in prolog. It is probably because it differ from other languages, because of unification.

Here is one of the sticking points : How do you apply declared Lambda expression ? f.e.

LAM = \X^R^(....)

(weird, there have to be space between = and \)

how do you do :

\(LAM)(abc,R)

Another thing which I want to do is to store Lambda expression like a FACT, so that I can query it, but also have it like a lambda function so I can do later binding..f.e. just of the top of my head ... i could think it wrong ..

move = \Obj^From^To(move(Obj,From,To))

instantiate :

?- \(move)(ball,ground,table).

or partially :

?- L2 = \(move)(ball).
?- L3 = \(L2)(table,floor)

query :

?- move(ball,F,T).
like image 824
sten Avatar asked Jan 24 '21 21:01

sten


2 Answers

Let's consider the following lambda term:

?- LAM_2 = \X^R^atom_chars(X,R).
LAM_2 = \X^R^atom_chars(X, R).

The _2 reminds us that two arguments are lacking in order to make this a real goal.

To use it, you have now to supply these two arguments. Either with some meta-predicate like maplist/3 or with call/3.

?- LAM_2 = \X^R^atom_chars(X,R), call(LAM_2, abc, Res).
LAM_2 = \X^R^atom_chars(X, R),
Res = [a, b, c].
?- LAM_2 = \X^R^atom_chars(X,R), maplist(LAM_2, [abc,def], Xss).
LAM_2 = \X^R^atom_chars(X, R),
Xss = [[a, b, c], [d, e, f]].

Note that the variables X and R do not get instantiated!

What is really a bit unusual is that there is no direct scoping of logic variables. They are all global within a clause, so we have to pay attention that these variables are not accidentally reused.

Also note that we could have written for above example, just:

?- LAM_2 = atom_chars, call(LAM_2, abc, Res).
LAM_2 = atom_chars,
Res = [a, b, c].

to store Lambda expression like a FACT, so that I can query it

Why not define the fact directly? There is no way to do this otherwise.

The example you give makes sense, provided we have already the fact defined:

move(ball, table, floor).

Now we can construct the query incrementally by adding arguments by wrapping call/2 around.

?- L1_3 = move, L2_2 = call(move, ball), L3_0 = call(L2_2, table, X), L3_0.
L1_3 = move,
L2_2 = call(move, ball),
L3_0 = call(call(move, ball), table, floor),
X = floor.

However, please note that such partial goals are rarely used today. Also the direct usage of call/N is mostly reserved to meta-predicates like maplist/3.

like image 72
false Avatar answered Oct 01 '22 03:10

false


Besides the SWI-Prolog package that's already been mentioned you might be also interested in λProlog.

Also, Logtalk supports lambdas since 2009.

like image 29
milia Avatar answered Oct 01 '22 04:10

milia