Dear All,
Another challenging conversion example. It will put
properties of a library(lambda) to the test:
1) Aliasing of ground variables across multiple invocations
of a lambda expression.
2) Alpha conversion of bound and local variables for a
single invocation of a lambda expression.
I am now using ('|')/2 instead of (\)/2 for global-by-default,
since this would clash with (\)/1 of local-by-default, and one
could not load both libraries. I have adapted the conversion
routine so that it yields ('|')/2 instead of (\)/2 for
global-by-default. The challenge is the fixpoint combinator.
So in mathematical lambda expressions we would have:
/* currys fixpoint combinator */
Y = F\call(X\call(F,call(X,X)),X\call(F,call(X,X))).
/* checking that something is a natural number */
Nat = F\N\H^(N=0;N>0,H is N-1,call(F,H)).
/* computing the factorial */
Fact = F\N\M\H^J^(N=0,M is 1;N>0,H is N-1,call(F,H,J),M is N*J).
I guess property 1) is used to keep and pass around F in the
Y combinator. Further I guess property 2) is used in Nat and
Fact to avoid clashes, when F is reduced.
Here are the results:
local-by-default (output massaged):
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 6.3.15)
Copyright (c) 1990-2013 University of Amsterdam, VU Amsterdam
?- Y = F\call(X\call(F,call(X,X)),X\call(F,call(X,X))),
convert(Y,R).
R = \F^call([F]+\X^call(F, call(X, X)),
[F]+\X^call(F, call(X, X))).
?- Nat = F\N\H^(N=0;N>0,H is N-1,call(F,H)), convert(Nat,R).
R = \F^ ([F]+\N^ (N=0;N>0, H is N-1, call(F, H))).
?- Fact = F\N\M\H^J^(N=0,M is 1;N>0,H is N-1,call(F,H,J),
M is N*J), convert(Fact,R).
R = \F^ ([F]+\N^ ([N, F]+\M^ (N=0, M is 1;N>0, ...is...,
..., ...))).
?- Y = \F^call([F]+\X^call(F, call(X, X)), [F]+\X^call(F,
call(X, X))), Nat = \F^ ([F]+\N^ (N=0;N>0, H is N-1, call(F,
H))), call(Y,Nat,3).
true.
?- Y = \F^call([F]+\X^call(F, call(X, X)), [F]+\X^call(F,
call(X, X))), Nat = \F^ ([F]+\N^ (N=0;N>0, H is N-1, call(F,
H))), call(Y,Nat,-1).
false.
?- Y = \F^call([F]+\X^call(F, call(X, X)), [F]+\X^call(F,
call(X, X))), Fact = \F^ ([F]+\N^ ([N, F]+\M^ (N=0,M is 1;
N>0,H is N-1,call(F,H,J),M is N*J))), call(Y,Fact,10,R).
R = 3628800.
global-by-default (output massaged):
Jekejeke Prolog, Development Environment 0.9.9
(c) 1985-2013, XLOG Technologies GmbH, Switzerland
?- Y = F\call(X\call(F,call(X,X)),X\call(F,call(X,X))),
convert(Y,R).
R = (F|X^call((X|call(F,call(X,X))),(X|call(F,call(X,X)))))
?- Nat = F\N\H^(N=0;N>0,H is N-1,call(F,H)), convert(Nat,R).
R = (F|H^N^(N|H^(N=0;N>0,H is N-1,call(F,H))))
?- Fact = F\N\M\H^J^(N=0,M is 1;N>0,H is N-1,call(F,H,J),M
is N*J), convert(Fact,R).
R = (F|J^H^M^N^(N|J^H^M^(M|J^H^(N=0,M is 1;N>0,H is
N-1,call(F,H,J),M is N*J))))
?- Y = (F|X^call((X|call(F,call(X,X))),(X|call(F,call(X,X))))),
Nat = (F|H^N^(N|H^(N=0;N>0,H is N-1,call(F,H)))),
call(Y,Nat,3).
Yes
?- Y = (F|X^call((X|call(F,call(X,X))),(X|call(F,call(X,X))))),
Nat = (F|H^N^(N|H^(N=0;N>0,H is N-1,call(F,H)))),
call(Y,Nat,-1).
No
?- Y = (F|X^call((X|call(F,call(X,X))),(X|call(F,call(X,X))))),
Fact = (F|J^H^M^N^(N|J^H^M^(M|J^H^(N=0,M is 1;N>0,H is
N-1,call(F,H,J),M is N*J)))), call(Y,Fact,10,R).
R = 3628800
Both local-by-default and global-by-default pass the test!
The curry fixpoint operator works astonishing well, I guess it
has to do that the inner call/2 is not evaluated call-by-value
in the Prolog setting of call/n.
Interestingly the curry fixpoint combinator based on call/n is
also polymorphic, works for an 1-ary predicate and for a 2-ary
predicate here. Didn't expect that.
Bye
Jan Burse schrieb: