Lambdas in Prolog?
Asked Answered
P

2

5

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).
Precocity answered 24/1, 2021 at 21:1 Comment(5)
See this for an intro that should answer most of your questions.Fortunna
red it before .. it is just disconnected snippets ... doesnt help muchPrecocity
Those lambda expression are not really the lambda expressions from functional programming. In particular you cannot make "closures" out of them (because Prolog has no contexts over which one could close, as it has no "local variables"). You cannot store them. They are actually "shims" around goals that need to be rewritten to "lambda-less Prolog" by "creating appropriate predicates" to call.Quadruped
The syntax above is this package. For SWI-Prolog and Logtalk there is an alternative syntax yall. Maybe it's clearer? It took me some time to get it.Quadruped
@DavidTonhofer: Note, that the alternative you cite does not type. So type checkers (like the one in SWI) cannot be used with it.Fortunna
F
6

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.

Fortunna answered 24/1, 2021 at 22:1 Comment(1)
so in general to apply lambda fun we use call()Precocity
P
1

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

Also, Logtalk supports lambdas since 2009.

Philbrick answered 4/2, 2022 at 6:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.