Module Lambda

Jan Burse, created Jun 19. 2019
/**
* Lambda Expressions.
*
* Warranty & Liability
* To the extent permitted by applicable law and unless explicitly
* otherwise agreed upon, XLOG Technologies GmbH makes no warranties
* regarding the provided information. XLOG Technologies GmbH assumes
* no liability that any problems might be solved with the information
* provided by XLOG Technologies GmbH.
*
* Rights & License
* All industrial property rights regarding the information - copyright
* and patent rights in particular - are the sole property of XLOG
* Technologies GmbH. If the company was not the originator of some
* excerpts, XLOG Technologies GmbH has at least obtained the right to
* reproduce, change and translate the information.
*
* Reproduction is restricted to the whole unaltered document. Reproduction
* of the information is only allowed for non-commercial uses. Selling,
* giving away or letting of the execution of the library is prohibited.
* The library can be distributed as part of your applications and libraries
* for execution provided this comment remains unchanged.
*
* Restrictions
* Only to be distributed with programs that add significant and primary
* functionality to the library. Not to be distributed with additional
* software intended to replace any components of the library.
*
* Trademarks
* Jekejeke is a registered trademark of XLOG Technologies GmbH.
*/
/*
* Obtained rights, copyright notice from original:
* https://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl
*
* Author: Ulrich Neumerkel
* E-mail: ulrich@complang.tuwien.ac.at
* Copyright (C): 2009 Ulrich Neumerkel. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY Ulrich Neumerkel ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Ulrich Neumerkel OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* official policies, either expressed or implied, of Ulrich Neumerkel.
*/
:- module(lambda, [
^ /3,^ /4,^ /5,^ /6,^ /7,^ /8,^ /9,
(\)/1,(\)/2,(\)/3,(\)/4,(\)/5,(\)/6,(\)/7,
+\ /2,+\ /3,+\ /4,+\ /5,+\ /6,+\ /7,
op(201,xfx,+\)]).
/** Lambda expressions
This library provides lambda expressions to simplify higher order
programming based on call/N.
Lambda expressions are represented by ordinary Prolog terms.
There are two kinds of lambda expressions:
Free+\X1^X2^ ..^XN^Goal
\X1^X2^ ..^XN^Goal
The second is a shorthand for t+\X1^X2^..^XN^Goal.
Xi are the parameters.
Goal is a goal or continuation. Syntax note: Operators within Goal
require parentheses due to the low precedence of the ^ operator.
Free contains variables that are valid outside the scope of the lambda
expression. They are thus free variables within.
All other variables of Goal are considered local variables. They must
not appear outside the lambda expression. This restriction is
currently not checked. Violations may lead to unexpected bindings.
In the following example the parentheses around X>3 are necessary.
==
?- use_module(library(lambda)).
?- use_module(library(apply)).
?- maplist(\X^(X>3),[4,5,9]).
true.
==
In the following X is a variable that is shared by both instances of
the lambda expression. The second query illustrates the cooperation of
continuations and lambdas. The lambda expression is in this case a
continuation expecting a further argument.
==
?- Xs = [A,B], maplist(X+\Y^dif(X,Y), Xs).
Xs = [A, B],
dif(X, A),
dif(X, B).
?- Xs = [A,B], maplist(X+\dif(X), Xs).
Xs = [A, B],
dif(X, A),
dif(X, B).
==
The following queries are all equivalent. To see this, use
the fact f(x,y).
==
?- call(f,A1,A2).
?- call(\X^f(X),A1,A2).
?- call(\X^Y^f(X,Y), A1,A2).
?- call(\X^(X+\Y^f(X,Y)), A1,A2).
?- call(call(f, A1),A2).
?- call(f(A1),A2).
?- f(A1,A2).
A1 = x,
A2 = y.
==
Further discussions
http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/ISO-Hiord
@tbd Static expansion similar to apply_macros.
@author Ulrich Neumerkel
*/
:- meta_predicate ^(?,0,?),^(?,1,?,?),^(?,2,?,?,?),^(?,3,?,?,?,?),^(?,4,?,?,?,?,?),^(?,5,?,?,?,?,?,?),^(?,6,?,?,?,?,?,?,?).
^(V1, Goal, V1) :-
call(Goal).
^(V1, Goal, V1, V2) :-
call(Goal, V2).
^(V1, Goal, V1, V2, V3) :-
call(Goal, V2, V3).
^(V1, Goal, V1, V2, V3, V4) :-
call(Goal, V2, V3, V4).
^(V1, Goal, V1, V2, V3, V4, V5) :-
call(Goal, V2, V3, V4, V5).
^(V1, Goal, V1, V2, V3, V4, V5, V6) :-
call(Goal, V2, V3, V4, V5, V6).
^(V1, Goal, V1, V2, V3, V4, V5, V6, V7) :-
call(Goal, V2, V3, V4, V5, V6, V7).
:- meta_predicate \(0),\(1,?),\(2,?,?),\(3,?,?,?),\(4,?,?,?,?),\(5,?,?,?,?,?),\(6,?,?,?,?,?,?).
\(FC) :-
copy_term(FC, C),
call(C).
\(FC, V1) :-
copy_term(FC, C),
call(C, V1).
\(FC, V1, V2) :-
copy_term(FC, C),
call(C, V1, V2).
\(FC, V1, V2, V3) :-
copy_term(FC, C),
call(C, V1, V2, V3).
\(FC, V1, V2, V3, V4) :-
copy_term(FC, C),
call(C, V1, V2, V3, V4).
\(FC, V1, V2, V3, V4, V5) :-
copy_term(FC, C),
call(C, V1, V2, V3, V4, V5).
\(FC, V1, V2, V3, V4, V5, V6) :-
copy_term(FC, C),
call(C, V1, V2, V3, V4, V5, V6).
:- meta_predicate +\(?,0),+\(?,1,?),+\(?,2,?,?),+\(?,3,?,?,?),+\(?,4,?,?,?,?),+\(?,5,?,?,?,?,?),+\(?,6,?,?,?,?,?,?).
+\(GV, FC) :-
copy_term(GV+FC, GV+C),
call(C).
+\(GV, FC, V1) :-
copy_term(GV+FC, GV+C),
call(C, V1).
+\(GV, FC, V1, V2) :-
copy_term(GV+FC, GV+C),
call(C, V1, V2).
+\(GV, FC, V1, V2, V3) :-
copy_term(GV+FC, GV+C),
call(C, V1, V2, V3).
+\(GV, FC, V1, V2, V3, V4) :-
copy_term(GV+FC, GV+C),
call(C, V1, V2, V3, V4).
+\(GV, FC, V1, V2, V3, V4, V5) :-
copy_term(GV+FC, GV+C),
call(C, V1, V2, V3, V4, V5).
+\(GV, FC, V1, V2, V3, V4, V5, V6) :-
copy_term(GV+FC, GV+C),
call(C, V1, V2, V3, V4, V5, V6).

Comments