20:- module(attributes, [op(
1150, fx, attribute)]).
65:-
dynamic existing_attribute/4.
66:-
dynamic modules_with_attributes/1.
67:-
dynamic attributed_module/3.
69modules_with_attributes([]).
75new_attribute(
V)
:- var(
V),
var,
76 throw(error(instantiation_error,attribute(
V))).
77new_attribute((
At1,
At2))
:-
80new_attribute(
Na/Ar)
:-
83 existing_attribute(
S,
Mod,
_,
_) ,
existing_attribute.
84new_attribute(
Na/Ar)
:-
87 store_new_module(
Mod,
Ar,
Position),
88 assertz(existing_attribute(
S,
Mod,
Ar,
Position)).
90store_new_module(
Mod,
Ar,
ArgPosition)
:-
92 retract(attributed_module(
Mod,
Position,
_))
96 retract(modules_with_attributes(
Mods)),
97 assert(modules_with_attributes([
Mod|Mods])),
Position = 2
99 ArgPosition is Position+1,
100 (
Ar == 0 -> NOfAtts is Position+1 ; NOfAtts is Position+Ar),
101 functor(
AccessTerm,
Mod,
NOfAtts),
102 assertz(attributed_module(
Mod,
NOfAtts,
AccessTerm)).
104:-
user_defined_directive(attribute(
G), attributes
:new_attribute(
G)).
123user_defined_directive
:goal_expansion(get_atts(
Var,
AccessSpec),
Mod,
Goal)
:-
124 expand_get_attributes(
AccessSpec,
Mod,
Var,
Goal).
142expand_get_attributes
:goal_expansion(put_atts(
Var,
AccessSpec),
Mod,
Goal)
:-
143 expand_put_attributes(
AccessSpec,
Mod,
Var,
Goal).
146expand_get_attributes(
V,
_,
_,
_)
:- var(
V),
var,
var.
147expand_get_attributes([],
_,
_,true)
:- expand_get_attributes.
148expand_get_attributes([
-G1],
Mod,
V,attributes
:free_att(
V,
Mod,
Pos))
:-
149 existing_attribute(
G1,
Mod,
_,
Pos),
existing_attribute.
150expand_get_attributes([
+G1],
Mod,
V,attributes
:get_att(
V,
Mod,
Pos,
A))
:-
151 existing_attribute(
G1,
Mod,
1,
Pos),
existing_attribute,
153expand_get_attributes([
G1],
Mod,
V,attributes
:get_att(
V,
Mod,
Pos,
A))
:-
154 existing_attribute(
G1,
Mod,
1,
Pos),
existing_attribute,
156expand_get_attributes(
Atts,
Mod,
Var,attributes
:get_module_atts(
Var,
AccessTerm))
:- Atts = [
_|_],
,
157 attributed_module(
Mod,
NOfAtts,
AccessTerm),
159 cvt_atts(
Atts,
Mod,
Void,
LAtts),
160 sort(
LAtts,
SortedLAtts),
162 build_att_term(
1,
NOfAtts,
SortedLAtts,
Free,
AccessTerm).
163expand_get_attributes(
Att,
Mod,
Var,
Goal)
:-
164 expand_get_attributes([
Att],
Mod,
Var,
Goal).
166build_att_term(
NOfAtts,
NOfAtts,[],
_,
_)
:- build_att_term.
167build_att_term(
I0,
NOfAtts,[
I-Info|SortedLAtts],
Void,
AccessTerm)
:-
168 I is I0+1,
build_att_term,
169 copy_att_args(
Info,
I0,
NI,
AccessTerm),
170 build_att_term(
NI,
NOfAtts,
SortedLAtts,
Void,
AccessTerm).
171build_att_term(
I0,
NOfAtts,
SortedLAtts,
Void,
AccessTerm)
:-
173 arg(
I,
AccessTerm,
Void),
174 build_att_term(
I,
NOfAtts,
SortedLAtts,
Void,
AccessTerm).
176cvt_atts(
V,
_,
_,
_)
:- var(
V),
var,
var.
178cvt_atts([
V|_],
_,
_,
_)
:- var(
V),
var,
var.
179cvt_atts([
+Att|Atts],
Mod,
Void,[
Pos-LAtts|Read])
:- cvt_atts,
180 existing_attribute(
Att,
Mod,
_,
Pos),
181 (
atom(
Att)
-> LAtts = [
_]
; Att=..[
_|LAtts]),
182 cvt_atts(
Atts,
Mod,
Void,
Read).
183cvt_atts([
-Att|Atts],
Mod,
Void,[
Pos-LVoids|Read])
:- cvt_atts,
184 existing_attribute(
Att,
Mod,
_,
Pos),
191 void_vars(
LAtts,
Void,
LVoids)
193 cvt_atts(
Atts,
Mod,
Void,
Read).
194cvt_atts([
Att|Atts],
Mod,
Void,[
Pos-LAtts|Read])
:- cvt_atts,
195 existing_attribute(
Att,
Mod,
_,
Pos),
196 (
atom(
Att)
-> LAtts = [
_]
; Att=..[
_|LAtts]),
197 cvt_atts(
Atts,
Mod,
Void,
Read).
199copy_att_args([],
I,
I,
_).
200copy_att_args([
V|Info],
I,
NI,
AccessTerm)
:-
202 arg(
I1,
AccessTerm,
V),
203 copy_att_args(
Info,
I1,
NI,
AccessTerm).
206void_vars([
_|LAtts],
Void,[
Void|LVoids])
:-
207 void_vars(
LAtts,
Void,
LVoids).
209expand_put_attributes(
V,
_,
_,
_)
:- var(
V),
var,
var.
210expand_put_attributes([
-G1],
Mod,
V,attributes
:rm_att(
V,
Mod,
NOfAtts,
Pos))
:-
211 existing_attribute(
G1,
Mod,
_,
Pos),
existing_attribute,
212 attributed_module(
Mod,
NOfAtts,
_).
213expand_put_attributes([
+G1],
Mod,
V,attributes
:put_att(
V,
Mod,
NOfAtts,
Pos,
A))
:-
214 existing_attribute(
G1,
Mod,
1,
Pos),
existing_attribute,
215 attributed_module(
Mod,
NOfAtts,
_),
217expand_put_attributes([
G1],
Mod,
V,attributes
:put_att(
V,
Mod,
NOfAtts,
Pos,
A))
:-
218 existing_attribute(
G1,
Mod,
1,
Pos),
existing_attribute,
219 attributed_module(
Mod,
NOfAtts,
_),
221expand_put_attributes(
Atts,
Mod,
Var,attributes
:put_module_atts(
Var,
AccessTerm))
:- Atts = [
_|_],
,
222 attributed_module(
Mod,
NOfAtts,
AccessTerm),
224 cvt_atts(
Atts,
Mod,
Void,
LAtts),
225 sort(
LAtts,
SortedLAtts),
227 build_att_term(
1,
NOfAtts,
SortedLAtts,
Free,
AccessTerm).
228expand_put_attributes(
Att,
Mod,
Var,
Goal)
:-
229 expand_put_attributes([
Att],
Mod,
Var,
Goal).
231expand_put_attributes
:woken_att_do(
AttVar,
Binding,
NGoals,
DoNotBind)
:-
232 modules_with_attributes(
AttVar,
Mods0),
233 modules_with_attributes(
Mods),
234 find_used(
Mods,
Mods0,[],
ModsI),
235 do_verify_attributes(
ModsI,
AttVar,
Binding,
Goals),
236 process_goals(
Goals,
NGoals,
DoNotBind).
239process_goals([], [],
_).
240process_goals([(
M:do_not_bind_variable(
Gs))
|Goals], (
M:Gs)
.NGoals, true)
:- process_goals,
241 process_goals(
Goals,
NGoals,
_).
242process_goals(
G.Goals,
G.NGoals,
Do)
:-
243 process_goals(
Goals,
NGoals,
Do).
246find_used([
M|Mods],
Mods0,
L0,
Lf)
:-
248 find_used(
Mods,
Mods0,[
M|L0],
Lf).
249find_used([
_|Mods],
Mods0,
L0,
Lf)
:-
250 find_used(
Mods,
Mods0,
L0,
Lf).
272do_verify_attributes([],
_,
_, []).
273do_verify_attributes([
Mod|Mods],
AttVar,
Binding, [
Mod:Goal|Goals])
:-
274 current_predicate(verify_attributes,
Mod:verify_attributes(
_,
_,
_)),
current_predicate,
275 Mod:verify_attributes(
AttVar,
Binding,
Goal),
276 do_verify_attributes(
Mods,
AttVar,
Binding,
Goals).
277do_verify_attributes([
_|Mods],
AttVar,
Binding,
Goals)
:-
278 do_verify_attributes(
Mods,
AttVar,
Binding,
Goals).
283
goal_expansion( :G,+ M,- NG)
member(?Element, ?Set) is true when Set is a list, and Element occurs in it