Merge branch 'master' of yap.dcc.fc.up.pt:yap-6

This commit is contained in:
Vítor Santos Costa 2010-08-05 22:20:47 +01:00
commit f63915b07a
11 changed files with 322 additions and 23 deletions

View File

@ -965,7 +965,6 @@ static InitBinEntry InitBinTab[] = {
{"\\/", op_or}, {"\\/", op_or},
{"#", op_xor}, {"#", op_xor},
{"><", op_xor}, {"><", op_xor},
{"atan", op_atan2},
{"atan2", op_atan2}, {"atan2", op_atan2},
/* C-Prolog exponentiation */ /* C-Prolog exponentiation */
{"^", op_power}, {"^", op_power},

View File

@ -1009,9 +1009,9 @@ Yap_InitUnify(void)
{ {
Term cm = CurrentModule; Term cm = CurrentModule;
Yap_InitCPred("unify_with_occurs_check", 2, p_ocunify, SafePredFlag); Yap_InitCPred("unify_with_occurs_check", 2, p_ocunify, SafePredFlag);
Yap_InitCPred("acyclic_term", 1, p_acyclic, SafePredFlag|TestPredFlag);
CurrentModule = TERMS_MODULE; CurrentModule = TERMS_MODULE;
Yap_InitCPred("cyclic_term", 1, p_cyclic, SafePredFlag|TestPredFlag); Yap_InitCPred("cyclic_term", 1, p_cyclic, SafePredFlag|TestPredFlag);
Yap_InitCPred("acyclic_term", 1, p_acyclic, SafePredFlag|TestPredFlag);
Yap_InitCPred("protected_unifiable", 3, p_unifiable, 0); Yap_InitCPred("protected_unifiable", 3, p_unifiable, 0);
CurrentModule = cm; CurrentModule = cm;
} }

View File

@ -17,7 +17,14 @@
<h2>Yap-6.0.7:</h2> <h2>Yap-6.0.7:</h2>
<ul> <ul>
<li> FIXED: nothing yet.</li> <li> NEW: Ulrich Neumerkel's lambda library.</li>
<li> DELETE: ^/2 and ^/3 as grammar built-ins.</li>
<li> FIXED: make install in clpqr was broken if we used local install_sh .</li>
<li> DELETE: atan/2 arithmetic function, use atan2/2 instead (WG17).</li>
<li> FIXED: compilation in Solaris was broken because of conflict in
declaration of gethostname.</li>
<li> FIXED: acyclic_term/1 is now built-in (WG17).</li>
<li> NEW: subsumes_term/2 (WG17).</li>
</ul> </ul>
<h2>Yap-6.0.6:</h2> <h2>Yap-6.0.6:</h2>

View File

@ -198,6 +198,7 @@ Subnodes of Library
* AVL Trees:: Predicates to add and lookup balanced binary trees. * AVL Trees:: Predicates to add and lookup balanced binary trees.
* Heaps:: Labelled binary tree where the key of each node is less * Heaps:: Labelled binary tree where the key of each node is less
than or equal to the keys of its children. than or equal to the keys of its children.
* Lambda:: Ulrich Neumerkel's Lambda Library
* LineUtilities:: Line Manipulation Utilities * LineUtilities:: Line Manipulation Utilities
* Lists:: List Manipulation * Lists:: List Manipulation
* MapList:: SWI-Compatible Apply library. * MapList:: SWI-Compatible Apply library.
@ -3350,6 +3351,22 @@ is bound to the empty list (nil) or a term with functor '.' and arity 2.
Same as @code{variant/2}, succeeds if @var{Term1} and @var{Term2} are variant terms. Same as @code{variant/2}, succeeds if @var{Term1} and @var{Term2} are variant terms.
@item subsumes_term(?@var{Subsumer}, ?@var{Subsumed})
@findex subsumes_term/2
@syindex subsumes_term/2
@cnindex subsumes_term/2
Succeed if @var{Submuser} subsumes @var{Subsuned} but does not bind any
variable in @var{Subsumer}.
@item acyclic_term(?@var{Term})
@findex cyclic_term/1
@syindex cyclic_term/1
@cnindex cyclic_term/1
Succeed if the argument @var{Term} is an acyclic term.
@end table @end table
@node Predicates on Atoms, Predicates on Characters, Testing Terms, Top @node Predicates on Atoms, Predicates on Characters, Testing Terms, Top
@ -3916,11 +3933,8 @@ Arc cosine.
@item atan(@var{X}) [ISO] @item atan(@var{X}) [ISO]
Arc tangent. Arc tangent.
@item atan(@var{X},@var{Y})
Four-quadrant arc tangent.
@item atan2(@var{X},@var{Y}) @item atan2(@var{X},@var{Y})
Four-quadrant arc tangent, same as atan/2. Four-quadrant arc tangent.
@item sinh(@var{X}) @item sinh(@var{X})
Hyperbolic sine. Hyperbolic sine.
@ -8452,6 +8466,7 @@ Library, Extensions, Built-ins, Top
* Heaps:: Labelled binary tree where the key of each node is less * Heaps:: Labelled binary tree where the key of each node is less
than or equal to the keys of its children. than or equal to the keys of its children.
* LAM:: LAM MPI * LAM:: LAM MPI
* Lambda:: Ulrich Neumerkel's Lambda Library
* Lists:: List Manipulation * Lists:: List Manipulation
* LineUtilities:: Line Manipulation Utilities * LineUtilities:: Line Manipulation Utilities
* MapList:: SWI-Compatible Apply library. * MapList:: SWI-Compatible Apply library.
@ -11574,12 +11589,6 @@ efficiency. They are available through the
@table @code @table @code
@item acyclic_term(?@var{Term})
@findex cyclic_term/1
@syindex cyclic_term/1
@cnindex cyclic_term/1
Succeed if the argument @var{Term} is an acyclic term.
@item cyclic_term(?@var{Term}) @item cyclic_term(?@var{Term})
@findex cyclic_term/1 @findex cyclic_term/1
@syindex cyclic_term/1 @syindex cyclic_term/1
@ -12496,7 +12505,7 @@ The path @var{Path} is a path starting at vertex @var{Vertex} in graph
@end table @end table
@node UnDGraphs, LAM , DGraphs, Library @node UnDGraphs, Lambda , DGraphs, Library
@section Undirected Graphs @section Undirected Graphs
@cindex undirected graphs @cindex undirected graphs
@ -12592,7 +12601,83 @@ directed graph @var{DGraph}.
@end table @end table
@node LAM, , UnDGraphs, Library @node Lambda, LAM, UnDGraphs, Library
@section Lambda Expressions
@cindex Lambda Expressions
This library, designed and implemented by Ulrich Neumerkel, provides
lambda expressions to simplify higher order programming based on @code{call/N}.
Lambda expressions are represented by ordinary Prolog terms. There are
two kinds of lambda expressions:
@example
Free+\X1^X2^ ..^XN^Goal
\X1^X2^ ..^XN^Goal
@end example
The second is a shorthand for@code{ t+\X1^X2^..^XN^Goal}, where @code{Xi} are the parameters.
@var{Goal} is a goal or continuation (Syntax note: @var{Operators} within @var{Goal}
require parentheses due to the low precedence of the @code{^} operator).
Free contains variables that are valid outside the scope of the lambda
expression. They are thus free variables within.
All other variables of @var{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 @code{X>3} are necessary.
@example
?- use_module(library(lambda)).
?- use_module(library(apply)).
?- maplist(\X^(X>3),[4,5,9]).
true.
@end example
In the following @var{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.
@example
?- 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).
@end example
The following queries are all equivalent. To see this, use
the fact @code{f(x,y)}.
@example
?- 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.
@end example
Further discussions
at @url{http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/ISO-Hiord}.
@node LAM, , Lambda, Library
@section LAM @section LAM
@cindex lam @cindex lam

View File

@ -44,6 +44,7 @@ PROGRAMS= \
$(srcdir)/gensym.yap \ $(srcdir)/gensym.yap \
$(srcdir)/hacks.yap \ $(srcdir)/hacks.yap \
$(srcdir)/heaps.yap \ $(srcdir)/heaps.yap \
$(srcdir)/lambda.pl \
$(srcdir)/lineutils.yap \ $(srcdir)/lineutils.yap \
$(srcdir)/lists.yap \ $(srcdir)/lists.yap \
$(srcdir)/nb.yap \ $(srcdir)/nb.yap \

204
library/lambda.pl Normal file
View File

@ -0,0 +1,204 @@
/*
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,+\)]).
/** <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 no_hat_call(0).
:- meta_predicate
^(?,0,?),
^(?,1,?,?),
^(?,2,?,?,?),
^(?,3,?,?,?,?),
^(?,4,?,?,?,?,?).
^(V1,Goal,V1) :-
no_hat_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_nat(FC,C),no_hat_call(C).
\(FC,V1) :-
copy_term_nat(FC,C),call(C,V1).
\(FC,V1,V2) :-
copy_term_nat(FC,C),call(C,V1,V2).
\(FC,V1,V2,V3) :-
copy_term_nat(FC,C),call(C,V1,V2,V3).
\(FC,V1,V2,V3,V4) :-
copy_term_nat(FC,C),call(C,V1,V2,V3,V4).
\(FC,V1,V2,V3,V4,V5) :-
copy_term_nat(FC,C),call(C,V1,V2,V3,V4,V5).
\(FC,V1,V2,V3,V4,V5,V6) :-
copy_term_nat(FC,C),call(C,V1,V2,V3,V4,V5,V6).
:- meta_predicate
+\(?,0),
+\(?,1,?),
+\(?,2,?,?),
+\(?,3,?,?,?),
+\(?,4,?,?,?,?),
+\(?,5,?,?,?,?,?),
+\(?,6,?,?,?,?,?,?).
+\(GV,FC) :-
copy_term_nat(GV+FC,GV+C),no_hat_call(C).
+\(GV,FC,V1) :-
copy_term_nat(GV+FC,GV+C),call(C,V1).
+\(GV,FC,V1,V2) :-
copy_term_nat(GV+FC,GV+C),call(C,V1,V2).
+\(GV,FC,V1,V2,V3) :-
copy_term_nat(GV+FC,GV+C),call(C,V1,V2,V3).
+\(GV,FC,V1,V2,V3,V4) :-
copy_term_nat(GV+FC,GV+C),call(C,V1,V2,V3,V4).
+\(GV,FC,V1,V2,V3,V4,V5) :-
copy_term_nat(GV+FC,GV+C),call(C,V1,V2,V3,V4,V5).
+\(GV,FC,V1,V2,V3,V4,V5,V6) :-
copy_term_nat(GV+FC,GV+C),call(C,V1,V2,V3,V4,V5,V6).
%% no_hat_call(:Goal)
%
% 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) :-
strip_module(MGoal, _, Goal),
( nonvar(Goal),
Goal = (_^_)
-> throw(error(existence_error(lambda_parameters,Goal),_))
; call(MGoal)
).
% I would like to replace this by:
% V1^Goal :- throw(error(existence_error(lambda_parameters,V1^Goal),_)).

View File

@ -24,7 +24,6 @@
subsumes/2, subsumes/2,
subsumes_chk/2, subsumes_chk/2,
cyclic_term/1, cyclic_term/1,
acyclic_term/1,
variable_in_term/2, variable_in_term/2,
variables_within_term/3, variables_within_term/3,
new_variables_in_term/3 new_variables_in_term/3

View File

@ -23,7 +23,7 @@
/* $Id$ */ /* $Id$ */
#if HAS_GETHOSTNAME #if HAS_GETHOSTNAME||HAVE_GETHOSTNAME
#else #else

@ -1 +1 @@
Subproject commit 11cbb29604383f4cfddc2bb98d59819f6ab6ad94 Subproject commit 5d263188330d4c66b88d25247dfdbd482a39b75a

View File

@ -15,11 +15,11 @@
* * * *
*************************************************************************/ *************************************************************************/
:- meta_predicate ^(?,0,?). % :- meta_predicate ^(?,0,?).
^(Xs, Goal, Xs) :- call(Goal). % ^(Xs, Goal, Xs) :- call(Goal).
:- meta_predicate ^(?,1,?,?). % :- meta_predicate ^(?,1,?,?).
^(Xs0, Goal, Xs0, Xs) :- call(Goal, Xs). % ^(Xs0, Goal, Xs0, Xs) :- call(Goal, Xs).
/* /*
Variables X in grammar rule bodies are translated as Variables X in grammar rule bodies are translated as

View File

@ -643,3 +643,7 @@ nb_current(GlobalVariable, Val) :-
). ).
subsumes_term(A,B) :-
\+ \+ terms:subsumes(A,B).