]> Repositorios git - scryer-prolog.git/commitdiff
ADDED: library(lambda) by Ulrich Neumerkel.
authorMarkus Triska <[email protected]>
Thu, 25 Feb 2021 21:00:44 +0000 (22:00 +0100)
committerMarkus Triska <[email protected]>
Thu, 25 Feb 2021 21:08:00 +0000 (22:08 +0100)
Source: http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl

More information:

    http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/ISO-Hiord

src/lib/lambda.pl [new file with mode: 0644]

diff --git a/src/lib/lambda.pl b/src/lib/lambda.pl
new file mode 100644 (file)
index 0000000..d59a512
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+    Author:        Ulrich Neumerkel
+    E-mail:        [email protected]
+    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, (^)/10,
+                  (\)/1, (\)/2, (\)/3, (\)/4, (\)/5, (\)/6, (\)/7, (\)/8,
+                  (+\)/2, (+\)/3, (+\)/4, (+\)/5, (+\)/6, (+\)/7, (+\)/8,
+                       (+\)/9, op(201,xfx,+\)]).
+
+/** <module> 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,?,?,?,?,?,?,?),
+       ^(?,7,?,?,?,?,?,?,?,?),
+       \(0),
+       \(1,?),
+       \(2,?,?),
+       \(3,?,?,?),
+       \(4,?,?,?,?),
+       \(5,?,?,?,?,?),
+       \(6,?,?,?,?,?,?),
+       \(7,?,?,?,?,?,?,?),
+       +\(?,0),
+       +\(?,1,?),
+       +\(?,2,?,?),
+       +\(?,3,?,?,?),
+       +\(?,4,?,?,?,?),
+       +\(?,5,?,?,?,?,?),
+       +\(?,6,?,?,?,?,?,?),
+       +\(?,7,?,?,?,?,?,?,?).
+
+:- meta_predicate no_hat_call(0).
+
+^(V1,C_0,V1) :-
+   no_hat_call(C_0).
+^(V1,C_1,V1,V2) :-
+   call(C_1,V2).
+^(V1,C_2,V1,V2,V3) :-
+   call(C_2,V2,V3).
+^(V1,C_3,V1,V2,V3,V4) :-
+   call(C_3,V2,V3,V4).
+^(V1,C_4,V1,V2,V3,V4,V5) :-
+   call(C_4,V2,V3,V4,V5).
+^(V1,C_5,V1,V2,V3,V4,V5,V6) :-
+   call(C_5,V2,V3,V4,V5,V6).
+^(V1,C_6,V1,V2,V3,V4,V5,V6,V7) :-
+   call(C_6,V2,V3,V4,V5,V6,V7).
+^(V1,C_7,V1,V2,V3,V4,V5,V6,V7,V8) :-
+   call(C_7,V2,V3,V4,V5,V6,V7,V8).
+
+\(FC_0) :-
+   copy_term_nat(FC_0,C_0),
+   no_hat_call(C_0).
+\(FC_1,V1) :-
+   copy_term_nat(FC_1,C_1),
+   call(C_1,V1).
+\(FC_2,V1,V2) :-
+   copy_term_nat(FC_2,C_2),
+   call(C_2,V1,V2).
+\(FC_3,V1,V2,V3) :-
+   copy_term_nat(FC_3,C_3),
+   call(C_3,V1,V2,V3).
+\(FC_4,V1,V2,V3,V4) :-
+   copy_term_nat(FC_4,C_4),
+   call(C_4,V1,V2,V3,V4).
+\(FC_5,V1,V2,V3,V4,V5) :-
+   copy_term_nat(FC_5,C_5),
+   call(C_5,V1,V2,V3,V4,V5).
+\(FC_6,V1,V2,V3,V4,V5,V6) :-
+   copy_term_nat(FC_6,C_6),
+   call(C_6,V1,V2,V3,V4,V5,V6).
+\(FC_7,V1,V2,V3,V4,V5,V6,V7) :-
+   copy_term_nat(FC_7,C_7),
+   call(C_7,V1,V2,V3,V4,V5,V6,V7).
+
+
++\(GV,FC_0) :-
+   copy_term_nat(GV+FC_0,GV+C_0),
+   no_hat_call(C_0).
++\(GV,FC_1,V1) :-
+   copy_term_nat(GV+FC_1,GV+C_1),
+   call(C_1,V1).
++\(GV,FC_2,V1,V2) :-
+   copy_term_nat(GV+FC_2,GV+C_2),
+   call(C_2,V1,V2).
++\(GV,FC_3,V1,V2,V3) :-
+   copy_term_nat(GV+FC_3,GV+C_3),
+   call(C_3,V1,V2,V3).
++\(GV,FC_4,V1,V2,V3,V4) :-
+   copy_term_nat(GV+FC_4,GV+C_4),
+   call(C_4,V1,V2,V3,V4).
++\(GV,FC_5,V1,V2,V3,V4,V5) :-
+   copy_term_nat(GV+FC_5,GV+C_5),
+   call(C_5,V1,V2,V3,V4,V5).
++\(GV,FC_6,V1,V2,V3,V4,V5,V6) :-
+   copy_term_nat(GV+FC_6,GV+C_6),
+   call(C_6,V1,V2,V3,V4,V5,V6).
++\(GV,FC_7,V1,V2,V3,V4,V5,V6,V7) :-
+   copy_term_nat(GV+FC_7,GV+C_7),
+   call(C_7,V1,V2,V3,V4,V5,V6,V7).
+
+
+%% no_hat_call(:Goal_0)
+%
+% Like call, but issues an error for a goal (^)/2.  Such goals are
+% likely the result of an insufficient number of arguments.
+
+no_hat_call(MGoal_0) :-
+   strip_module(MGoal_0, _, Goal_0),
+   (  nonvar(Goal_0),
+      Goal_0 = (_^_)
+   -> throw(
+                       error(
+                               existence_error(lambda_parameter,MGoal_0),
+                               _))
+       ;       call(MGoal_0)
+   ).
+
+% I would like to replace this by:
+% V1^Goal :- throw(error(existence_error(lambda_parameter,V1^Goal),_)).