1 /************************************************************************
2 ************************************************************************
4 Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
30 // Declaration of implementation
31 static Tree
calcDeBruijn2Sym (Tree t
);
32 static Tree
substitute(Tree t
, int n
, Tree id
);
33 static Tree
calcsubstitute(Tree t
, int level
, Tree id
);
34 static Tree
liftn(Tree t
, int threshold
);
35 static Tree
calcliftn(Tree t
, int threshold
);
39 Sym DEBRUIJN
= symbol ("DEBRUIJN");
40 Sym DEBRUIJNREF
= symbol ("DEBRUIJNREF");
41 Sym SUBSTITUTE
= symbol ("SUBSTITUTE");
43 Sym SYMREC
= symbol ("SYMREC");
44 Sym SYMRECREF
= symbol ("SYMRECREF");
45 Sym SYMLIFTN
= symbol ("LIFTN");
47 //Tree NOVAR = tree("NOVAR");
49 //-----------------------------------------------------------------------------------------
50 // rec, isRec : declare recursive trees
51 //-----------------------------------------------------------------------------------------
53 // de Bruijn declaration of a recursive tree
56 return tree(DEBRUIJN
, body
);
59 bool isRec(Tree t
, Tree
& body
)
61 return isTree(t
, DEBRUIJN
, body
);
67 return tree(DEBRUIJNREF
, tree(level
)); // reference to enclosing recursive tree starting from 1
70 bool isRef(Tree t
, int& level
)
74 if (isTree(t
, DEBRUIJNREF
, u
)) {
75 return isInt(u
->node(), &level
);
82 //-----------------------------------------------------------------------------------------
83 // Recursive tree in symbolic notation (using a recursive definition property)
84 //-----------------------------------------------------------------------------------------
85 Tree RECDEF
= tree(symbol("RECDEF"));
87 // declaration of a recursive tree using a symbolic variable
88 Tree
rec(Tree var
, Tree body
)
90 Tree t
= tree(SYMREC
, var
);
91 t
->setProperty(RECDEF
, body
);
95 bool isRec(Tree t
, Tree
& var
, Tree
& body
)
97 if (isTree(t
, SYMREC
, var
)) {
98 body
= t
->getProperty(RECDEF
);
108 return tree(SYMREC
, id
); // reference to a symbolic id
111 bool isRef(Tree t
, Tree
& v
)
113 return isTree(t
, SYMREC
, v
);
116 //-----------------------------------------------------------------------------------------
117 // L'aperture d'un arbre est la plus profonde reference de Bruijn qu'il contienne.
118 // Les references symboliques compte pour zero ce qui veut dire qu'un arbre d'aperture
119 // 0 ne compte aucun reference de bruijn libres.
121 int CTree::calcTreeAperture( const Node
& n
, const tvec
& br
)
124 if (n
== DEBRUIJNREF
) {
126 if (isInt(br
[0]->node(), &x
)) {
132 } else if (n
== DEBRUIJN
) {
134 return br
[0]->fAperture
- 1;
137 // return max aperture of branches
139 tvec::const_iterator b
= br
.begin();
140 tvec::const_iterator z
= br
.end();
142 if ((*b
)->aperture() > rc
) rc
= (*b
)->aperture();
149 Tree
lift(Tree t
) { return liftn(t
, 1); }
151 void printSignal(Tree sig
, FILE* out
, int prec
=0);
153 // lift (t) : increase free references by 1
156 static Tree
_liftn(Tree t
, int threshold
);
158 static Tree
liftn(Tree t
, int threshold
)
160 fprintf(stderr
, "call of liftn("); printSignal(t
, stderr
); fprintf(stderr
, ", %d)\n", threshold
);
161 Tree r
= _liftn(t
, threshold
);
162 fprintf(stderr
, "return of liftn("); printSignal(t
, stderr
); fprintf(stderr
, ", %d) -> ", threshold
);
163 printSignal(r
, stderr
); fprintf(stderr
, "\n");
169 static Tree
liftn(Tree t
, int threshold
)
171 Tree L
= tree( Node(SYMLIFTN
), tree(Node(threshold
)) );
172 Tree t2
= t
->getProperty(L
);
175 t2
= calcliftn(t
, threshold
);
176 t
->setProperty(L
, t2
);
182 static Tree
calcliftn(Tree t
, int threshold
)
191 } else if (isRef(t
,n
)) {
194 // it is a bounded reference
197 // it is a free reference
201 } else if (isRec(t
,u
)) {
203 return rec(liftn(u
, threshold
+1));
209 for (int i
= 0; i
< n
; i
++) {
210 br
[i
] = liftn(t
->branch(i
), threshold
);
212 //return CTree::make(t->node(), n, br);
213 return CTree::make(t
->node(), br
);
218 //-----------------------------------------------------------
219 // Transform a tree from deBruijn to symbolic representation
220 //-----------------------------------------------------------
221 Tree DEBRUIJN2SYM
= tree(symbol("deBruijn2Sym"));
223 Tree
deBruijn2Sym (Tree t
)
226 Tree t2
= t
->getProperty(DEBRUIJN2SYM
);
229 t2
= calcDeBruijn2Sym(t
);
230 t
->setProperty(DEBRUIJN2SYM
, t2
);
235 static Tree
calcDeBruijn2Sym (Tree t
)
242 var
= tree(unique("W"));
243 return rec(var
, deBruijn2Sym(substitute(body
,1,ref(var
))));
245 } else if (isRef(t
,var
)) {
249 } else if (isRef(t
,i
)) {
251 fprintf(stderr
, "ERREUR, une reference de Bruijn touvee ! : ");
252 printSignal(t
, stderr
);
253 fprintf(stderr
, ")\n");
263 for (int i
= 0; i
< a
; i
++) {
264 br
[i
] = deBruijn2Sym(t
->branch(i
));
266 //return CTree::make(t->node(), a, br);
267 return CTree::make(t
->node(), br
);
271 static Tree
substitute(Tree t
, int level
, Tree id
)
273 Tree S
= tree( Node(SUBSTITUTE
), tree(Node(level
)), id
);
274 Tree t2
= t
->getProperty(S
);
277 t2
= calcsubstitute(t
, level
, id
);
278 t
->setProperty(S
, t2
);
284 static Tree
calcsubstitute(Tree t
, int level
, Tree id
)
289 if (t
->aperture()<level
) {
290 // fprintf(stderr, "aperture %d < level %d !!\n", t->aperture(), level);
293 if (isRef(t
,l
)) return (l
== level
) ? id
: t
;
294 if (isRec(t
,body
)) return rec(substitute(body
, level
+1, id
));
299 for (int i
= 0; i
< ar
; i
++) {
300 br
[i
] = substitute(t
->branch(i
), level
, id
);
302 //return CTree::make(t->node(), ar, br);
303 return CTree::make(t
->node(), br
);
307 //--------------------------------------------------------------------------
308 // UpdateAperture (t) : recursively mark open and closed terms.
309 // closed term : fAperture == 0, open term fAperture == -1
312 Tree fTree
; Env
* fNext
;
313 Env(Tree t
, Env
* nxt
) : fTree(t
), fNext(nxt
) {}
316 static void markOpen(Tree t
);
317 static int recomputeAperture(Tree t
, Env
* p
);
318 static int orderof (Tree t
, Env
* p
);
320 void updateAperture(Tree t
)
323 recomputeAperture(t
, NULL
);
326 //----------------------implementation--------------------------------
328 static void markOpen(Tree t
)
330 if (t
->aperture() == INT_MAX
) return;
331 t
->setAperture(INT_MAX
);
333 for (int i
= 0; i
< ar
; i
++) {
334 markOpen(t
->branch(i
));
338 static int recomputeAperture(Tree t
, Env
* env
)
342 if (t
->aperture() == 0) return 0;
346 return orderof(var
, env
);
348 } else if (isRec(t
, var
, body
)) {
351 int a
= recomputeAperture(body
, &e
) - 1;
352 if (a
<=0) { /*print(t, stderr);*/ t
->setAperture(0); }
356 // return max aperture of branches
359 for (int i
= 0; i
<ar
; i
++) {
360 int a
= recomputeAperture(t
->branch(i
), env
);
363 if (ma
<= 0) { /*print(t, stderr);*/ t
->setAperture(0); }
369 static int orderof (Tree t
, Env
* p
)
371 if (p
== NULL
) return 0;
372 if (t
== p
->fTree
) return 1;
376 if (t
== p
->fTree
) return pos
;