34
35:- module(clambda, [op(201,xfx,+\)]).
45:- reexport(library(compound_expand)). 46:- reexport(library(lambda)). 47:- use_module(library(apply)). 48:- use_module(library(lists)). 49:- use_module(library(occurs)). 50:- init_expansors. 51
54
55remove_hats(^(H, G1), G) -->
56 [H],
57 !,
58 remove_hats(G1, G).
59remove_hats(G, G) --> [].
60
61remove_hats(G1, G, EL) :-
62 remove_hats(G1, G2, EL, T),
63 '$expand':extend_arg_pos(G2, _, T, G, _).
64
65cgoal_args(G1, G, AL, EL) :-
66 G1 =.. [F|Args],
67 cgoal_args(F, Args, G, Fr, EL),
68 term_variables(Fr, AL).
69
70cgoal_args(\, [G1|EL], G, [], EL) :- remove_hats(G1, G, EL).
71cgoal_args(+\, [Fr,G1|EL], G, Fr, EL) :- remove_hats(G1, G, EL).
72
73singleton(T, Name=V) :-
74 occurrences_of_var(V, T, 1),
75 \+ atom_concat('_', _, Name).
76
77have_name(VarL, _=Value) :-
78 member(Var, VarL),
79 Var==Value, !.
80
81bind_name(Name=_, Name).
82
83check_singletons(Goal, Term) :-
84 term_variables(Term, VarL),
85 Term = h(_, _, A),
86 ( nb_current('$variable_names', Bindings)
87 ->true
88 ; Bindings = []
89 ),
90 include(have_name(VarL), Bindings, VarN),
91 include(singleton(Term), VarN, VarSN),
92 ( VarSN \= []
93 ->term_variables(A, VarAL),
94 include(have_name(VarAL), Bindings, VarAN),
95 intersection(VarAN, VarSN, VarIN),
96 subtract(VarSN, VarAN, VarDN),
97 ( VarIN \= []
98 ->maplist(bind_name, VarIN, INames),
99 print_message(warning, local_variables_outside(INames, Goal, Bindings))
100 ; true
101 ),
102 ( VarDN \= []
103 ->maplist(bind_name, VarDN, DNames),
104 print_message(warning, unused_parameter(DNames, Goal, Bindings))
105 ; true
106 )
107 ; true
108 ).
109
110prolog:message(local_variables_outside(Names, Goal, Bindings)) -->
111 [ 'Local variables ~w should not occur outside lambda expression: ~W'-[Names, Goal, [variable_names(Bindings)]] ].
112
113prolog:message(unused_parameter(Names, Goal, Bindings)) -->
114 [ 'Unused parameters ~w in lambda expression: ~W'-[Names, Goal, [variable_names(Bindings)]] ].
115
116lambdaize_args(G, A1, M, VL, Ex, A) :-
117 check_singletons(G, h(VL, Ex, A1)),
118 ( ( Ex==[]
119 ; '$member'(E1, Ex),
120 '$member'(E2, VL),
121 E1==E2
122 )
123 ->'$expand':wrap_meta_arguments(A1, M, VL, Ex, A)
124 ; '$expand':remove_arg_pos(A1, _, M, VL, Ex, A, _)
125 ).
126
127goal_expansion(G1, G) :-
128 callable(G1),
129 cgoal_args(G1, G2, AL, EL),
130 '$current_source_module'(M),
131 expand_goal(G2, G3),
132 lambdaize_args(G1, G3, M, AL, EL, G4),
133 134 G4 =.. [AuxName|VL],
135 append(VL, EL, AV),
136 G =.. [AuxName|AV]
Lambda expressions
This library is semantically equivalent to the lambda library implemented by Ulrich Neumerkel, but it performs static expansion of the expressions to improve performance.