d2a6d35cea3efc066c47be58d6b3a81c653a95d0
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 ************************************************************************/
32 #include "sigprint.hh"
37 #include "sigtyperules.hh"
39 #include "recursivness.hh"
40 #include "sigraterules.hh"
43 //--------------------------------------------------------------------------
44 // Uncomment to activate type inference tracing
51 //--------------------------------------------------------------------------
53 static ostream
& printRateEnvironment(ostream
& fout
, Tree E
);
54 static Tree
inferreMultiRates(Tree lsig
, bool& success
);
55 static ostream
& printRateEnvironmentList(ostream
& fout
, Tree LE
);
57 static void setSigType(Tree sig
, Type t
);
58 static Type
getSigType(Tree sig
);
59 static Type
initialRecType(Tree t
);
61 static Type
T(Tree term
, Tree env
);
63 static Type
infereSigType(Tree term
, Tree env
);
64 static Type
infereFFType (Tree ff
, Tree ls
, Tree env
);
65 static Type
infereFConstType (Tree type
);
66 static Type
infereFVarType (Tree type
);
67 static Type
infereRecType (Tree var
, Tree body
, Tree env
);
68 static Type
infereReadTableType(Type tbl
, Type ri
);
69 static Type
infereWriteTableType(Type tbl
, Type wi
, Type wd
);
70 static Type
infereProjType(Type t
, int i
, int vec
);
71 static Type
infereXType(Tree sig
, Tree env
);
72 static Type
infereDocConstantTblType(Type size
, Type init
);
73 static Type
infereDocWriteTblType(Type size
, Type init
, Type widx
, Type wsig
);
74 static Type
infereDocAccessTblType(Type tbl
, Type ridx
);
75 static interval
arithmetic (int opcode
, const interval
& x
, const interval
& y
);
78 static Type
infereVectorizeType(Tree sig
, Type T
, Type Tsize
);
79 static Type
infereSerializeType(Tree sig
, Type Tvec
);
80 static Type
infereConcatType(Type Tvec1
, Type Tvec2
);
81 static Type
infereVectorAtType(Type Tvec
, Type Tidx
);
87 * The empty type environment (also property key for closed term type)
89 static Tree NULLTYPEENV
= tree(symbol("NullTypeEnv"));
91 static int countInferences
;
92 static int countMaximal
;
97 * Fully annotate every subtree of term with type information.
98 * @param sig the signal term tree to annotate
101 void typeAnnotation(Tree sig
)
103 Tree sl
= symlist(sig
);
106 vector
<Tree
> vrec
, vdef
;
109 //cerr << "Symlist " << *sl << endl;
110 for (Tree l
=sl
; isList(l
); l
=tl(l
)) {
112 assert(isRec(hd(l
), id
, body
));
114 vrec
.push_back(hd(l
));
115 vdef
.push_back(body
);
118 // init recursive types
119 for (int i
=0; i
<n
; i
++) {
120 vtype
.push_back(initialRecType(vdef
[i
]));
123 assert (int(vrec
.size())==n
);
124 assert (int(vdef
.size())==n
);
125 assert (int(vtype
.size())==n
);
127 // find least fixpoint
128 for (bool finished
= false; !finished
; ) {
130 // init recursive types
131 CTree::startNewVisit();
132 for (int i
=0; i
<n
; i
++) {
133 setSigType(vrec
[i
], vtype
[i
]);
134 vrec
[i
]->setVisited();
137 // compute recursive types
138 for (int i
=0; i
<n
; i
++) {
139 vtype
[i
] = T(vdef
[i
], NULLTYPEENV
);
144 for (int i
=0; i
<n
; i
++) {
145 //cerr << i << "-" << *vrec[i] << ":" << *getSigType(vrec[i]) << " => " << *vtype[i] << endl;
146 finished
= finished
& (getSigType(vrec
[i
]) == vtype
[i
]);
154 //cerr << TABBER << "COUNT INFERENCE " << countInferences << " AT TIME " << clock()/CLOCKS_PER_SEC << 's' << endl;
155 fixInferredType(sig
, NULLTYPEENV
);
156 //cerr << --TABBER << "EXIT TYPE ANNOTATION OF " << *sig << " AT TIME " << clock()/CLOCKS_PER_SEC << 's' << endl;
160 Tree RE
= inferreMultiRates(sig
, success
);
162 printRateEnvironment(cerr
, RE
); cerr
<< endl
;
164 cerr
<< "ERROR can't inferre rate environment of " << ppsig(sig
) << endl
;
167 //RateInferrer R(sig);
175 void annotationStatistics()
177 cerr
<< TABBER
<< "COUNT INFERENCE " << countInferences
<< " AT TIME " << clock()/CLOCKS_PER_SEC
<< 's' << endl
;
178 cerr
<< TABBER
<< "COUNT ALLOCATION " << AudioType::gAllocationCount
<< endl
;
179 cerr
<< TABBER
<< "COUNT MAXIMAL " << countMaximal
<< endl
;
183 * Retrieve the type of sig and check it exists. Produces an
184 * error if the signal has no type associated
185 * @param sig the signal we want to know the type
186 * @return the type of the signal
188 Type
getCertifiedSigType(Tree sig
)
190 Type ty
= getSigType(sig
);
197 /***********************************************
198 * Set and get the type property of a signal
199 * (we suppose the signal have been previously
200 * annotated with type information)
201 ***********************************************/
204 * Set the type annotation of sig
205 * @param sig the signal we want to type
206 * @param t the type of the signal
208 static void setSigType(Tree sig
, Type t
)
210 TRACE(cerr
<< TABBER
<< "SET FIX TYPE OF " << *sig
<< " TO TYPE " << *t
<< endl
;)
216 * Retrieve the type annotation of sig
217 * @param sig the signal we want to know the type
219 static Type
getSigType(Tree sig
)
221 AudioType
* ty
= (AudioType
*) sig
->getType();
223 TRACE(cerr
<< TABBER
<< "GET FIX TYPE OF " << *sig
<< " HAS NO TYPE YET" << endl
;)
225 TRACE(cerr
<< TABBER
<< "GET FIX TYPE OF " << *sig
<< " IS TYPE " << *ty
<< endl
;)
233 /**************************************************************************
235 Type Inference System
237 ***************************************************************************/
240 /**************************************************************************
242 Infered Type property
244 ***************************************************************************/
247 * Shortcut to getOrInferType, retrieve or infere the type of a term according to its surrounding type environment
248 * @param sig the signal to analyze
249 * @param env the type environment
250 * @return the type of sig according to environment env
251 * @see getCertifiedSigType
253 static Type
T(Tree term
, Tree ignoreenv
)
255 TRACE(cerr
<< ++TABBER
<< "ENTER T() " << *term
<< endl
;)
257 if (term
->isAlreadyVisited()) {
258 Type ty
= getSigType(term
);
259 TRACE(cerr
<< --TABBER
<< "EXIT 1 T() " << *term
<< " AS TYPE " << *ty
<< endl
);
263 Type ty
= infereSigType(term
, ignoreenv
);
266 TRACE(cerr
<< --TABBER
<< "EXIT 2 T() " << *term
<< " AS TYPE " << *ty
<< endl
);
273 * Infere the type of a term according to its surrounding type environment
274 * @param sig the signal to aanlyze
275 * @param env the type environment
276 * @return the type of sig according to environment env
279 static Type
infereSigType(Tree sig
, Tree env
)
283 Tree sel
, s1
, s2
, s3
, ff
, id
, ls
, l
, x
, y
, z
, u
, var
, body
, type
, name
, file
;
284 Tree label
, cur
, min
, max
, step
;
288 if ( getUserData(sig
) ) return infereXType(sig
, env
);
290 else if (isSigInt(sig
, &i
)) { Type t
= makeSimpleType(kInt
, kKonst
, kComp
, kVect
, kNum
, interval(i
));
291 /*sig->setType(t);*/ return t
; }
293 else if (isSigReal(sig
, &r
)) { Type t
= makeSimpleType(kReal
, kKonst
, kComp
, kVect
, kNum
, interval(r
));
294 /*sig->setType(t);*/ return t
; }
296 else if (isSigInput(sig
, &i
)) { /*sig->setType(TINPUT);*/ return TINPUT
; }
298 else if (isSigOutput(sig
, &i
, s1
)) return sampCast(T(s1
,env
));
300 else if (isSigDelay1(sig
, s1
)) {
302 return castInterval(sampCast(t
), reunion(t
->getInterval(), interval(0,0)));
305 else if (isSigPrefix(sig
, s1
, s2
)) {
309 return castInterval(sampCast(t1
|t2
), reunion(t1
->getInterval(), t2
->getInterval()));
312 else if (isSigFixDelay(sig
, s1
, s2
)) {
313 Type vt1
= T(s1
,env
);
315 Type t1
= vt1
->dimensions(dim
);
317 interval i
= t2
->getInterval();
319 // cerr << "for sig fix delay : s1 = "
320 // << t1 << ':' << ppsig(s1) << ", s2 = "
321 // << t2 << ':' << ppsig(s2) << endl;
323 cerr
<< "ERROR : can't compute the min and max values of : " << ppsig(s2
) << endl
;
324 cerr
<< " used in delay expression : " << ppsig(sig
) << endl
;
325 cerr
<< " (probably a recursive signal)" << endl
;
327 } else if (i
.lo
< 0) {
328 cerr
<< "ERROR : possible negative values of : " << ppsig(s2
) << endl
;
329 cerr
<< " used in delay expression : " << ppsig(sig
) << endl
;
330 cerr
<< " " << i
<< endl
;
334 Type nt1
= castInterval(sampCast(t1
), reunion(t1
->getInterval(), interval(0,0)));
335 return makeVectorType(nt1
,dim
);
338 else if (isSigBinOp(sig
, &i
, s1
, s2
)) {
343 vector
<int> D1
, D2
, D3
;
344 Type b1
= t1
->dimensions(D1
);
345 Type b2
= t2
->dimensions(D2
);
347 if (maxdimensions(D1
, D2
, D3
)) {
348 Type b3
= castInterval(b1
| b2
, arithmetic(i
, b1
->getInterval(), b2
->getInterval()));
349 if ((i
>=kGT
) && (i
<=kNE
)) b3
= intCast(b3
);
350 Type t3
= makeVectorType(b3
, D3
);
353 cerr
<< "ERROR operation on incompatible types : " << *t1
<< " and " << *t2
354 << " in expression : " << ppsig(sig
) << endl
;
357 //cerr <<"type rule for : " << ppsig(sig) << " -> " << *t3 << endl;
358 //return (!gVectorSwitch && (i>=kGT) && (i<=kNE)) ? intCast(t3) : t3; // for comparaison operation the result is int
359 //return ((i>=kGT) && (i<=kNE)) ? intCast(t3) : t3; // for comparaison operation the result is int
362 else if (isSigIntCast(sig
, s1
)) return intCast(T(s1
,env
));
364 else if (isSigFloatCast(sig
, s1
)) return floatCast(T(s1
,env
));
366 else if (isSigFFun(sig
, ff
, ls
)) return infereFFType(ff
,ls
,env
);
368 else if (isSigFConst(sig
,type
,name
,file
)) return infereFConstType(type
);
370 else if (isSigFVar(sig
,type
,name
,file
)) return infereFVarType(type
);
372 else if (isSigButton(sig
)) { /*sig->setType(TGUI01);*/ return TGUI01
; }
374 else if (isSigCheckbox(sig
)) { /*sig->setType(TGUI01);*/ return TGUI01
; }
376 else if (isSigVSlider(sig
,label
,cur
,min
,max
,step
))
377 return castInterval(TGUI
,interval(tree2float(min
),tree2float(max
)));
379 else if (isSigHSlider(sig
,label
,cur
,min
,max
,step
))
380 return castInterval(TGUI
,interval(tree2float(min
),tree2float(max
)));
382 else if (isSigNumEntry(sig
,label
,cur
,min
,max
,step
))
383 return castInterval(TGUI
,interval(tree2float(min
),tree2float(max
)));
385 else if (isSigHBargraph(sig
, l
, x
, y
, s1
)) return T(s1
,env
);
387 else if (isSigVBargraph(sig
, l
, x
, y
, s1
)) return T(s1
,env
);
389 else if (isSigAttach(sig
, s1
, s2
)) { T(s2
,env
); return T(s1
,env
); }
391 else if (isRec(sig
, var
, body
)) return infereRecType(sig
, body
, env
);
393 else if (isProj(sig
, &i
, s1
)) return infereProjType(T(s1
,env
),i
,kScal
);
395 else if (isSigTable(sig
, id
, s1
, s2
)) { checkInt(checkInit(T(s1
,env
))); return makeTableType(checkInit(T(s2
,env
))); }
397 else if (isSigWRTbl(sig
, id
, s1
, s2
, s3
)) return infereWriteTableType(T(s1
,env
), T(s2
,env
), T(s3
,env
));
399 else if (isSigRDTbl(sig
, s1
, s2
)) return infereReadTableType(T(s1
,env
), T(s2
,env
));
401 else if (isSigGen(sig
, s1
)) return T(s1
,NULLTYPEENV
);
403 else if ( isSigDocConstantTbl(sig
, x
, y
) ) return infereDocConstantTblType(T(x
,env
), T(y
,env
));
404 else if ( isSigDocWriteTbl(sig
,x
,y
,z
,u
) ) return infereDocWriteTblType(T(x
,env
), T(y
,env
), T(z
,env
), T(u
,env
));
405 else if ( isSigDocAccessTbl(sig
, x
, y
) ) return infereDocAccessTblType(T(x
,env
), T(y
,env
));
407 else if (isSigSelect2(sig
,sel
,s1
,s2
)) {
408 SimpleType
*st1
, *st2
, *stsel
;
410 st1
= isSimpleType(T(s1
,env
));
411 st2
= isSimpleType(T(s2
,env
));
412 stsel
= isSimpleType(T(sel
,env
));
414 return makeSimpleType( st1
->nature()|st2
->nature(),
415 st1
->variability()|st2
->variability()|stsel
->variability(),
416 st1
->computability()|st2
->computability()|stsel
->computability(),
417 st1
->vectorability()|st2
->vectorability()|stsel
->vectorability(),
418 st1
->boolean()|st2
->boolean(),
419 reunion(st1
->getInterval(), st2
->getInterval())
423 else if (isSigSelect3(sig
,sel
,s1
,s2
,s3
)) { return T(sel
,env
)|T(s1
,env
)|T(s2
,env
)|T(s3
,env
); }
425 else if (isNil(sig
)) { Type t
= new TupletType(); /*sig->setType(t);*/ return t
; }
427 else if (isList(sig
)) { return T( hd(sig
),env
) * T( tl(sig
),env
); }
429 else if ( isSigVectorize(sig
, x
, y
) ) return infereVectorizeType(sig
, T(x
,env
), T(y
,env
));
430 else if ( isSigSerialize(sig
, x
) ) return infereSerializeType(sig
, T(x
,env
));
431 else if ( isSigConcat(sig
, x
, y
) ) return infereConcatType(T(x
,env
), T(y
,env
));
432 else if ( isSigVectorAt(sig
, x
, y
) ) return infereVectorAtType(T(x
,env
), T(y
,env
));
434 else if ( isSigUpSample(sig
, x
, y
) ) { T(x
,env
); return T(y
,env
); }
435 else if ( isSigDownSample(sig
, x
, y
) ) { T(x
,env
); return T(y
,env
); }
437 // unrecognized signal here
438 fprintf(stderr
, "ERROR in ***infereSigType()***, unrecognized signal : "); print(sig
, stderr
); fprintf(stderr
, "\n");
445 * Infere the type of a projection (selection) of a tuplet element
447 static Type
infereProjType(Type t
, int i
, int vec
)
449 TupletType
* tt
= isTupletType(t
);
451 cerr
<< "ERROR infering projection type, not a tuplet type : " << t
<< endl
;
454 //return (*tt)[i] ->promoteVariability(t->variability())
455 // ->promoteComputability(t->computability());
456 Type temp
= (*tt
)[i
] ->promoteVariability(t
->variability())
457 ->promoteComputability(t
->computability())
458 ->promoteVectorability(vec
/*t->vectorability()*/);
459 //->promoteBooleanity(t->boolean());
461 if(vec
==kVect
) temp
= vecCast(temp
);
462 //cerr << "infereProjType(" << t << ',' << i << ',' << vec << ")" << " -> " << temp << endl;
470 * Infere the type of the result of writing into a table
472 static Type
infereWriteTableType(Type tbl
, Type wi
, Type wd
)
474 TableType
* tt
= isTableType(tbl
);
476 cerr
<< "ERROR infering write table type, wrong table type : " << tbl
<< endl
;
479 SimpleType
* st
= isSimpleType(wi
);
480 if (st
== 0 || st
->nature() > kInt
) {
481 cerr
<< "ERROR infering write table type, wrong write index type : " << wi
<< endl
;
485 int n
= tt
->nature();
486 int v
= wi
->variability() | wd
->variability();
487 int c
= wi
->computability() | wd
->computability();
488 int vec
= wi
->vectorability() | wd
->vectorability();
490 return makeTableType(tt
->content(), n
, v
, c
, vec
);
497 * Infere the type of the result of reading a table
499 static Type
infereReadTableType(Type tbl
, Type ri
)
501 TableType
* tt
= isTableType(tbl
);
503 cerr
<< "ERROR infering read table type, wrong table type : " << tbl
<< endl
;
506 SimpleType
* st
= isSimpleType(ri
);
507 if (st
== 0 || st
->nature() > kInt
) {
508 cerr
<< "ERROR infering read table type, wrong write index type : " << ri
<< endl
;
512 Type temp
= tt
->content()->promoteVariability(ri
->variability()|tt
->variability())
513 ->promoteComputability(ri
->computability()|tt
->computability())
514 ->promoteVectorability(ri
->vectorability()|tt
->vectorability())
515 ->promoteBoolean(ri
->boolean()|tt
->boolean())
523 static Type
infereDocConstantTblType(Type size
, Type init
)
525 checkKonst(checkInt(checkInit(size
)));
530 static Type
infereDocWriteTblType(Type size
, Type init
, Type widx
, Type wsig
)
532 checkKonst(checkInt(checkInit(size
)));
535 ->promoteVariability(kSamp
) // difficult to tell, therefore kSamp to be safe
536 ->promoteComputability(widx
->computability()|wsig
->computability())
537 ->promoteVectorability(kScal
) // difficult to tell, therefore kScal to be safe
538 ->promoteNature(wsig
->nature()) // nature of the initial and written signal
539 ->promoteBoolean(wsig
->boolean()) // booleanity of the initial and written signal
544 static Type
infereDocAccessTblType(Type tbl
, Type ridx
)
547 ->promoteVariability(ridx
->variability())
548 ->promoteComputability(ridx
->computability())
549 ->promoteVectorability(ridx
->vectorability())
556 * Compute an initial type solution for a recursive block
557 * E1,E2,...En -> TREC,TREC,...TREC
559 static Type
initialRecType(Tree t
)
564 while (isList(t
)) { v
.push_back(TREC
); t
= tl(t
); };
565 return new TupletType(v
);
570 * Infere the type of e recursive block by trying solutions of
571 * increasing generality
573 static Type
infereRecType (Tree sig
, Tree body
, Tree env
)
575 assert(false); // we should not come here
581 * Infere the type of a foreign function call
583 static Type
infereFFType (Tree ff
, Tree ls
, Tree env
)
585 // une primitive externe ne peut pas se calculer au plus tot qu'a
586 // l'initialisation. Sa variabilite depend de celle de ses arguments
587 // sauf si elle n'en pas, auquel cas on considere que c'est comme
588 // rand() c'est a dire que le resultat varie a chaque appel.
589 if (ffarity(ff
)==0) {
590 // case of functions like rand()
591 return makeSimpleType(ffrestype(ff
),kSamp
,kInit
,kVect
,kNum
, interval());
593 // otherwise variability and computability depends
594 // arguments (OR of all arg types)
595 Type t
= makeSimpleType(kInt
,kKonst
,kInit
,kVect
,kNum
, interval());
596 while (isList(ls
)) { t
= t
|T(hd(ls
),env
); ls
=tl(ls
); }
597 // but the result type is defined by the function
600 return makeSimpleType( ffrestype(ff
),
611 * Infere the type of a foreign constant
613 static Type
infereFConstType (Tree type
)
615 // une constante externe ne peut pas se calculer au plus tot qu'a
616 // l'initialisation. Elle est constante, auquel cas on considere que c'est comme
617 // rand() c'est a dire que le resultat varie a chaque appel.
618 return makeSimpleType(tree2int(type
),kKonst
,kInit
,kVect
,kNum
, interval());
623 * Infere the type of a foreign variable
625 static Type
infereFVarType (Tree type
)
627 // une variable externe ne peut pas se calculer au plus tot qu'a
628 // l'execution. Elle est varie par blocs comme les éléments d'interface utilisateur.
629 return makeSimpleType(tree2int(type
),kBlock
,kExec
,kVect
,kNum
, interval());
634 * Infere the type of an extended (primitive) block
636 static Type
infereXType(Tree sig
, Tree env
)
638 //cerr << "infereXType :" << endl;
639 //cerr << "infereXType of " << *sig << endl;
640 xtended
* p
= (xtended
*) getUserData(sig
);
643 for (int i
= 0; i
< sig
->arity(); i
++) vt
.push_back(T(sig
->branch(i
), env
));
644 return p
->infereSigType(vt
);
652 * Compute the resulting interval of an arithmetic operation
653 * @param op code of the operation
654 * @param s1 interval of the left operand
655 * @param s2 interval of the right operand
656 * @return the resulting interval
659 static interval
arithmetic (int opcode
, const interval
& x
, const interval
& y
)
662 case kAdd
: return x
+y
;
663 case kSub
: return x
-y
;
664 case kMul
: return x
*y
;
665 case kDiv
: return x
/y
;
666 case kRem
: return x
%y
;
667 case kLsh
: return x
<<y
;
668 case kRsh
: return x
>>y
;
669 case kGT
: return x
>y
;
670 case kLT
: return x
<y
;
671 case kGE
: return x
>=y
;
672 case kLE
: return x
<=y
;
673 case kEQ
: return x
==y
;
674 case kNE
: return x
!=y
;
675 case kAND
: return x
&y
;
676 case kOR
: return x
|y
;
677 case kXOR
: return x
^y
;
679 cerr
<< "Unrecognized opcode : " << opcode
<< endl
;
688 static Type
infereVectorizeType(Tree sig
, Type Tsize
, Type T
)
690 SimpleType
* st
= isSimpleType(Tsize
);
691 if (st
&& st
->nature()==kInt
) {
692 interval i
= Tsize
->getInterval();
693 if (i
.valid
&& i
.lo
>= 0 && i
.lo
== i
.hi
) {
694 return new VectorType(int(i
.lo
+0.5), T
);
697 cerr
<< "ERROR in expression : " << ppsig(sig
) << endl
;
698 cerr
<< "the size of the vector is not of a valide type : " << *Tsize
<< endl
;
702 static Type
infereSerializeType(Tree sig
, Type Tvec
)
704 VectorType
* vt
= isVectorType(Tvec
);
706 return vt
->content();
708 cerr
<< "ERROR in expression : " << ppsig(sig
) << endl
;
709 cerr
<< "the 'serialize' operation can only be used on vectorized signals" << endl
;
714 static Type
infereConcatType(Type Tvec1
, Type Tvec2
)
716 VectorType
* vt1
= isVectorType(Tvec1
);
717 VectorType
* vt2
= isVectorType(Tvec2
);
720 Type ct1
= vt1
->content();
721 Type ct2
= vt2
->content();
723 return new VectorType(vt1
->size()+vt2
->size(), ct1
);
726 cerr
<< "ERROR in vector concatenation, the types : " << Tvec1
<< " and " << Tvec2
<< " are incompatible" << endl
;
730 static Type
infereVectorAtType(Type Tvec
, Type Tidx
)
732 VectorType
* vt
= isVectorType(Tvec
);
733 SimpleType
* it
= isSimpleType(Tidx
);
736 Type ct
= vt
->content();
738 interval i
= it
->getInterval();
739 if (i
.valid
&& i
.lo
>= 0 && i
.hi
<= n
) {
743 cerr
<< "ERROR in vector access, with types : " << Tvec
<< " and " << Tidx
<< endl
;