1 /* -*- mode:C++ ; compile-command: "g++ -DHAVE_CONFIG_H -I. -I.. -DIN_GIAC -DGIAC_GENERIC_CONSTANTS  -g -c -fno-strict-aliasing prog.cc -Wall" -*- */
2 #include "giacPCH.h"
3 
4 /*
5  *  Copyright (C) 2001,14 B. Parisse, Institut Fourier, 38402 St Martin d'Heres
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 using namespace std;
21 #ifndef HAVE_NO_PWD_H
22 #ifndef BESTA_OS
23 #include <pwd.h>
24 #endif
25 #endif
26 #ifdef FXCG
27 extern "C" {
28 #include <rtc.h>
29 }
30 #endif
31 #include <stdexcept>
32 #include <cmath>
33 #include <cstdlib>
34 #include <algorithm>
35 #if !defined GIAC_HAS_STO_38 && !defined NSPIRE && !defined FXCG
36 #include <fstream>
37 #endif
38 #include "prog.h"
39 #include "identificateur.h"
40 #include "symbolic.h"
41 #include "identificateur.h"
42 #include "usual.h"
43 #include "sym2poly.h"
44 #include "subst.h"
45 #include "plot.h"
46 #include "tex.h"
47 #include "input_parser.h"
48 #include "input_lexer.h"
49 #include "rpn.h"
50 #include "help.h"
51 #include "ti89.h" // for _unarchive_ti
52 #include "permu.h"
53 #include "modpoly.h"
54 #include "unary.h"
55 #include "input_lexer.h"
56 #include "maple.h"
57 #include "derive.h"
58 #include "giacintl.h"
59 #include "misc.h"
60 #include "lin.h"
61 #include "pari.h"
62 #include "intg.h"
63 #include "csturm.h"
64 #include "sparse.h"
65 #include "giacintl.h"
66 // #include "input_parser.h"
67 #ifdef HAVE_UNISTD_H
68 #include <unistd.h>
69 #endif
70 #ifdef HAVE_LIBDL
71 #include <dlfcn.h>
72 #endif // HAVE_LIBDL
73 #ifdef USE_GMP_REPLACEMENTS
74 #undef HAVE_GMPXX_H
75 #undef HAVE_LIBMPFR
76 #undef HAVE_LIBPARI
77 #endif
78 
79 //#ifdef BESTA_OS
80 //unsigned int PrimeGetNow();
81 //#endif
82 
83 #ifdef RTOS_THREADX
84 u32 PrimeGetNow();
85 extern "C" uint32_t mainThreadStack[];
86 #else
87 #if !defined BESTA_OS && !defined FXCG
88 #include <time.h>
89 #endif
90 #endif
91 
92 #ifdef EMCC
93 #include <emscripten.h>
94 #endif
95 
96 #ifdef KHICAS
97 #include "kdisplay.h"
98 #endif
99 
100 #ifndef NO_NAMESPACE_GIAC
101 namespace giac {
102 #endif // ndef NO_NAMESPACE_GIAC
103 
104 #if 1 // defined(GIAC_HAS_STO_38) && defined(VISUALC)
105   const int rand_max2=2147483647;
106 #else
107   const int rand_max2=RAND_MAX;
108 #endif
109   const double inv_rand_max2_p1=1.0/(rand_max2+1.0);
110 
111 #ifdef HAVE_LIBDL
112   modules_tab giac_modules_tab;
113 #endif
114 
alert(const string & s,GIAC_CONTEXT)115   void alert(const string & s,GIAC_CONTEXT){
116 #ifdef EMCC
117     EM_ASM_ARGS({
118 	if (UI.warnpy){
119           var msg = Pointer_stringify($0); // Convert message to JS string
120           alert(msg);                      // Use JS version of alert
121         }
122       }, s.c_str());
123 #endif
124     *logptr(contextptr) << s << '\n';
125   }
126 
equaltosto(const gen & g,GIAC_CONTEXT)127   gen equaltosto(const gen & g,GIAC_CONTEXT){
128     if (g.type<=_IDNT || !eval_equaltosto(contextptr))
129       return g;
130     if (g.is_symb_of_sommet(at_add_autosimplify)){
131       return symbolic(g._SYMBptr->sommet,equaltosto(g._SYMBptr->feuille,contextptr));
132     }
133     if (is_equal(g)){
134       vecteur v=*g._SYMBptr->feuille._VECTptr;
135       gen a;
136       if (v.size()==2)
137 	a=v.back();
138       else
139 	a=gen(vecteur(v.begin()+1,v.end()),g.subtype);
140       if (v.front().type==_IDNT)
141 	return symb_sto(a,v.front());
142       if (v.front().type==_VECT){
143 	vecteur w=*v.front()._VECTptr;
144 	for (int i=0;i<w.size();++i){
145 	  if (w[i].type!=_IDNT)
146 	    return g;
147 	}
148 	return symb_sto(a,v.front());
149       }
150     }
151     return g;
152   }
153 
equaltostov(const vecteur & v,GIAC_CONTEXT)154   vecteur equaltostov(const vecteur & v,GIAC_CONTEXT){
155     vecteur w(v);
156     iterateur it=w.begin(),itend=w.end();
157     for (;it!=itend;++it)
158       *it=equaltosto(*it,contextptr);
159     return w;
160   }
161 
attoof(const gen & g)162   gen attoof(const gen & g){
163     if (g.type==_VECT){
164       vecteur v=*g._VECTptr;
165       iterateur it=v.begin(),itend=v.end();
166       for (;it!=itend;++it)
167        *it=attoof(*it);
168       return gen(v,g.subtype);
169     }
170     if (g.type!=_SYMB)
171       return g;
172     if (g._SYMBptr->sommet!=at_at)
173       return symbolic(g._SYMBptr->sommet,attoof(g._SYMBptr->feuille));
174     if (g._SYMBptr->feuille.type!=_VECT || g._SYMBptr->feuille._VECTptr->size()<=1) // not somehting that I recognize as a proper parameter list, just return as before
175       return symbolic(at_of,attoof(g._SYMBptr->feuille));
176     // This looks like it is a vector of at least 2 objects. The first one should be the variable to do an at/of on and all the rest should be indices that needs to be incremented
177     vecteur v=*g._SYMBptr->feuille._VECTptr;
178     iterateur it=v.begin()+1,itend=v.end(); // from item 1 to n-1 in the vector
179     for (;it!=itend;++it)
180       *it=attoof(*it)+gen(1); // add 1 to the object
181     return symbolic(at_of,attoof(gen(v,g._SYMBptr->feuille.subtype))); // return the of(vector with modified indices) gen
182   }
183 
prog_eval_level(GIAC_CONTEXT)184   static int prog_eval_level(GIAC_CONTEXT){
185     if (int i=prog_eval_level_val(contextptr))
186       return i;
187     return std::max(1,eval_level(contextptr));
188   }
189 
check_secure()190   gen check_secure(){
191     if (secure_run)
192       return gensizeerr(gettext("Running in secure mode"));
193     return 0;
194   }
195 
indent(GIAC_CONTEXT)196   string indent(GIAC_CONTEXT){
197     if (xcas_mode(contextptr)==3)
198       return "\n:"+string(debug_ptr(contextptr)->indent_spaces,' ');
199     else
200       return " \n"+string(debug_ptr(contextptr)->indent_spaces,' ');
201   }
202 
indent2(GIAC_CONTEXT)203   static string indent2(GIAC_CONTEXT){
204     return string(debug_ptr(contextptr)->indent_spaces,' ');
205   }
206 
207   // static gen substsametoequal(const gen & g){  return symbolic(at_subst,apply(g,sametoequal)); }
208 
209   // static gen subssametoequal(const gen & g){  return symbolic(at_subs,apply(g,sametoequal));  }
210 
211   // static gen maplesubssametoequal(const gen & g){  return symbolic(at_maple_subs,apply(g,sametoequal)); }
212 
equaltosame(const gen & a)213   gen equaltosame(const gen & a){
214     // full replacement of = by == has been commented to avoid
215     // problems with tests like: if (limit(...,x=0,..))
216     /*
217     unary_function_ptr equaltosametab1[]={at_equal,at_subst,at_subs,at_maple_subs};
218     vector<unary_function_ptr> substin(equaltosametab1,equaltosametab1+sizeof(equaltosametab1)/sizeof(unary_function_ptr));
219     gen_op equaltosametab2[]={symb_same,substsametoequal,subssametoequal,maplesubssametoequal};
220     vector<gen_op> substout(equaltosametab2,equaltosametab2+sizeof(equaltosametab2)/sizeof(gen_op));
221     gen tmp=subst(a,substin,substout,true);
222     return tmp;
223     */
224     if ( is_equal(a))
225       return symb_same(a._SYMBptr->feuille._VECTptr->front(),a._SYMBptr->feuille._VECTptr->back());
226     else
227       return a;
228   }
229 
sametoequal(const gen & a)230   gen sametoequal(const gen & a){
231     if ( (a.type==_SYMB) && (a._SYMBptr->sommet==at_same) )
232       return symb_equal(a._SYMBptr->feuille._VECTptr->front(),a._SYMBptr->feuille._VECTptr->back());
233     else
234       return a;
235   }
236 
increment_instruction(const const_iterateur & it0,const const_iterateur & itend,debug_struct * dbgptr)237   static void increment_instruction(const const_iterateur & it0,const const_iterateur & itend,debug_struct * dbgptr){
238     const_iterateur it=it0;
239     for (;it!=itend;++it)
240       increment_instruction(*it,dbgptr);
241   }
242 
increment_instruction(const vecteur & v,debug_struct * dbgptr)243   void increment_instruction(const vecteur & v,debug_struct * dbgptr){
244     const_iterateur it=v.begin(),itend=v.end();
245     for (;it!=itend;++it)
246       increment_instruction(*it,dbgptr);
247   }
248 
increment_instruction(const gen & arg,debug_struct * dbgptr)249   void increment_instruction(const gen & arg,debug_struct * dbgptr){
250     // cerr << debug_ptr(contextptr)->current_instruction << " " << arg <<'\n';
251     ++dbgptr->current_instruction;
252     if (arg.type!=_SYMB)
253       return;
254     const unary_function_ptr & u=arg._SYMBptr->sommet;
255     const gen & f=arg._SYMBptr->feuille;
256     const unary_function_eval * uptr=dynamic_cast<const unary_function_eval *>(u.ptr());
257     if (uptr && uptr->op==_ifte){
258       --dbgptr->current_instruction;
259       increment_instruction(*f._VECTptr,dbgptr);
260       return;
261     }
262     if ( (u==at_local) || (uptr && uptr->op==_for) ){
263       gen F(f._VECTptr->back());
264       if (F.type!=_VECT){
265 	if (F.is_symb_of_sommet(at_bloc) && F._SYMBptr->feuille.type==_VECT)
266 	  increment_instruction(*F._SYMBptr->feuille._VECTptr,dbgptr);
267 	else
268 	  increment_instruction(F,dbgptr);
269       }
270       else
271 	increment_instruction(*F._VECTptr,dbgptr);
272       return;
273     }
274     if (u==at_bloc){
275       if (f.type!=_VECT)
276 	increment_instruction(f,dbgptr);
277       else
278 	increment_instruction(*f._VECTptr,dbgptr);
279       return;
280     }
281     if (u==at_try_catch){
282       increment_instruction(f._VECTptr->front(),dbgptr);
283       increment_instruction(f._VECTptr->back(),dbgptr);
284     }
285   }
286 
increment_instruction(const gen & arg,GIAC_CONTEXT)287   void increment_instruction(const gen & arg,GIAC_CONTEXT){
288     increment_instruction(arg,debug_ptr(contextptr));
289   }
290 
concatenate(const vector<string> & v)291   static string concatenate(const vector<string> & v){
292     vector<string>::const_iterator it=v.begin(),itend=v.end();
293     string res;
294     for (;it!=itend;++it){
295       res=res + "  "+*it;
296     }
297     return res;
298   }
299 
debug_print(const vecteur & arg,vector<string> & v,GIAC_CONTEXT)300   void debug_print(const vecteur & arg,vector<string> & v,GIAC_CONTEXT){
301     const_iterateur it=arg.begin(),itend=arg.end();
302     for (;it!=itend;++it){
303       if (it->is_symb_of_sommet(at_program)){
304 	vector<string> tmp;
305 	debug_print(*it,tmp,contextptr);
306 	v.push_back(concatenate(tmp));
307       }
308       debug_print(*it,v,contextptr);
309     }
310   }
311 
printaslocalvars(const gen & loc,GIAC_CONTEXT)312   static string printaslocalvars(const gen &loc,GIAC_CONTEXT){
313     gen locals(loc);
314     if (locals._VECTptr->size()==1)
315       return locals._VECTptr->front().print(contextptr);
316     locals.subtype=_SEQ__VECT;
317     return locals.print(contextptr);
318   }
319 
320   // convert back increment and decrement to sto
from_increment(const gen & g)321   static gen from_increment(const gen & g){
322     int type=0;
323     if (g.is_symb_of_sommet(at_increment))
324       type=1;
325     if (g.is_symb_of_sommet(at_decrement))
326       type=-1;
327     if (type){
328       gen & f =g._SYMBptr->feuille;
329       if (f.type!=_VECT)
330 	return symbolic(at_sto,gen(makevecteur(symbolic(at_plus,makevecteur(f,type)),f),_SEQ__VECT));
331       vecteur & v = *f._VECTptr;
332       if (v.size()!=2)
333 	return gensizeerr(gettext("from_increment"));
334       return symbolic(at_sto,gen(makevecteur(symbolic(at_plus,gen(makevecteur(v[0],type*v[1]),_SEQ__VECT)),v[0]),_SEQ__VECT));
335     }
336     return g;
337   }
338 
debug_print(const gen & e,vector<string> & v,GIAC_CONTEXT)339   void debug_print(const gen & e,vector<string>  & v,GIAC_CONTEXT){
340     if (e.type!=_SYMB){
341       v.push_back(indent2(contextptr)+e.print(contextptr));
342       return ;
343     }
344     bool is38=abs_calc_mode(contextptr)==38;
345     bool python=python_compat(contextptr);
346     unary_function_ptr u=e._SYMBptr->sommet;
347     gen f=e._SYMBptr->feuille;
348     const unary_function_eval * uptr=dynamic_cast<const unary_function_eval *>(u.ptr());
349     if (uptr && uptr->op==_ifte){
350       string s=indent2(contextptr);
351       s += python?"if ":(is38?"IF ":"if(");
352       vecteur w=*f._VECTptr;
353       s += w.front().print(contextptr);
354       s += python?":":(is38?" THEN/ELSE":")");
355       v.push_back(s);
356       debug_ptr(contextptr)->indent_spaces += 1;
357       debug_print(w[1],v,contextptr);
358       debug_ptr(contextptr)->indent_spaces += 1;
359       debug_print(w[2],v,contextptr);
360       debug_ptr(contextptr)->indent_spaces -=2;
361       return ;
362     }
363     if (u==at_local){
364       string s(indent2(contextptr));
365       s += python?"# local ":(is38?"LOCAL ":"local ");
366       gen local_global=f._VECTptr->front(),locals(gen2vecteur(local_global)),globals(vecteur(0));
367       if (local_global.type==_VECT && local_global._VECTptr->size()==2){
368 	gen f=local_global._VECTptr->front(),b=local_global._VECTptr->back();
369 	if (f.type!=_IDNT){
370 	  locals=gen2vecteur(f);
371 	  globals=gen2vecteur(b);
372 	}
373       }
374       if (globals._VECTptr->empty())
375 	s += printaslocalvars(locals,contextptr);
376       else
377 	s += local_global.print(contextptr);
378       v.push_back(s);
379       debug_ptr(contextptr)->indent_spaces += 2;
380       f=f._VECTptr->back();
381       if (f.type!=_VECT)
382 	debug_print(f,v,contextptr);
383       else
384 	debug_print(*f._VECTptr,v,contextptr);
385       debug_ptr(contextptr)->indent_spaces -= 2;
386       return;
387     }
388     if (uptr && uptr->op==_for){
389       vecteur w=*f._VECTptr;
390       string s(indent2(contextptr));
391       bool done=false;
392       if (python){
393 	gen inc(from_increment(w[2]));
394 	if (inc.is_symb_of_sommet(at_sto) && inc._SYMBptr->feuille[1].type==_IDNT){
395 	  gen index=inc._SYMBptr->feuille[1];
396 	  if (inc._SYMBptr->feuille[0]==index+1 && w[0].is_symb_of_sommet(at_sto) && w[0]._SYMBptr->feuille[1]==index){
397 	    gen start=w[0]._SYMBptr->feuille[0];
398 	    if (w[1].type==_SYMB && (w[1]._SYMBptr->sommet==at_inferieur_egal || w[1]._SYMBptr->sommet==at_inferieur_strict) && w[1]._SYMBptr->feuille[0]==index){
399 	      int large=w[1]._SYMBptr->sommet==at_inferieur_egal?1:0;
400 	      gen stop=w[1]._SYMBptr->feuille[1];
401 	      s += "for "+index.print(contextptr)+" in range(";
402 	      if (start!=0)
403 		s +=start.print(contextptr)+",";
404 	      s += (stop+large).print(contextptr)+"):";
405 	      done=true;
406 	    }
407 	  }
408 	}
409       }
410       if (w[0].type==_INT_ && w[2].type==_INT_){
411 	s += python?"while ":(is38?"WHILE(":"while(");
412 	s += w[1].print(contextptr);
413 	s += python?":":")";
414 	done=true;
415       }
416       if (!done){
417 	s += is38?"FOR(":"for(";
418 	s += w[0].print(contextptr)+";"+w[1].print(contextptr)+";"+w[2].print(contextptr)+")";
419       }
420       v.push_back(s);
421       debug_ptr(contextptr)->indent_spaces += 2;
422       f=f._VECTptr->back();
423       if ((f.type==_SYMB) && (f._SYMBptr->sommet==at_bloc))
424 	f=f._SYMBptr->feuille;
425       if (f.type!=_VECT)
426 	debug_print(f,v,contextptr);
427       else
428 	debug_print(*f._VECTptr,v,contextptr);
429       debug_ptr(contextptr)->indent_spaces -= 2;
430       return;
431     }
432     if (u==at_bloc){
433       v.push_back(string(indent2(contextptr)+"bloc"));
434       debug_ptr(contextptr)->indent_spaces += 2;
435       if (f.type!=_VECT)
436 	debug_print(f,v,contextptr);
437       else
438 	debug_print(*f._VECTptr,v,contextptr);
439       debug_ptr(contextptr)->indent_spaces -= 2;
440       return;
441     }
442     if (u==at_try_catch){
443       // cerr << f << '\n';
444       v.push_back(string(indent2(contextptr)+"try"));
445       debug_ptr(contextptr)->indent_spaces += 1;
446       debug_print(f._VECTptr->front(),v,contextptr);
447       debug_ptr(contextptr)->indent_spaces += 1;
448       debug_print(f._VECTptr->back(),v,contextptr);
449       debug_ptr(contextptr)->indent_spaces -=2;
450       return;
451     }
452     v.push_back(indent2(contextptr)+e.print(contextptr));
453   }
454 
rm_checktype(const vecteur & v,GIAC_CONTEXT)455   static vecteur rm_checktype(const vecteur & v,GIAC_CONTEXT){
456     vecteur addvars(v);
457     iterateur it=addvars.begin(),itend=addvars.end();
458     for (;it!=itend;++it){
459       if (it->is_symb_of_sommet(at_deuxpoints))
460 	*it=it->_SYMBptr->feuille._VECTptr->front();
461       if (it->is_symb_of_sommet(at_check_type))
462 	*it=it->_SYMBptr->feuille._VECTptr->back();
463       if (it->is_symb_of_sommet(at_sto))
464 	*it=it->_SYMBptr->feuille._VECTptr->back();
465       if (it->is_symb_of_sommet(at_equal))
466 	*it=it->_SYMBptr->feuille._VECTptr->front();
467     }
468     return addvars;
469   }
470   // res1= list of assignation with =, res2= list of non declared global vars, res3= list of declared global vars, res4=list of functions
check_local_assign(const gen & g,const vecteur & prog_args,vecteur & res1,vecteur & res2,vecteur & res3,vecteur & res4,bool testequal,GIAC_CONTEXT)471   void check_local_assign(const gen & g,const vecteur & prog_args,vecteur & res1,vecteur & res2,vecteur & res3,vecteur & res4,bool testequal,GIAC_CONTEXT){
472     if (g.is_symb_of_sommet(at_double_deux_points))
473       return;
474     if (g.is_symb_of_sommet(at_local)){
475       gen &f=g._SYMBptr->feuille;
476       if (f.type!=_VECT || f._VECTptr->size()!=2)
477 	return;
478       gen declaredvars=f._VECTptr->front();
479       if (declaredvars.type==_VECT && declaredvars._VECTptr->size()==2){
480 	vecteur f1(gen2vecteur(declaredvars._VECTptr->front()));
481 	for (int i=0;i<int(f1.size());++i){
482 	  if (f1[i].is_symb_of_sommet(at_equal))
483 	    f1[i]=f1[i]._SYMBptr->feuille[0];
484 	}
485 	vecteur f2(gen2vecteur(declaredvars._VECTptr->back()));
486 	res3=mergevecteur(res3,f2);
487 	declaredvars=mergevecteur(f1,f2);
488       }
489       vecteur addvars(rm_checktype(gen2vecteur(declaredvars),contextptr));
490       vecteur newvars(mergevecteur(prog_args,addvars));
491       // check_local_assign(f._VECTptr->front(),newvars,res1,res2,res3,res4,testequal,contextptr);
492       check_local_assign(f._VECTptr->back(),newvars,res1,res2,res3,res4,testequal,contextptr);
493       return;
494     }
495     if (g.is_symb_of_sommet(at_sto)){
496       gen &f=g._SYMBptr->feuille;
497       if (f.type==_VECT && f._VECTptr->size()==2 && f._VECTptr->front().is_symb_of_sommet(at_program)){
498 	res4.push_back(f._VECTptr->back());
499 	gen & ff = f._VECTptr->front()._SYMBptr->feuille;
500 	if (ff.type==_VECT && ff._VECTptr->size()==3){
501 	  vecteur alt_prog_args(gen2vecteur(ff._VECTptr->front()));
502 	  check_local_assign(ff._VECTptr->back(),alt_prog_args,res1,res2,res3,res4,testequal,contextptr);
503 	}
504 	return;
505       }
506     }
507     if (g.is_symb_of_sommet(at_ifte) || g.is_symb_of_sommet(at_when)){
508       vecteur v=lop(g,at_array_sto);
509       if (!v.empty() && logptr(contextptr))
510 	*logptr(contextptr) << gettext("Warning, =< is in-place assign, check ") << v << '\n';
511     }
512     if (g.is_symb_of_sommet(at_bloc) ||
513 	g.is_symb_of_sommet(at_for) || g.is_symb_of_sommet(at_pour) ||
514 	g.is_symb_of_sommet(at_tantque) || g.is_symb_of_sommet(at_si) ||
515 	g.is_symb_of_sommet(at_sialorssinon) ||
516 	g.is_symb_of_sommet(at_ifte) || g.is_symb_of_sommet(at_when)){
517       check_local_assign(g._SYMBptr->feuille,prog_args,res1,res2,res3,res4,testequal,contextptr);
518       return;
519     }
520     if (testequal && is_equal(g)){
521       if (g._SYMBptr->feuille.type==_VECT && g._SYMBptr->feuille._VECTptr->size()==2 && g._SYMBptr->feuille._VECTptr->front().type!=_INT_ )
522 	res1.push_back(g);
523       return;
524     }
525     if (g.is_symb_of_sommet(at_of)){
526       gen & f=g._SYMBptr->feuille;
527       if (f.type!=_VECT || f._VECTptr->size()!=2)
528 	return;
529       if (python_compat(contextptr) || protecteval(f._VECTptr->front(),1,contextptr)!=f._VECTptr->front())
530 	check_local_assign(f._VECTptr->back(),prog_args,res1,res2,res3,res4,false,contextptr);
531       else
532 	check_local_assign(f,prog_args,res1,res2,res3,res4,false,contextptr);
533       return;
534     }
535     if (g.type==_SYMB){
536       check_local_assign(g._SYMBptr->feuille,prog_args,res1,res2,res3,res4,false,contextptr);
537       return;
538     }
539     if (g.type!=_VECT){
540       vecteur l(gen2vecteur(_lname(g,contextptr)));
541       const_iterateur it=l.begin(),itend=l.end();
542       for (;it!=itend;++it){
543 	if (!equalposcomp(res2,*it) && !equalposcomp(prog_args,*it))
544 	  res2.push_back(*it);
545       }
546       return;
547     }
548     const_iterateur it=g._VECTptr->begin(),itend=g._VECTptr->end();
549     for (;it!=itend;++it){
550       check_local_assign(*it,prog_args,res1,res2,res3,res4,testequal,contextptr);
551     }
552   }
is_constant_idnt(const gen & g)553   bool is_constant_idnt(const gen & g){
554     return g==cst_pi || g==cst_euler_gamma || is_inf(g) || is_undef(g) || (g.type==_IDNT && (strcmp(g._IDNTptr->id_name,"i")==0 || strcmp(g._IDNTptr->id_name,"None")==0 || strcmp(g._IDNTptr->id_name,"cmath")==0 || strcmp(g._IDNTptr->id_name,"math")==0 || strcmp(g._IDNTptr->id_name,"kandinsky")==0 || strcmp(g._IDNTptr->id_name,"pass")==0));
555   }
556 
557   bool warn_equal_in_prog=true,warn_symb_program_sto=true;
_warn_equal_in_prog(const gen & g,GIAC_CONTEXT)558   gen _warn_equal_in_prog(const gen & g,GIAC_CONTEXT){
559     if (is_zero(g) && g.type!=_VECT){
560       warn_equal_in_prog=false;
561       return string2gen(gettext("Warning disabled"),false);
562     }
563     if (is_one(g)){
564       warn_equal_in_prog=true;
565       return string2gen(gettext("Warning enabled"),false);
566     }
567     return warn_equal_in_prog;
568   }
569   static const char _warn_equal_in_prog_s []="warn_equal_in_prog";
570   static define_unary_function_eval (__warn_equal_in_prog,&_warn_equal_in_prog,_warn_equal_in_prog_s);
571   define_unary_function_ptr5( at_warn_equal_in_prog ,alias_at_warn_equal_in_prog,&__warn_equal_in_prog,0,true);
572 
573   // Return the names of variables that are not local in g
574   // and the equality that are not used (warning = instead of := )
check_local_assign(const gen & g,GIAC_CONTEXT)575   string check_local_assign(const gen & g,GIAC_CONTEXT){
576     string res;
577     if (g.type==_VECT){
578       const_iterateur it=g._VECTptr->begin(),itend=g._VECTptr->end();
579       for (;it!=itend;++it)
580 	res += check_local_assign(*it,contextptr);
581       return res;
582     }
583     if (g.is_symb_of_sommet(at_nodisp))
584       return check_local_assign(g._SYMBptr->feuille,contextptr);
585     if (g.is_symb_of_sommet(at_sto)){
586       gen & f =g._SYMBptr->feuille;
587       if (f.type!=_VECT || f._VECTptr->size()!=2)
588 	return res;
589       res=check_local_assign(f._VECTptr->front(),contextptr);
590       return res.substr(0,res.size()-1)+"\n//"+gettext(" compiling ")+f._VECTptr->back().print(contextptr)+'\n';
591     }
592     if (!g.is_symb_of_sommet(at_program))
593       return res;
594     gen & f=g._SYMBptr->feuille;
595     if (f.type!=_VECT || f._VECTptr->size()!=3)
596       return gettext("// Invalid program");
597     vecteur & v =*f._VECTptr;
598     vecteur vars=gen2vecteur(v[0]),res1,res2,res3,res4;
599     // add implicit declaration of global var in argument optional value
600     for (int i=0;i<vars.size();i++){
601       if (vars[i].is_symb_of_sommet(at_equal)){
602 	gen g=vars[i]._SYMBptr->feuille[1];
603 	res2=mergevecteur(res2,lidnt(g));
604       }
605     }
606     res2.push_back(undef);
607     vars=rm_checktype(vars,contextptr);
608     for (unsigned i=0;i<vars.size();++i){
609       if (equalposcomp(vars,vars[i])!=int(i+1))
610 	res += gettext("// Warning, duplicate argument name: ")+vars[i].print(contextptr)+'\n';
611     }
612     gen prog=v.back();
613     check_local_assign(prog,vars,res1,res2,res3,res4,true,contextptr);
614     int rs=int(res2.size());
615     for (int i=0;i<rs;i++){
616       if (is_constant_idnt(res2[i])){
617 	res2.erase(res2.begin()+i);
618 	--i; --rs;
619       }
620     }
621     if (warn_equal_in_prog && !res1.empty()){ // syntax = for := is now accepted
622       res += gettext("// Warning, assignation is :=, check the lines below:\n");
623       res += "// (Run warn_equal_in_prog(0) to disable this warning)\n";
624       const_iterateur it=res1.begin(),itend=res1.end();
625       for (;it!=itend;++it){
626 	res += '\n'+it->print(contextptr);
627       }
628       res +="\n";
629     }
630     if (res2.size()>=1){
631       res+=gettext("// Warning: ");
632       const_iterateur it=res2.begin(),itend=res2.end();
633       for (;it!=itend;++it){
634 	// pi already checked if (*it!=cst_pi)
635 	res += it->print(contextptr)+",";
636       }
637       res +=gettext(" declared as global variable(s). If symbolic variables are required, declare them as local and run purge\n");
638     }
639     if (res.empty())
640       return first_error_line(contextptr)?gettext("// Error(s)\n"):gettext("// Success\n");
641     else
642       return res;
643   }
644 
printascheck_type(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)645   static string printascheck_type(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
646     if ( (feuille.type!=_VECT) || (feuille._VECTptr->size()!=2) )
647       return string(sommetstr)+('('+feuille.print(contextptr)+')');
648     return print_the_type(feuille._VECTptr->front().val,contextptr)+' '+feuille._VECTptr->back().print(contextptr);
649   }
650 
symb_check_type(const gen & args,GIAC_CONTEXT)651   gen symb_check_type(const gen & args,GIAC_CONTEXT){
652     return symbolic(at_check_type,args);
653   }
_check_type(const gen & args,GIAC_CONTEXT)654   gen _check_type(const gen & args,GIAC_CONTEXT){
655     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
656     if (args.type!=_VECT)
657       return symb_check_type(args,contextptr);
658     if (args._VECTptr->size()!=2)
659       return gensizeerr(gettext("check_type must have 2 args"));
660     gen res=args._VECTptr->back();
661     gen req=args._VECTptr->front();
662     if (req.type!=_INT_) // FIXME check for matrix(...) or vector(...)
663       return res;
664     int type;
665     switch (res.type){
666     case _INT_:
667       type=_ZINT;
668       break;
669     case _REAL:
670       type=_DOUBLE_;
671       break;
672     default:
673       type=res.type;
674       break;
675     }
676     if (req.val==_MAPLE_LIST){
677       if (type==_VECT)
678 	return res;
679       return gensizeerr(contextptr);
680     }
681     if (type==req.val)
682       return res;
683     if (type==_ZINT && type==(req.val &0xff) ){
684       if (req.val==_POSINT && is_strictly_positive(res,contextptr))
685 	return res;
686       if (req.val==_NEGINT && is_strictly_positive(-res,contextptr))
687 	return res;
688       if (req.val==_NONPOSINT && is_positive(-res,contextptr))
689 	return res;
690       if (req.val==_NONNEGINT && is_positive(res,contextptr))
691 	return res;
692     }
693     return gentypeerr(gettext("Argument should be of type ")+print_the_type(args._VECTptr->front().val,contextptr));
694   }
695   static const char _check_type_s []="check_type";
696   static define_unary_function_eval2_index (118,__check_type,&symb_check_type,_check_type_s,&printascheck_type);
697   define_unary_function_ptr( at_check_type ,alias_at_check_type ,&__check_type);
698 
699   // static gen symb_type(const gen & args){  return symbolic(at_type,args); }
_type(const gen & args,GIAC_CONTEXT)700   gen _type(const gen & args,GIAC_CONTEXT){
701     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
702     int type;
703     switch (args.type){
704     case _INT_:
705       type=_ZINT;
706       break;
707     case _REAL:
708 #ifndef NO_RTTI
709       if (dynamic_cast<real_interval *>(args._REALptr))
710 	type=_FLOAT_;
711       else
712 #endif
713 	type=_DOUBLE_;
714       break;
715     default:
716       if (args.is_symb_of_sommet(at_program))
717 	type=_FUNC;
718       else
719 	type=args.type;
720     }
721     gen tmp(type);
722     tmp.subtype=1;
723     return tmp;
724   }
725   static const char _type_s []="type";
726   static define_unary_function_eval (__type,&_type,_type_s);
727   define_unary_function_ptr5( at_type ,alias_at_type,&__type,0,true);
728 
_nop(const gen & a,GIAC_CONTEXT)729   gen _nop(const gen & a,GIAC_CONTEXT){
730     if ( a.type==_STRNG &&  a.subtype==-1) return  a;
731     if (a.type==_VECT && a.subtype==_SEQ__VECT){
732       // Workaround so that sequences inside spreadsheet are saved as []
733       gen tmp=a;
734       tmp.subtype=0;
735       return tmp;
736     }
737     return a;
738   }
739   static const char _nop_s []="nop";
740   static define_unary_function_eval (__nop,&_nop,_nop_s);
741   define_unary_function_ptr5( at_nop ,alias_at_nop,&__nop,0,true);
742 
_Nop(const gen & a,GIAC_CONTEXT)743   gen _Nop(const gen & a,GIAC_CONTEXT){
744     if ( a.type==_STRNG &&  a.subtype==-1) return  a;
745     return a;
746   }
747   static const char _Nop_s []="Nop";
748   static define_unary_function_eval (__Nop,&_Nop,_Nop_s);
749   define_unary_function_ptr5( at_Nop ,alias_at_Nop,&__Nop,0,true);
750 
printasinnerbloc(const gen & feuille,GIAC_CONTEXT)751   string printasinnerbloc(const gen & feuille,GIAC_CONTEXT){
752     if ( (feuille.type==_SYMB) && feuille._SYMBptr->sommet==at_bloc)
753       return printasinnerbloc(feuille._SYMBptr->feuille,contextptr);
754     if (feuille.type!=_VECT)
755       return indent(contextptr)+feuille.print(contextptr);
756     const_iterateur it=feuille._VECTptr->begin(),itend=feuille._VECTptr->end();
757     string res;
758     if (it==itend)
759       return res;
760     for (;;){
761       res += indent(contextptr)+it->print(contextptr);
762       ++it;
763       if (it==itend)
764 	return res;
765       if (xcas_mode(contextptr)!=3)
766 	res += ";";
767     }
768   }
769 
local_init(const gen & e,vecteur & non_init_vars,vecteur & initialisation_seq)770   static void local_init(const gen & e,vecteur & non_init_vars,vecteur & initialisation_seq){
771     vecteur v;
772     if (e.type!=_VECT)
773       v=vecteur(1,e);
774     else
775       v=*e._VECTptr;
776     if (v.size()==2 && v.front().type==_VECT)
777       v=*v.front()._VECTptr;
778     const_iterateur it=v.begin(),itend=v.end();
779     for (;it!=itend;++it){
780       if (it->type==_IDNT){
781 	non_init_vars.push_back(*it);
782 	continue;
783       }
784       if ( (it->type==_SYMB) && (it->_SYMBptr->sommet==at_sto)){
785 	non_init_vars.push_back(it->_SYMBptr->feuille._VECTptr->back());
786 	initialisation_seq.push_back(*it);
787       }
788     }
789   }
790 
add_global(const gen & i,GIAC_CONTEXT)791   static gen add_global(const gen & i,GIAC_CONTEXT){
792 #ifndef NO_STDEXCEPT
793     if (i.type==_IDNT)
794 #endif
795       return identificateur("global_"+i.print(contextptr));
796     return gensizeerr(gettext("Proc Parameters"));
797   }
798 
remove_empty_lines(const string & s)799   static string remove_empty_lines(const string & s){
800     // return s;
801     string res;
802     int ss=int(s.size()),ns=0;
803     bool blank=true;
804     for (int i=0;i<ss;++i){
805       char ch=s[i];
806       if (!blank){
807 	res += ch;
808 	if (ch=='\n'){
809 	  ns=0;
810 	  blank=true;
811 	}
812 	continue;
813       }
814       if (ch=='\n'){
815 	ns=0;
816 	continue;
817       }
818       if (ch!=' '){
819 	blank=false;
820 	res += string(ns,' ')+ch;
821 	ns=0;
822 	continue;
823       }
824       ++ns;
825     }
826     return res;
827   }
828 
829   static string printasbloc(const gen & feuille,const char * sommetstr,GIAC_CONTEXT);
printasprogram(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)830   static string printasprogram(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
831     if ( (feuille.type!=_VECT) || (feuille._VECTptr->size()!=3) )
832       return string(sommetstr)+('('+feuille.print(contextptr)+')');
833     string res;
834     bool python=python_compat(contextptr) && !debug_ptr(contextptr)->debug_mode;
835     if (python){
836       int & ind=debug_ptr(contextptr)->indent_spaces;
837       vecteur v =*feuille._VECTptr;
838       if (v[2].type==_VECT && v[2].subtype==_PRG__VECT)
839 	v[2]=symb_bloc(v[2]);
840       if (!v[2].is_symb_of_sommet(at_bloc) && !v[2].is_symb_of_sommet(at_local)){
841 	res=string(ind,' ')+"lambda ";
842 	if (v[0].type==_VECT && v[0].subtype==_SEQ__VECT && v[0]._VECTptr->size()==1)
843 	  res += v[0]._VECTptr->front().print(contextptr);
844 	else
845 	  res += v[0].print(contextptr);
846 	res +=':';
847 	if (v[2].is_symb_of_sommet(at_return))
848 	  res += v[2]._SYMBptr->feuille.print(contextptr);
849 	else
850 	  res += v[2].print(contextptr);
851 	return res;
852       }
853       res = string(ind,' ')+"def "+lastprog_name(contextptr)+"(";
854       if (v[0].type==_VECT && v[0].subtype==_SEQ__VECT && v[0]._VECTptr->size()==1)
855 	res += equaltosto(v[0]._VECTptr->front(),contextptr).print(contextptr);
856       else
857 	res += equaltosto(v[0],contextptr).print(contextptr);
858       res += "):\n";
859       ind += 4;
860       if (v[2].is_symb_of_sommet(at_bloc) || v[2].is_symb_of_sommet(at_local))
861 	res += v[2].print(contextptr);
862       else
863 	res += string(ind,' ')+v[2].print(contextptr)+'\n';
864       ind -= 4;
865       // remove empty lines in res
866       return remove_empty_lines(res);
867     }
868     bool calc38=abs_calc_mode(contextptr)==38;
869     if (!calc38){
870       if (xcas_mode(contextptr)==3)
871 	res="\n:lastprog";
872       else
873 	res=" "; // was res=indent(contextptr);
874     }
875     gen & feuille0=feuille._VECTptr->front();
876     if (feuille0.type==_VECT && feuille0.subtype==_SEQ__VECT && feuille0._VECTptr->size()==1)
877       res +="("+feuille0._VECTptr->front().print(contextptr)+")";
878     else
879       res +="("+feuille0.print(contextptr)+")";
880     if (xcas_mode(contextptr)==3)
881       res +="\n";
882     else
883       res += "->";
884     bool test;
885     string locals,inits;
886     gen proc_args=feuille._VECTptr->front();
887     vecteur vect,non_init_vars,initialisation_seq;
888     if ((xcas_mode(contextptr)>0 || abs_calc_mode(contextptr)==38) && (feuille._VECTptr->back().type==_SYMB) && (feuille._VECTptr->back()._SYMBptr->sommet==at_local)){
889       test=false;
890       gen tmp=feuille._VECTptr->back()._SYMBptr->feuille;
891       local_init(tmp._VECTptr->front(),non_init_vars,initialisation_seq);
892       // For Maple add proc parameters to local vars
893       if (xcas_mode(contextptr) ==1+_DECALAGE){
894 	if (proc_args.type==_VECT){
895 	  vecteur v=*proc_args._VECTptr;
896 	  non_init_vars=mergevecteur(non_init_vars,v);
897 	  iterateur it=v.begin(),itend=v.end();
898 	  for (;it!=itend;++it){
899 	    gen tmp=add_global(*it,contextptr);
900 	    initialisation_seq.push_back(symb_sto(tmp,*it));
901 	    *it=tmp;
902 	  }
903 	  proc_args=gen(v,_SEQ__VECT);
904 	}
905 	else {
906 	  non_init_vars.push_back(proc_args);
907 	  gen tmp=add_global(proc_args,contextptr);
908 	  initialisation_seq.push_back(symb_sto(tmp,proc_args));
909 	  proc_args=tmp;
910 	}
911       }
912       if (!non_init_vars.empty()){
913 	if (xcas_mode(contextptr)==3)
914 	  locals=indent(contextptr)+"Local "+printinner_VECT(non_init_vars,_SEQ__VECT,contextptr);
915 	else
916 	  locals=indent(contextptr)+(calc38?" LOCAL ":"  local ")+printinner_VECT(non_init_vars,_SEQ__VECT,contextptr)+";";
917       }
918       inits=printasinnerbloc(gen(initialisation_seq,_SEQ__VECT),contextptr);
919       if (tmp._VECTptr->back().type==_VECT)
920 	vect=*tmp._VECTptr->back()._VECTptr;
921       else
922 	vect=makevecteur(tmp._VECTptr->back());
923     }
924     else {
925       test=(feuille._VECTptr->back().type!=_VECT ||feuille._VECTptr->back().subtype );
926       if (!test)
927 	vect=*feuille._VECTptr->back()._VECTptr;
928     }
929     if (test){
930       gen & fb=feuille._VECTptr->back();
931       if (xcas_mode(contextptr)==3)
932 	return res+":Func "+fb.print(contextptr)+"\n:EndFunc\n";
933       if (fb.is_symb_of_sommet(at_local)){
934 	gen fb0=fb._SYMBptr->feuille[0][0];
935 	if (fb0.type==_VECT && fb0._VECTptr->empty())
936 	  return res+'{'+fb.print(contextptr)+'}';
937       }
938       return res+(fb.type==_VECT?printasbloc(fb,sommetstr,contextptr):fb.print(contextptr));
939     }
940     if (xcas_mode(contextptr)>0){
941       if (xcas_mode(contextptr)==3)
942 	res+=":Func"+locals;
943       else {
944 	res="proc("+proc_args.print(contextptr)+")"+locals;
945 	if (xcas_mode(contextptr)==2)
946 	  res +=indent(contextptr)+"begin ";
947 	if (inits.size())
948 	  res += indent(contextptr)+inits+";";
949       }
950     }
951     else {
952       if (calc38)
953 	res += "BEGIN "+locals;
954       else
955 	res += "{";
956     }
957     const_iterateur it=vect.begin(),itend=vect.end();
958     debug_ptr(contextptr)->indent_spaces +=2;
959     for (;;){
960       if (xcas_mode(contextptr)==3)
961 	res += indent(contextptr)+it->print(contextptr);
962       else
963 	res += indent(contextptr)+it->print(contextptr);
964       ++it;
965       if (it==itend){
966 	debug_ptr(contextptr)->indent_spaces -=2;
967 	if (xcas_mode(contextptr)!=3)
968 	  res += "; "+indent(contextptr);
969 	switch (xcas_mode(contextptr)){
970 	case 0:
971 	  res += calc38?"END;":"}";
972 	  break;
973 	case 1: case 1+_DECALAGE:
974 	  res+=indent(contextptr)+"end;";
975 	  break;
976 	case 2:
977 	  return res+=indent(contextptr)+"end_proc;";
978 	case 3:
979 	  return res+=indent(contextptr)+"EndFunc\n";
980 	}
981 	break;
982       }
983       else {
984 	if (xcas_mode(contextptr)!=3)
985 	  res +="; ";
986       }
987     }
988     return res;
989   }
990 
texprintasprogram(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)991   static string texprintasprogram(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
992     if (latex_format(contextptr)==1){
993       return printasprogram(feuille,sommetstr,contextptr);
994     }
995     string s("\\parbox{12cm}{\\tt ");
996     s += translate_underscore(printasprogram(feuille,sommetstr,contextptr));
997     s+=" }";
998     return s;
999   }
1000 
1001   // parser helper
symb_test_equal(const gen & a,const gen & op,const gen & b)1002   gen symb_test_equal(const gen & a,const gen & op,const gen & b){
1003     if (a.is_symb_of_sommet(at_and) && a._SYMBptr->feuille[1].is_symb_of_sommet(*op._FUNCptr)){
1004       vecteur v=*a._SYMBptr->feuille._VECTptr;
1005       v.push_back(symbolic(*op._FUNCptr,makesequence(v[1]._SYMBptr->feuille[1],b)));
1006       return symbolic(at_and,gen(v,_SEQ__VECT));
1007     }
1008     if (is_inequation(a) || a.is_symb_of_sommet(at_different) || (a.is_symb_of_sommet(at_same) && (b.type!=_INT_ || b.subtype!=_INT_BOOLEAN))){
1009       return symb_and(a,symbolic(*op._FUNCptr,gen(makevecteur(a._SYMBptr->feuille[1],b),_SEQ__VECT)));
1010     }
1011     return symbolic(*op._FUNCptr,gen(makevecteur(a,b),_SEQ__VECT));
1012   }
1013 
1014   // utility for default argument handling
default_args(gen & a,gen & b,GIAC_CONTEXT)1015   static void default_args(gen & a,gen & b,GIAC_CONTEXT){
1016 #ifndef GIAC_DEFAULT_ARGS
1017     return;
1018 #endif
1019     if (a.type==_VECT && b.type==_VECT && a._VECTptr->size()==b._VECTptr->size()){
1020       vecteur va=*a._VECTptr;
1021       vecteur vb=*b._VECTptr;
1022       for (unsigned i=0;i<a._VECTptr->size();++i)
1023 	default_args(va[i],vb[i],contextptr);
1024       a=gen(va,a.subtype);
1025       b=gen(vb,b.subtype);
1026       return;
1027     }
1028     if (a.is_symb_of_sommet(at_sto)){
1029       b=a._SYMBptr->feuille[0];
1030       a=a._SYMBptr->feuille[1];
1031       return;
1032     }
1033     if (a.is_symb_of_sommet(at_equal)){
1034       b=a._SYMBptr->feuille[1];
1035       a=a._SYMBptr->feuille[0];
1036       return;
1037     }
1038     b=string2gen(gettext("Unitialized parameter ")+a.print(contextptr),false);
1039     b.subtype=-1;
1040   }
1041 
replace_keywords(const gen & a,const gen & b,gen & newa,gen & newb,GIAC_CONTEXT)1042   static void replace_keywords(const gen & a,const gen & b,gen & newa,gen & newb,GIAC_CONTEXT){
1043     // Check that variables in a are really variables, otherwise print
1044     // the var and make new variables
1045     vecteur newv(gen2vecteur(a));
1046     if (newv.size()==2 && newv.front().type==_VECT && newv.back().type==_VECT){
1047       gen tmpa,tmpb;
1048       replace_keywords(*newv.front()._VECTptr,b,tmpa,tmpb,contextptr);
1049       replace_keywords(*newv.back()._VECTptr,tmpb,newa,newb,contextptr);
1050       newa=gen(makevecteur(tmpa,newa),a.subtype);
1051       return;
1052     }
1053     vecteur v1,v2;
1054     iterateur it=newv.begin(),itend=newv.end();
1055     for (;it!=itend;++it){
1056       if (it->is_symb_of_sommet(at_sto) || it->is_symb_of_sommet(at_check_type) || it->is_symb_of_sommet(at_equal)) // FIXME check 1st arg too
1057 	continue;
1058       if (it->is_symb_of_sommet(at_of)){
1059 	*logptr(contextptr) << gettext("Invalid argument name ") << *it << gettext(". You should use ") << it->_SYMBptr->feuille._VECTptr->front() << gettext(" instead, even if the argument should be of type function") << '\n';
1060 	*it=it->_SYMBptr->feuille._VECTptr->front();
1061       }
1062       if (it->is_symb_of_sommet(at_deuxpoints)){
1063 	gen theid=it->_SYMBptr->feuille[0];
1064 	gen egal=0;
1065 	if (theid.is_symb_of_sommet(at_sto)){
1066 	  egal=theid._SYMBptr->feuille[0];
1067 	  theid=theid._SYMBptr->feuille[1];
1068 	}
1069 	if (theid.is_symb_of_sommet(at_equal)){
1070 	  egal=theid._SYMBptr->feuille[1];
1071 	  theid=theid._SYMBptr->feuille[0];
1072 	}
1073 	gen thetype=it->_SYMBptr->feuille[1],newid=*it;
1074 	if (thetype.type==_INT_ && thetype.subtype==_INT_TYPE){
1075 	  v1.push_back(theid);
1076 	  // add =
1077 	  if (thetype.val==_ZINT){
1078 	    newid=*it=gen(identificateur(theid.print(contextptr)+"_i"));
1079 	    if (egal!=0)
1080 	      *it=symb_equal(*it,egal);
1081 	  }
1082 	  if (thetype.val==_DOUBLE_ || thetype.val==_REAL){
1083 	    newid=*it=gen(identificateur(theid.print(contextptr)+"_d"));
1084 	    if (egal!=0)
1085 	      *it=symb_equal(*it,egal);
1086 	  }
1087 	  if (thetype.val==_CPLX){
1088 	    newid=*it=gen(identificateur(theid.print(contextptr)+"_c"));
1089 	    if (egal!=0)
1090 	      *it=symb_equal(*it,egal);
1091 	  }
1092 	  if (thetype.val==_FRAC){
1093 	    newid=*it=gen(identificateur(theid.print(contextptr)+"_f"));
1094 	    if (egal!=0)
1095 	      *it=symb_equal(*it,egal);
1096 	  }
1097 	  v2.push_back(newid);
1098 	  continue;
1099 	}
1100 	if (thetype==at_real || thetype==at_float){
1101 	  v1.push_back(theid);
1102 	  *it=gen(identificateur(theid.print(contextptr)+"_d"));
1103 	  if (egal!=0)
1104 	    *it=symb_equal(*it,egal);
1105 	  v2.push_back(*it);
1106 	  continue;
1107 	}
1108 	if (thetype==at_complex){
1109 	  v1.push_back(theid);
1110 	  *it=gen(identificateur(theid.print(contextptr)+"_c"));
1111 	  if (egal!=0)
1112 	    *it=symb_equal(*it,egal);
1113 	  v2.push_back(*it);
1114 	  continue;
1115 	}
1116 	if (thetype==at_vector){
1117 	  v1.push_back(theid);
1118 	  newid=*it=gen(identificateur(theid.print(contextptr)+"_v"));
1119 	  if (egal!=0)
1120 	    *it=symb_equal(*it,egal);
1121 	  v2.push_back(newid);
1122 	  continue;
1123 	}
1124 	if (thetype==at_string){
1125 	  v1.push_back(theid);
1126 	  newid=*it=gen(identificateur(theid.print(contextptr)+"_s"));
1127 	  if (egal!=0)
1128 	    *it=symb_equal(*it,egal);
1129 	  v2.push_back(newid);
1130 	  continue;
1131 	}
1132 	if (thetype==at_integrate || thetype==at_int){ // int==integrate
1133 	  v1.push_back(theid);
1134 	  newid=*it=gen(identificateur(theid.print(contextptr)+"_i"));
1135 	  if (egal!=0)
1136 	    *it=symb_equal(*it,egal);
1137 	  v2.push_back(newid);
1138 	  continue;
1139 	}
1140       }
1141       if (it->type!=_IDNT && it->type!=_CPLX){
1142 	v1.push_back(*it);
1143 	string s=gen2string(*it);
1144 	int ss=int(s.size());
1145 	if (ss==1)
1146 	  s += "___";
1147 	if (ss>2 && s[0]=='\'' && s[ss-1]=='\'')
1148 	  s=s.substr(1,ss-2);
1149 	for (unsigned i=0;i<s.size();++i){
1150 	  if (!isalpha(s[i]))
1151 	    s[i]='_';
1152 	}
1153 	lock_syms_mutex();
1154 	sym_string_tab::const_iterator i = syms().find(s);
1155 	if (i == syms().end()) {
1156 	  *it = *(new identificateur(s));
1157 	  syms()[s] = *it;
1158 	} else {
1159 	  // std::cerr << "lexer" << s << '\n';
1160 	  *it = i->second;
1161 	}
1162 	unlock_syms_mutex();
1163 	v2.push_back(*it);
1164       }
1165     }
1166     newa=gen(newv,_SEQ__VECT);
1167     if (v1.empty())
1168       newb=b;
1169     else {
1170       *logptr(contextptr) << gettext("Invalid or typed variable(s) name(s) were replaced by creating special identifiers, check ") << v1 << '\n';
1171       newb=quotesubst(b,v1,v2,contextptr);
1172     }
1173   }
1174 
mkvalid(const string & s)1175   string mkvalid(const string & s){
1176     string res;
1177     for (size_t i=0;i<s.size();++i){
1178       char ch=s[i];
1179       if (ch!='.' && isalphan(ch)){
1180 	res += ch;
1181 	continue;
1182       }
1183       res += "char";
1184       res += char('0'+(ch/100));
1185       res += char('0'+((ch%100)/10));
1186       res += char('0'+(ch%10));
1187     }
1188     return res;
1189   }
1190 
1191   // a=arguments, b=values, c=program bloc, d=program name
symb_program_sto(const gen & a_,const gen & b_,const gen & c_,const gen & d,bool embedd,GIAC_CONTEXT)1192   symbolic symb_program_sto(const gen & a_,const gen & b_,const gen & c_,const gen & d,bool embedd,GIAC_CONTEXT){
1193     gen a(a_),b(b_),c(c_);
1194     default_args(a,b,contextptr);
1195     bool warn=false;
1196 #ifndef GIAC_HAS_STO_38
1197     if (logptr(contextptr) && calc_mode(contextptr)!=1)
1198       warn=warn_symb_program_sto; // true;
1199 #endif
1200     if (warn){
1201       *logptr(contextptr) << gettext("// Parsing ") << d << '\n';
1202       lastprog_name(d.print(contextptr),contextptr);
1203       if (c.is_symb_of_sommet(at_derive))
1204 	*logptr(contextptr) << gettext("Warning, defining a derivative function should be done with function_diff or unapply: ") << c << '\n';
1205        if (c.type==_SYMB && c._SYMBptr->sommet!=at_local && c._SYMBptr->sommet!=at_bloc && c._SYMBptr->sommet!=at_when && c._SYMBptr->sommet!=at_for && c._SYMBptr->sommet!=at_ifte){
1206 	 vecteur lofc=lop(c,at_of);
1207 	 vecteur lofc_no_d;
1208 	 vecteur av=gen2vecteur(a);
1209 	 for (unsigned i=0;i<lofc.size();++i){
1210 	   if (lofc[i][1]!=d && !equalposcomp(av,lofc[i][1]) )
1211 	     lofc_no_d.push_back(lofc[i]);
1212 	 }
1213 	 if (!lofc_no_d.empty()){
1214 	   *logptr(contextptr) << gettext("Warning: algebraic function defined in term of others functions may lead to evaluation errors") << '\n';
1215 	   CERR << c.print(contextptr) << '\n';
1216 	   *logptr(contextptr) << gettext("Perhaps you meant ") << d.print(contextptr) << ":=unapply(" << c.print(contextptr) << ",";
1217 	   if (a.type==_VECT && a.subtype==_SEQ__VECT && a._VECTptr->size()==1)
1218 	     *logptr(contextptr) << a._VECTptr->front().print(contextptr) << ")" << '\n';
1219 	   else
1220 	     *logptr(contextptr) << a.print(contextptr) << ")" << '\n';
1221 	 }
1222        }
1223     }
1224     vecteur newcsto(lop(c,at_sto)),newc1,newc2;
1225     for (size_t i=0;i<newcsto.size();++i){
1226       gen & val=newcsto[i]._SYMBptr->feuille._VECTptr->front();
1227       if (val.type==_VECT && (is_numericv(*val._VECTptr) || is_integer_vecteur(*val._VECTptr))) // in-place modification
1228 	val=symbolic(at_copy,val);
1229       gen var=newcsto[i]._SYMBptr->feuille._VECTptr->back();
1230       if (var.type==_FUNC && (python_compat(contextptr) || !archive_function_index(*var._FUNCptr))){
1231 	newc1.push_back(var);
1232 	newc2.push_back(identificateur(mkvalid(var._FUNCptr->ptr()->print(contextptr))+"_rep"));
1233       }
1234     }
1235     newcsto=mergevecteur(lop(c,at_struct_dot),lop(c,at_for));
1236     for (size_t i=0;i<newcsto.size();++i){
1237       gen var=newcsto[i]._SYMBptr->feuille[0];
1238       if (var.type==_FUNC && var!=at_random && (python_compat(contextptr) || !archive_function_index(*var._FUNCptr))){
1239 	newc1.push_back(var);
1240 	newc2.push_back(identificateur(mkvalid(var._FUNCptr->ptr()->print(contextptr))+"_rep"));
1241       }
1242     }
1243     newcsto=gen2vecteur(a);
1244     for (size_t i=0;i<newcsto.size();++i){
1245       gen var=newcsto[i];
1246       if (var.type==_FUNC){
1247 	newc1.push_back(var);
1248 	newc2.push_back(identificateur(mkvalid(var._FUNCptr->ptr()->print(contextptr))+"_rep"));
1249       }
1250     }
1251     if (!newc1.empty()){
1252       c=subst(c,newc1,newc2,true,contextptr);
1253       a=subst(a,newc1,newc2,true,contextptr);
1254     }
1255     gen newa,newc;
1256     replace_keywords(a,((embedd&&c.type==_VECT)?makevecteur(c):c),newa,newc,contextptr);
1257     //cout << c._SYMBptr->sommet << '\n';
1258     bool cloc=newc.is_symb_of_sommet(at_local),glob=false;
1259     gen clocg;
1260     if (cloc){
1261       clocg=newc._SYMBptr->feuille;
1262       if (clocg.type==_VECT && !clocg._VECTptr->empty()){
1263 	clocg=clocg._VECTptr->front();
1264 	glob=clocg.type==_VECT && clocg._VECTptr->size()==2 && clocg._VECTptr->front().type==_VECT && clocg._VECTptr->front()._VECTptr->empty();
1265       }
1266     }
1267     if (python_compat(contextptr) && (!cloc || glob) ){
1268       vecteur res1,non_decl,res3,res4,Newa=gen2vecteur(newa);
1269       for (int i=0;i<int(Newa.size());++i){
1270 	if (Newa[i].is_symb_of_sommet(at_equal))
1271 	  Newa[i]=Newa[i]._SYMBptr->feuille[0];
1272       }
1273       check_local_assign(newc,Newa,res1,non_decl,res3,res4,false,contextptr);
1274       vecteur stov(lop(newc,at_sto));
1275       for (size_t i=0;i<stov.size();++i){
1276 	stov[i]=stov[i]._SYMBptr->feuille[1];
1277       }
1278       vecteur stoprog(lop(newc,at_program));
1279       for (size_t i=0;i<stoprog.size();++i){
1280 	stoprog[i]=stoprog[i]._SYMBptr->feuille[0];
1281       }
1282       vecteur stofor(lop(newc,at_for));
1283       for (size_t i=0;i<stofor.size();++i){
1284 	stofor[i]=stofor[i]._SYMBptr->feuille[0];
1285       }
1286       stov=lidnt(mergevecteur(mergevecteur(stov,stoprog),stofor));
1287       int rs=int(non_decl.size());
1288       for (int i=0;i<rs;i++){
1289 	// remove var that are not assigned (assumed global), constant idnt and recursive def
1290 	gen noni=non_decl[i];
1291 	if (noni.type!=_IDNT){
1292 	  non_decl.erase(non_decl.begin()+i);
1293 	  --i; --rs;
1294 	  continue;
1295 	}
1296 	bool b=equalposcomp(stov,noni);
1297 	if (strcmp(noni._IDNTptr->id_name,"i")==0){
1298 	  if (!b){
1299 	    non_decl.erase(non_decl.begin()+i);
1300 	    --i; --rs;
1301 	  }
1302 	}
1303 	else {
1304 	  if (!b || is_constant_idnt(noni) || noni==d){
1305 	    non_decl.erase(non_decl.begin()+i);
1306 	    --i; --rs;
1307 	  }
1308 	}
1309       }
1310       if (!non_decl.empty()){
1311 	*logptr(contextptr) << gettext("Auto-declared local variables : ") << gen(non_decl,_SEQ__VECT) << '\n';
1312 	if (glob)
1313 	  newc=symb_local(makesequence(non_decl,clocg._VECTptr->back()),newc._SYMBptr->feuille._VECTptr->back(),contextptr);
1314 	else
1315 	  newc=symb_local(non_decl,newc,contextptr);
1316       }
1317     }
1318     symbolic g=symbolic(at_program,gen(makevecteur(newa,b,newc),_SEQ__VECT));
1319     g=symbolic(at_sto,gen(makevecteur(g,d),_SEQ__VECT));
1320     if (warn)
1321       *logptr(contextptr) << check_local_assign(g,contextptr) ;
1322     if (warn && newc.is_symb_of_sommet(at_local)){
1323       // check that a local variable name does not shadow a parameter name
1324       gen & newcf=newc._SYMBptr->feuille;
1325       if (newcf.type==_VECT && newcf._VECTptr->size()==2){
1326 	gen & vars = newcf._VECTptr->front(); // local vars, back is global vars
1327 	gen inters=_intersect(gen(makevecteur(vars,newa),_SEQ__VECT),contextptr);
1328 	if (inters.type==_VECT && !inters._VECTptr->empty()){
1329 	  inters.subtype=_SEQ__VECT;
1330 	  *logptr(contextptr) << gettext("Warning: Local variables shadow function arguments ") << inters << '\n';
1331 	}
1332       }
1333     }
1334     if (printprog){
1335       int p=python_compat(contextptr);
1336       python_compat(printprog/256,contextptr);
1337       if (g.sommet==at_sto){
1338 	lastprog_name(g.feuille[1].print(contextptr),contextptr);
1339 	COUT << g.feuille[0].print(contextptr) <<'\n';
1340       }
1341       else
1342 	COUT << g <<'\n';
1343       python_compat(p,contextptr);
1344     }
1345     return g;
1346   }
symb_program(const gen & a_,const gen & b_,const gen & c,GIAC_CONTEXT)1347   symbolic symb_program(const gen & a_,const gen & b_,const gen & c,GIAC_CONTEXT){
1348     gen a(a_),b(b_);
1349     default_args(a,b,contextptr);
1350     gen newa,newc;
1351     replace_keywords(a,c,newa,newc,contextptr);
1352     symbolic g=symbolic(at_program,gen(makevecteur(newa,b,newc),_SEQ__VECT));
1353 #ifndef GIAC_HAS_STO_38
1354     if (logptr(contextptr))
1355       *logptr(contextptr) << check_local_assign(g,contextptr) ;
1356 #endif
1357     return g;
1358   }
symb_program(const gen & args)1359   symbolic symb_program(const gen & args){
1360     return symbolic(at_program,args);
1361   }
1362   static void lidnt_prog(const gen & g,vecteur & res);
lidnt_prog(const vecteur & v,vecteur & res)1363   static void lidnt_prog(const vecteur & v,vecteur & res){
1364     const_iterateur it=v.begin(),itend=v.end();
1365     for (;it!=itend;++it)
1366       lidnt_prog(*it,res);
1367   }
lidnt_prog(const gen & g,vecteur & res)1368   static void lidnt_prog(const gen & g,vecteur & res){
1369     switch (g.type){
1370     case _VECT:
1371       lidnt_prog(*g._VECTptr,res);
1372       break;
1373     case _IDNT:
1374       if (!equalposcomp(res,g))
1375 	res.push_back(g);
1376       break;
1377     case _SYMB:
1378       /* if (g._SYMBptr->sommet==at_at || g._SYMBptr->sommet==at_of )
1379 	lidnt_prog(g._SYMBptr->feuille._VECTptr->back(),res);
1380 	else */
1381 	lidnt_prog(g._SYMBptr->feuille,res);
1382       break;
1383     }
1384   }
1385 
local_vars(const gen & g,vecteur & v,GIAC_CONTEXT)1386   static void local_vars(const gen & g,vecteur & v,GIAC_CONTEXT){
1387     if (g.type==_VECT){
1388       const_iterateur it=g._VECTptr->begin(),itend=g._VECTptr->end();
1389       for (;it!=itend;++it){
1390 	local_vars(*it,v,contextptr);
1391       }
1392       return ;
1393     }
1394     if (g.type!=_SYMB)
1395       return;
1396     if (g._SYMBptr->sommet==at_local && g._SYMBptr->feuille.type==_VECT){
1397       vecteur & w = *g._SYMBptr->feuille._VECTptr;
1398       if (w[0].type==_VECT && w[0]._VECTptr->size()==2 && w[0]._VECTptr->front().type==_VECT)
1399 	v=mergevecteur(v,*w[0]._VECTptr->front()._VECTptr);
1400       else
1401 	v=mergevecteur(v,gen2vecteur(w[0]));
1402       local_vars(w[1],v,contextptr);
1403       return;
1404     }
1405     if (g._SYMBptr->sommet==at_program && g._SYMBptr->feuille.type==_VECT){
1406       vecteur & w = *g._SYMBptr->feuille._VECTptr;
1407       if (w[0].type==_VECT )
1408 	v=mergevecteur(v,*w[0]._VECTptr);
1409     }
1410     local_vars(g._SYMBptr->feuille,v,contextptr);
1411   }
1412 
quote_program(const gen & args,GIAC_CONTEXT)1413   gen quote_program(const gen & args,GIAC_CONTEXT){
1414     // return symb_program(args);
1415     // g:=unapply(p ->translation(w,p),w);g(1)
1416     // Necessite d'evaluer les arguments des programmes a l'interieur d'un programme.
1417     // Mais il ne faut pas evaluer les variables declarees comme locales!!
1418     bool in_prog=debug_ptr(contextptr)->sst_at_stack.size()!=0;
1419     // ?? Subst all variables except arguments
1420     if (!in_prog || args.type!=_VECT || args._VECTptr->size()!=3)
1421       return symb_program(args);
1422     vecteur & v = *args._VECTptr;
1423     vecteur vars(gen2vecteur(v[0]));
1424     int s=int(vars.size()); // s vars not subst-ed
1425     lidnt_prog(v[2],vars);
1426     vars=vecteur(vars.begin()+s,vars.end());
1427     // Remove local variables from the list
1428     vecteur tmpvar,resvar;
1429     local_vars(v[2],tmpvar,contextptr);
1430     const_iterateur it=vars.begin(),itend=vars.end();
1431     for (;it!=itend;++it){
1432       if (!equalposcomp(tmpvar,*it))
1433 	resvar.push_back(*it);
1434     }
1435     gen tmp=gen(resvar).eval(1,contextptr);
1436     vecteur varsub(*tmp._VECTptr);
1437     return symbolic(at_program,quotesubst(args,resvar,varsub,contextptr));
1438   }
is_return(const gen & g,gen & newres)1439   static bool is_return(const gen & g,gen & newres){
1440     if (g.type==_SYMB && g._SYMBptr->sommet==at_return){
1441       // gen tmp = g._SYMBptr->feuille; is_return(tmp,newres);
1442       is_return(g._SYMBptr->feuille,newres);
1443       return true;
1444     }
1445     if (g.type==_STRNG && g.subtype==-1){
1446       newres=g;
1447       return true;
1448     }
1449     if ( (g.type==_VECT && (g.subtype ==_SEQ__VECT || g.subtype==_PRG__VECT) && g._VECTptr->size()==1) )
1450       return is_return(g._VECTptr->front(),newres);
1451     newres=g;
1452     return false;
1453   }
adjust_sst_at(const gen & name,GIAC_CONTEXT)1454   void adjust_sst_at(const gen & name,GIAC_CONTEXT){
1455     debug_ptr(contextptr)->sst_at.clear();
1456     const_iterateur it=debug_ptr(contextptr)->debug_breakpoint.begin(),itend=debug_ptr(contextptr)->debug_breakpoint.end();
1457     for (;it!=itend;++it){
1458       if (it->_VECTptr->front()==name)
1459 	debug_ptr(contextptr)->sst_at.push_back(it->_VECTptr->back().val);
1460     }
1461   }
1462 
program_leave(const gen & save_debug_info,bool save_sst_mode,debug_struct * dbgptr)1463   void program_leave(const gen & save_debug_info,bool save_sst_mode,debug_struct * dbgptr){
1464     dbgptr->args_stack.pop_back();
1465     // *logptr(contextptr) << "Leaving " << args << '\n';
1466     if (!dbgptr->sst_at_stack.empty()){
1467       dbgptr->sst_at=dbgptr->sst_at_stack.back();
1468       dbgptr->sst_at_stack.pop_back();
1469     }
1470     if (!dbgptr->current_instruction_stack.empty()){
1471       dbgptr->current_instruction=dbgptr->current_instruction_stack.back();
1472       dbgptr->current_instruction_stack.pop_back();
1473     }
1474     dbgptr->sst_mode=save_sst_mode;
1475     if (dbgptr->current_instruction_stack.empty())
1476       dbgptr->debug_mode=false;
1477     (*dbgptr->debug_info_ptr)=save_debug_info;
1478     (*dbgptr->fast_debug_info_ptr)=save_debug_info;
1479   }
1480 
_program(const gen & args,const gen & name,const context * contextptr)1481   gen _program(const gen & args,const gen & name,const context * contextptr){
1482     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
1483     if (args.type!=_VECT)
1484       return args.eval(prog_eval_level(contextptr),contextptr);
1485     // set breakpoints
1486     debug_struct * dbgptr=debug_ptr(contextptr);
1487     context * newcontextptr=(context *)contextptr;
1488     const_iterateur it,itend;
1489     gen res,newres,label,vars,values,prog,save_debug_info;
1490     // *logptr(contextptr) << & res << '\n';
1491 #ifdef RTOS_THREADX
1492     if ((void *)&res<= (void *)&mainThreadStack[1024]) {
1493       gensizeerr(gettext("Too many recursions"),res);
1494       return res;
1495     }
1496 #else
1497 #if !defined(WIN32) && defined HAVE_PTHREAD_H
1498     if (contextptr){
1499       // CERR << &slevel << " " << thread_param_ptr(contextptr)->stackaddr << '\n';
1500       if ( ((size_t) &res) < ((size_t) thread_param_ptr(contextptr)->stackaddr)+8192){
1501 	gensizeerr(gettext("Too many recursion levels"),res);
1502 	return res;
1503       }
1504     }
1505     else {
1506       if ( int(dbgptr->sst_at_stack.size()) >= MAX_RECURSION_LEVEL+1){
1507 	gensizeerr(gettext("Too many recursions"),res);
1508 	return res;
1509       }
1510     }
1511 #else
1512     if ( int(dbgptr->sst_at_stack.size()) >= MAX_RECURSION_LEVEL+1){
1513       gensizeerr(gettext("Too many recursions"),res);
1514       return res;
1515     }
1516 #endif
1517 #endif
1518     dbgptr->sst_at_stack.push_back(dbgptr->sst_at);
1519     dbgptr->sst_at.clear();
1520     if (name.type==_IDNT)
1521       adjust_sst_at(name,contextptr);
1522     dbgptr->current_instruction_stack.push_back(dbgptr->current_instruction);
1523     dbgptr->current_instruction=0;
1524     bool save_sst_mode = dbgptr->sst_mode,findlabel,calc_save ;
1525     int protect=0;
1526     // *logptr(contextptr) << "Entering prog " << args << " " << dbgptr->sst_in_mode << '\n';
1527     if (dbgptr->sst_in_mode){
1528       dbgptr->sst_in_mode=false;
1529       dbgptr->sst_mode=true;
1530     }
1531     else
1532       dbgptr->sst_mode=false;
1533     // Bind local var
1534 #ifdef TIMEOUT
1535     control_c();
1536 #endif
1537     if (ctrl_c || interrupted || args._VECTptr->size()!=3){
1538       gensizeerr(res,contextptr);
1539       return res;
1540     }
1541     calc_save=calc_mode(contextptr)==38;
1542     if (calc_save)
1543       calc_mode(-38,contextptr);
1544     vars=args._VECTptr->front();
1545     values=(*(args._VECTptr))[1];
1546     prog=args._VECTptr->back();
1547     save_debug_info=(*dbgptr->debug_info_ptr);
1548     if (vars.type!=_VECT)
1549       vars=gen(makevecteur(vars));
1550     if (values.type!=_VECT || values.subtype!=_SEQ__VECT || (vars._VECTptr->size()==1 && values._VECTptr->size()>1))
1551       values=gen(makevecteur(values));
1552     // *logptr(contextptr) << vars << " " << values << '\n';
1553     dbgptr->args_stack.push_back(gen(mergevecteur(vecteur(1,name),*values._VECTptr)));
1554     // removed sst test so that when a breakpoint is evaled
1555     // the correct info is displayed
1556     (*dbgptr->debug_info_ptr)=prog;
1557     (*dbgptr->fast_debug_info_ptr)=prog;
1558     if (!vars._VECTptr->empty())
1559       protect=giac_bind(*values._VECTptr,*vars._VECTptr,newcontextptr);
1560     if (protect==-RAND_MAX){
1561       program_leave(save_debug_info,save_sst_mode,dbgptr);
1562       if (calc_save)
1563 	calc_mode(38,contextptr);
1564       gensizeerr(res,contextptr);
1565       return res;
1566     }
1567 #ifndef NO_STDEXCEPT
1568     try {
1569 #endif
1570       if (prog.type!=_VECT || (prog.subtype && prog.subtype!=_PRG__VECT)){
1571 	++debug_ptr(newcontextptr)->current_instruction;
1572 	prog=equaltosto(prog,contextptr);
1573 	if (debug_ptr(newcontextptr)->debug_mode){
1574 	  debug_loop(res,newcontextptr);
1575 	  if (!is_undef(res)){
1576 	    if (!prog.in_eval(prog_eval_level(newcontextptr),res,newcontextptr))
1577 	      res=prog;
1578 	  }
1579 	}
1580 	else {
1581 	  if (!prog.in_eval(prog_eval_level(newcontextptr),res,newcontextptr))
1582 	    res=prog;
1583 	}
1584 	if (is_return(res,newres))
1585 	  res=newres;
1586       }
1587       else {
1588 	it=prog._VECTptr->begin();
1589 	itend=prog._VECTptr->end();
1590 	findlabel=false;
1591 	for (;!ctrl_c && !interrupted && it!=itend;++it){
1592 #ifdef TIMEOUT
1593 	  control_c();
1594 #endif
1595 	  ++debug_ptr(newcontextptr)->current_instruction;
1596 	  if (debug_ptr(newcontextptr)->debug_mode){
1597 	    debug_loop(res,newcontextptr);
1598 	    if (is_undef(res)) break;
1599 	  }
1600 	  if (!findlabel){
1601 	    if (it->is_symb_of_sommet(at_return)){
1602 	      if (!equaltosto(it->_SYMBptr->feuille,contextptr).in_eval(prog_eval_level(newcontextptr),newres,newcontextptr))
1603 		newres=it->_SYMBptr->feuille;
1604 	      is_return(newres,res);
1605 	      break;
1606 	    }
1607 	    if (!equaltosto(*it,contextptr).in_eval(prog_eval_level(newcontextptr),res,newcontextptr))
1608 	      res=*it;
1609 	  }
1610 	  else
1611 	    res=*it;
1612 	  if (res.type==_STRNG && res.subtype==-1)
1613 	    break;
1614 	  if (res.type==_SYMB){
1615 	    if (findlabel && res.is_symb_of_sommet(at_label) && label==res._SYMBptr->feuille)
1616 	      findlabel=false;
1617 	    if (!findlabel && res.is_symb_of_sommet(at_goto)){
1618 	      findlabel=true;
1619 	      label=res._SYMBptr->feuille;
1620 	    }
1621 	  }
1622 	  if (findlabel && it+1==itend)
1623 	    it=prog._VECTptr->begin()-1;
1624 	  if (!findlabel && is_return(res,newres)){
1625 	    res=newres;
1626 	    break;
1627 	  }
1628 	}
1629       }
1630 #ifndef NO_STDEXCEPT
1631     } // end try
1632     catch (std::runtime_error & e){
1633       last_evaled_argptr(contextptr)=NULL;
1634       if (!vars._VECTptr->empty())
1635 	leave(protect,*vars._VECTptr,newcontextptr);
1636       if (calc_save)
1637 	calc_mode(38,contextptr);
1638       throw(std::runtime_error(e.what()));
1639     }
1640 #endif
1641     if (!vars._VECTptr->empty())
1642       leave(protect,*vars._VECTptr,newcontextptr);
1643     program_leave(save_debug_info,save_sst_mode,dbgptr);
1644     if (calc_save)
1645       calc_mode(38,contextptr);
1646     return res;
1647   }
1648   static const char _program_s []="program";
1649   static define_unary_function_eval4_index (147,__program,&quote_program,_program_s,&printasprogram,&texprintasprogram);
1650   define_unary_function_ptr5( at_program ,alias_at_program,&__program,_QUOTE_ARGUMENTS,0);
1651 
printasbloc(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)1652   static string printasbloc(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
1653     if ( feuille.type!=_VECT || feuille._VECTptr->empty() )
1654       return "{"+feuille.print(contextptr)+";}";
1655     const_iterateur it=feuille._VECTptr->begin(),itend=feuille._VECTptr->end();
1656     string res("{");
1657     bool python=python_compat(contextptr) && !debug_ptr(contextptr)->debug_mode;
1658     if (python){
1659       int & ind=debug_ptr(contextptr)->indent_spaces;
1660       res="\n";
1661       for (;it!=itend;++it){
1662 	string add=it->print(contextptr);
1663 	if (add.size() && add[0]=='\n' && res.size() && res[res.size()-1]=='\n')
1664 	  res += add.substr(1,add.size()-1)+'\n';
1665 	else
1666 	  res += string(ind,' ')+add+'\n';
1667       }
1668       return res;
1669     }
1670     if (xcas_mode(contextptr)>0){
1671       if (xcas_mode(contextptr)==3)
1672 	res="";
1673       else
1674 	res=indent(contextptr)+"begin";
1675     }
1676     debug_ptr(contextptr)->indent_spaces +=2;
1677     for (;;){
1678       if (xcas_mode(contextptr)==3)
1679 	res += indent(contextptr)+it->print(contextptr);
1680       else
1681 	res += indent(contextptr)+it->print(contextptr);
1682       ++it;
1683       if (it==itend){
1684 	debug_ptr(contextptr)->indent_spaces -=2;
1685 	if (xcas_mode(contextptr)==3)
1686 	  break;
1687 	res += "; "+indent(contextptr);
1688 	if (xcas_mode(contextptr)>0)
1689 	  res += indent(contextptr)+"end";
1690 	else
1691 	  res += "}";
1692 	break;
1693       }
1694       else {
1695 	if (xcas_mode(contextptr)!=3)
1696 	  res +="; ";
1697       }
1698     }
1699     return res;
1700   }
symb_bloc(const gen & args)1701   gen symb_bloc(const gen & args){
1702     if (args.type!=_VECT)
1703       return args;
1704     if (args.type==_VECT && args._VECTptr->size()==1)
1705       return args._VECTptr->front();
1706     gen a=args; a.subtype=_SEQ__VECT;
1707     return symbolic(at_bloc,a);
1708   }
_bloc(const gen & prog,GIAC_CONTEXT)1709   gen _bloc(const gen & prog,GIAC_CONTEXT){
1710     if ( prog.type==_STRNG &&  prog.subtype==-1) return  prog;
1711     gen res,label;
1712     bool findlabel=false;
1713     debug_struct * dbgptr=debug_ptr(contextptr);
1714     if (prog.type!=_VECT){
1715       ++dbgptr->current_instruction;
1716       if (dbgptr->debug_mode){
1717 	debug_loop(res,contextptr);
1718 	if (is_undef(res)) return res;
1719       }
1720       return prog.eval(eval_level(contextptr),contextptr);
1721     }
1722     else {
1723       const_iterateur it=prog._VECTptr->begin(),itend=prog._VECTptr->end();
1724       for (;!ctrl_c && !interrupted && it!=itend;++it){
1725 #ifdef TIMEOUT
1726 	control_c();
1727 #endif
1728 	++dbgptr->current_instruction;
1729 	if (dbgptr->debug_mode){
1730 	  debug_loop(res,contextptr);
1731 	  if (is_undef(res)) return res;
1732 	}
1733 	if (!findlabel){
1734 	  if (it->type==_SYMB && it->_SYMBptr->sommet==at_return){
1735 	    // res=it->_SYMBptr->feuille.eval(prog_eval_level(contextptr),contextptr);
1736 	    if (!it->_SYMBptr->feuille.in_eval(prog_eval_level(contextptr),res,contextptr))
1737 	      res=it->_SYMBptr->feuille;
1738 	    increment_instruction(it+1,itend,dbgptr);
1739 	    return symbolic(at_return,res);
1740 	  }
1741 	  else {
1742 	    // res=it->eval(eval_level(contextptr),contextptr);
1743 	    if (!equaltosto(*it,contextptr).in_eval(eval_level(contextptr),res,contextptr))
1744 	      res=*it;
1745 	  }
1746 	}
1747 	else
1748 	  res=*it;
1749 	if (res.type==_STRNG && res.subtype==-1)
1750 	  return res;
1751 	if (res.type==_SYMB){
1752 	  unary_function_ptr & u=res._SYMBptr->sommet;
1753 	  if (!findlabel && (u==at_return || u==at_break)) {
1754 	    increment_instruction(it+1,itend,dbgptr);
1755 	    return res; // it->eval(eval_level(contextptr),contextptr);
1756 	  }
1757 	  if (!findlabel && u==at_goto){
1758 	    findlabel=true;
1759 	    label=res._SYMBptr->feuille;
1760 	  }
1761 	  if ( u==at_label && label==res._SYMBptr->feuille )
1762 	    findlabel=false;
1763 	}
1764 	// restart the bloc if needed
1765 	if (findlabel && it+1==itend)
1766 	  it=prog._VECTptr->begin()-1;
1767       }
1768     }
1769     return res;
1770   }
1771   static const char _bloc_s []="bloc";
1772   static define_unary_function_eval2_index (145,__bloc,&_bloc,_bloc_s,&printasbloc);
1773   define_unary_function_ptr5( at_bloc ,alias_at_bloc,&__bloc,_QUOTE_ARGUMENTS,0);
1774 
1775   // test
printasifte(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)1776   string printasifte(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
1777     if ( (feuille.type!=_VECT) || (feuille._VECTptr->size()!=3) )
1778       return string(sommetstr)+('('+feuille.print(contextptr)+')');
1779     bool calc38=abs_calc_mode(contextptr)==38;
1780     const_iterateur it=feuille._VECTptr->begin();//,itend=feuille._VECTptr->end();
1781     string res(calc38?"IF ":"if ");
1782     bool python=python_compat(contextptr) && !debug_ptr(contextptr)->debug_mode;
1783     if (python){
1784       int & ind=debug_ptr(contextptr)->indent_spaces;
1785       res = '\n'+string(ind,' ')+string("if ")+it->print(contextptr)+" :\n";
1786       ind += 4;
1787       ++it;
1788       res += string(ind,' ')+it->print(contextptr);
1789       ++it;
1790       if (it->type!=_INT_)
1791 	res += '\n'+string(ind-4,' ')+string("else :\n")+string(ind,' ')+it->print(contextptr);
1792       ind -= 4;
1793       return res;
1794     }
1795     if (xcas_mode(contextptr)==3)
1796       res="If ";
1797     if (calc38 || xcas_mode(contextptr)>0)
1798       res += sametoequal(*it).print(contextptr);
1799     else
1800       res += "("+it->print(contextptr);
1801     ++it;
1802     if (calc38 || xcas_mode(contextptr)>0){
1803       if (xcas_mode(contextptr)==3){
1804 	if (is_undef(*(it+1)) && (it->type!=_SYMB || it->_SYMBptr->sommet!=at_bloc) )
1805 	  return res + indent(contextptr)+"  "+it->print(contextptr);
1806 	res += " Then "; // +indent(contextptr);
1807       }
1808       else
1809 	res += calc38?" THEN ":" then ";
1810     }
1811     else
1812       res += ") ";
1813     debug_ptr(contextptr)->indent_spaces +=2;
1814     if ((calc38 || xcas_mode(contextptr)>0) && (it->type==_SYMB) && (it->_SYMBptr->sommet==at_bloc))
1815       res += printasinnerbloc(it->_SYMBptr->feuille,contextptr);
1816     else {
1817       res += it->print(contextptr);
1818       char reslast=res[res.size()-1];
1819       if (reslast!=';' && reslast!='}')
1820 	res += ";";
1821     }
1822     debug_ptr(contextptr)->indent_spaces -=2;
1823     ++it;
1824     while ( (calc38 || xcas_mode(contextptr)>0) && (it->type==_SYMB) && (it->_SYMBptr->sommet==at_ifte) ){
1825       if (xcas_mode(contextptr)==3)
1826 	res += indent(contextptr)+"Elseif ";
1827       else
1828 	res += indent(contextptr)+ (calc38? "ELIF ":"elif ");
1829       it=it->_SYMBptr->feuille._VECTptr->begin();
1830       res += it->print(contextptr);
1831       if (xcas_mode(contextptr)==3)
1832 	res += " Then "; // +indent(contextptr);
1833       else
1834 	res += calc38? " THEN ":" then ";
1835       ++it;
1836       debug_ptr(contextptr)->indent_spaces +=2;
1837       if ((it->type==_SYMB) && (it->_SYMBptr->sommet==at_bloc))
1838 	res += printasinnerbloc(it->_SYMBptr->feuille,contextptr);
1839       else {
1840 	res += it->print(contextptr);
1841 	if (res[res.size()-1]!=';')
1842 	  res += ";";
1843       }
1844       debug_ptr(contextptr)->indent_spaces -=2;
1845       ++it;
1846     }
1847     if (!is_zero(*it)){
1848       if (!calc38 && xcas_mode(contextptr)<=0 && (res[res.size()-1]=='}'))
1849 	res += indent(contextptr)+" else ";
1850       else {
1851 	if (calc38)
1852 	  res += " ELSE ";
1853 	else {
1854 	  if (xcas_mode(contextptr)<=0 && res[res.size()-1]!=';')
1855 	    res +=";";
1856 	  if (xcas_mode(contextptr)==3)
1857 	    res += indent(contextptr)+"Else ";
1858 	  else
1859 	    res+= " else ";
1860 	}
1861       }
1862       debug_ptr(contextptr)->indent_spaces +=2;
1863       if ((calc38 || xcas_mode(contextptr)>0) && (it->type==_SYMB) && (it->_SYMBptr->sommet==at_bloc))
1864 	res += printasinnerbloc(it->_SYMBptr->feuille,contextptr);
1865       else {
1866 	res += it->print(contextptr);
1867 	if (res[res.size()-1]!=';'
1868 	    //&& !xcas_mode(contextptr)
1869 	    )
1870 	  res += ";";
1871       }
1872       debug_ptr(contextptr)->indent_spaces -=2;
1873     }
1874     // FIXME? NO ; AT END OF IF
1875     if ((xcas_mode(contextptr)<=0) && (res[res.size()-1]!='}'))
1876       res +=" ";
1877     if (calc38)
1878       res += " END ";
1879     else {
1880       if ( (xcas_mode(contextptr) ==1) || (xcas_mode(contextptr) == 1+_DECALAGE) )
1881 	res += indent(contextptr)+ "fi ";
1882       if (xcas_mode(contextptr)==2)
1883 	res += indent(contextptr)+ "end_if ";
1884       if (xcas_mode(contextptr)==3)
1885 	res += indent(contextptr)+"EndIf ";
1886     }
1887     return res;
1888   }
symb_ifte(const gen & test,const gen & oui,const gen & non)1889   symbolic symb_ifte(const gen & test,const gen & oui, const gen & non){
1890     return symbolic(at_ifte,gen(makevecteur(test,oui,non),_SEQ__VECT));
1891   }
1892 
symb_return(const gen & arg)1893   gen symb_return(const gen & arg){
1894     return gen(symbolic(at_return,arg));
1895   }
symb_when(const gen & arg)1896   gen symb_when(const gen & arg){
1897     return gen(symbolic(at_when,arg));
1898   }
1899 
ifte(const gen & args,bool isifte,const context * contextptr)1900   gen ifte(const gen & args,bool isifte,const context * contextptr){
1901     gen test,res;
1902     if (args.type!=_VECT || args._VECTptr->size()!=3){
1903       gensizeerr(gettext("Ifte must have 3 args"),res);
1904       return res;
1905     }
1906     int evallevel=eval_level(contextptr);
1907 #if 1
1908     res=args._VECTptr->front();
1909     if (!res.in_eval(evallevel,test,contextptr))
1910       test=res;
1911     if (test.type!=_INT_){
1912       test=equaltosame(test).eval(evallevel,contextptr);
1913       if (!is_integer(test)){
1914 	test=test.type==_MAP?!test._MAPptr->empty():test.evalf_double(evallevel,contextptr);
1915 	if (test.type==_VECT && python_compat(contextptr)){
1916 	  // OR test on a list
1917 	  const_iterateur it=test._VECTptr->begin(),itend=test._VECTptr->end();
1918 	  for (;it!=itend;++it){
1919 	    if (!is_zero(*it,contextptr)){
1920 	      test=*it;
1921 	      break;
1922 	    }
1923 	  }
1924 	  if (it==itend)
1925 	    test=0;
1926 	}
1927 	if ( test.type>_CPLX ){
1928 	  if (isifte){
1929 	    gensizeerr(gettext("Ifte: Unable to check test"),res);
1930 	    return res;
1931 	  }
1932 	  else
1933 	    return symb_when(eval(args,1,contextptr));
1934 	}
1935       }
1936     }
1937 #else
1938     test=args._VECTptr->front();
1939     test=equaltosame(test.eval(eval_level(contextptr),contextptr)).eval(eval_level(contextptr),contextptr);
1940     if (!is_integer(test)){
1941       test=test.evalf_double(eval_level(contextptr),contextptr);
1942       if ( (test.type!=_DOUBLE_) && (test.type!=_CPLX) ){
1943 	if (isifte){
1944 	  gensizeerr(gettext("Ifte: Unable to check test"),res);
1945 	  return res;
1946 	}
1947 	else
1948 	  return symb_when(eval(args,1,contextptr));
1949       }
1950     }
1951 #endif
1952     bool rt;
1953     vecteur *argsptr=args._VECTptr;
1954     // *logptr(contextptr) << "Ifte " << debug_ptr(contextptr)->current_instruction << '\n' ;
1955     if (is_zero(test)){ // test false, do the else part
1956       if (isifte){
1957 	debug_struct * dbgptr=debug_ptr(contextptr);
1958 	increment_instruction((*argsptr)[1],dbgptr);
1959 	// *logptr(contextptr) << "Else " << debug_ptr(contextptr)->current_instruction << '\n' ;
1960 	++dbgptr->current_instruction;
1961 	if (dbgptr->debug_mode){
1962 	  debug_loop(test,contextptr);
1963 	  if (is_undef(test)) return test;
1964 	}
1965       }
1966       if (argsptr->back().type==_INT_)
1967 	return argsptr->back();
1968       gen clause_fausse=equaltosto(argsptr->back(),contextptr);
1969       rt=clause_fausse.is_symb_of_sommet(at_return);
1970       if (rt)
1971 	clause_fausse=clause_fausse._SYMBptr->feuille;
1972       // res=clause_fausse.eval(evallevel,contextptr);
1973       if (!clause_fausse.in_eval(evallevel,res,contextptr))
1974 	res=clause_fausse;
1975       if (rt && (res.type!=_SYMB || res._SYMBptr->sommet!=at_return))
1976 	res=symb_return(res);
1977       // *logptr(contextptr) << "Else " << debug_ptr(contextptr)->current_instruction << '\n' ;
1978     }
1979     else { // test true, do the then part
1980       if (isifte){
1981 	debug_struct * dbgptr=debug_ptr(contextptr);
1982 	++dbgptr->current_instruction;
1983 	if (dbgptr->debug_mode){
1984 	  debug_loop(test,contextptr);
1985 	  if (is_undef(test)) return test;
1986 	}
1987       }
1988       gen clause_vraie=equaltosto((*argsptr)[1],contextptr);
1989       rt=clause_vraie.is_symb_of_sommet(at_return);
1990       if (rt)
1991 	clause_vraie=clause_vraie._SYMBptr->feuille;
1992       // res=clause_vraie.eval(evallevel,contextptr);
1993       if (!clause_vraie.in_eval(evallevel,res,contextptr))
1994 	res=clause_vraie;
1995       if (rt && (res.type!=_SYMB || res._SYMBptr->sommet!=at_return) )
1996 	res=symb_return(res);
1997       // *logptr(contextptr) << "Then " << debug_ptr(contextptr)->current_instruction << '\n' ;
1998       if (isifte)
1999 	increment_instruction(argsptr->back(),contextptr);
2000       // *logptr(contextptr) << "Then " << debug_ptr(contextptr)->current_instruction << '\n' ;
2001     }
2002     return res;
2003   }
_ifte(const gen & args,const context * contextptr)2004   gen _ifte(const gen & args,const context * contextptr){
2005     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
2006     return ifte(args,true,contextptr);
2007   }
2008   static const char _ifte_s []="ifte";
2009   static define_unary_function_eval2_index (141,__ifte,&_ifte,_ifte_s,&printasifte);
2010   define_unary_function_ptr5( at_ifte ,alias_at_ifte,&__ifte,_QUOTE_ARGUMENTS,0);
2011 
_evalb(const gen & args,GIAC_CONTEXT)2012   gen _evalb(const gen & args,GIAC_CONTEXT){
2013     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
2014     if (args.type==_VECT) return apply(args,_evalb,contextptr);
2015     gen test=equaltosame(args);
2016     test=normal(test,contextptr);
2017     test=test.eval(eval_level(contextptr),contextptr);
2018     test=test.evalf_double(1,contextptr);
2019     if ( (test.type!=_DOUBLE_) && (test.type!=_CPLX) ){
2020       test=args.eval(eval_level(contextptr),contextptr);
2021       test=equaltosame(test);
2022       test=normal(test,contextptr);
2023       test=test.eval(eval_level(contextptr),contextptr);
2024       test=test.evalf_double(1,contextptr);
2025       if ( (test.type!=_DOUBLE_) && (test.type!=_CPLX) ){
2026 	return symbolic(at_evalb,args);
2027       }
2028     }
2029     gen g=is_zero(test)?zero:plus_one;
2030     g.subtype=_INT_BOOLEAN;
2031     return g;
2032   }
2033   static const char _evalb_s []="evalb";
2034   static define_unary_function_eval_quoted (__evalb,&_evalb,_evalb_s);
2035   define_unary_function_ptr5( at_evalb ,alias_at_evalb,&__evalb,_QUOTE_ARGUMENTS,true);
2036 
2037   static const char _maple_if_s []="if";
2038   static define_unary_function_eval2_quoted (__maple_if,&_ifte,_maple_if_s,&printasifte);
2039   define_unary_function_ptr5( at_maple_if ,alias_at_maple_if,&__maple_if,_QUOTE_ARGUMENTS,0);
2040 
printaswhen(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)2041   static string printaswhen(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
2042     bool b=calc_mode(contextptr)==38;
2043     if (b || xcas_mode(contextptr)|| feuille.type!=_VECT || feuille._VECTptr->size()!=3)
2044       return (b?"IFTE":sommetstr)+("("+feuille.print(contextptr)+")");
2045     vecteur & v=*feuille._VECTptr;
2046     if (calc_mode(contextptr)==1 || python_compat(contextptr)){
2047 #if 0
2048       string s="If["+v[0].print(contextptr)+","+v[1].print(contextptr);
2049       if (!is_undef(v[2]))
2050 	s +=","+v[2].print(contextptr);
2051       return s+"]";
2052 #else
2053       string s="when("+v[0].print(contextptr)+","+v[1].print(contextptr)+","+v[2].print(contextptr)+")";
2054       return s;
2055 #endif
2056     }
2057     return "(("+v[0].print(contextptr)+")? "+v[1].print(contextptr)+" : "+v[2].print(contextptr)+")";
2058   }
symb_when(const gen & t,const gen & a,const gen & b)2059   gen symb_when(const gen & t,const gen & a,const gen & b){
2060     return symbolic(at_when,gen(makevecteur(t,a,b),_SEQ__VECT));
2061   }
_when(const gen & args,const context * contextptr)2062   gen _when(const gen & args,const context * contextptr){
2063     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
2064     if (args.type!=_VECT)
2065       return gensizeerr(gettext("3 or 4 arguments expected"));
2066     vecteur & v=*args._VECTptr;
2067     if (v.size()==3){
2068       gen res=ifte(args,false,contextptr);
2069       return res;
2070     }
2071     if (v.size()!=4)
2072       return gentypeerr(contextptr);
2073     gen res=ifte(vecteur(v.begin(),v.begin()+3),false,contextptr);
2074     if (res.type==_SYMB && res._SYMBptr->sommet==at_when)
2075       return v[3];
2076     return res;
2077   }
2078   static const char _when_s []="when";
2079   static define_unary_function_eval2_quoted (__when,&_when,_when_s,&printaswhen);
2080   define_unary_function_ptr5( at_when ,alias_at_when,&__when,_QUOTE_ARGUMENTS,true);
2081 
2082   // loop
printasfor(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)2083   string printasfor(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
2084     if (feuille.type!=_VECT)
2085       return string(sommetstr)+('('+feuille.print(contextptr)+')');
2086     if (feuille._VECTptr->size()==2)
2087       return feuille._VECTptr->front().print(contextptr)+ " in "+feuille._VECTptr->back().print(contextptr);
2088     if (feuille._VECTptr->size()!=4)
2089       return string(sommetstr)+('('+feuille.print(contextptr)+')');
2090     int maplemode=xcas_mode(contextptr) & 0x07;
2091     if (abs_calc_mode(contextptr)==38)
2092       maplemode=4;
2093     const_iterateur it=feuille._VECTptr->begin();//,itend=feuille._VECTptr->end();
2094     string res;
2095     gen inc(from_increment(*(it+2)));
2096     bool python=python_compat(contextptr) && !debug_ptr(contextptr)->debug_mode;
2097     if (python){
2098       int & ind=debug_ptr(contextptr)->indent_spaces;
2099       if (inc.is_symb_of_sommet(at_sto) && inc._SYMBptr->feuille[1].type==_IDNT){
2100 	gen index=inc._SYMBptr->feuille[1];
2101 	if (inc._SYMBptr->feuille[0]==index+1 && it->is_symb_of_sommet(at_sto) && it->_SYMBptr->feuille[1]==index){
2102 	  gen start=it->_SYMBptr->feuille[0];
2103 	  if ((it+1)->type==_SYMB && ((it+1)->_SYMBptr->sommet==at_inferieur_egal || (it+1)->_SYMBptr->sommet==at_inferieur_strict) && (it+1)->_SYMBptr->feuille[0]==index){
2104 	    int large=(it+1)->_SYMBptr->sommet==at_inferieur_egal?1:0;
2105 	    gen stop=(it+1)->_SYMBptr->feuille[1];
2106 	    res +=  '\n'+string(ind,' ')+string("for ")+index.print(contextptr)+" in range(";
2107 	    if (start!=0)
2108 	      res +=start.print(contextptr)+",";
2109 	    res +=(stop+large).print(contextptr)+"):"+'\n';
2110 	    ind += 4;
2111 	    res += string(ind,' ')+(it+3)->print(contextptr);
2112 	    ind -=4;
2113 	    return res;
2114 	  }
2115 	}
2116       }
2117       if (it->type!=_INT_) res += '\n'+string(ind,' ')+it->print(contextptr)+'\n';
2118       res += '\n'+string(ind,' ')+string("while ") + (it+1)->print(contextptr)+" :";
2119       if (!(it+3)->is_symb_of_sommet(at_bloc))
2120 	res += '\n';
2121       ind += 4;
2122       res += string(ind,' ')+(it+3)->print(contextptr);
2123       if ((it+2)->type!=_INT_) res += '\n'+string(ind,' ')+(it+2)->print(contextptr);
2124       ind -=4;
2125       return res;
2126     }
2127     if (is_integer(*it) && is_integer(*(it+2))){
2128       ++it;
2129       if (is_one(*it) && (it+2)->is_symb_of_sommet(at_bloc)){
2130 	const gen & loopf=(it+2)->_SYMBptr->feuille;
2131 	if (loopf.type==_VECT && loopf._VECTptr->back().is_symb_of_sommet(at_ifte)){
2132 	  const vecteur & condv=*loopf._VECTptr->back()._SYMBptr->feuille._VECTptr;
2133 	  if (condv.size()==3 && is_zero(condv[2]) && condv[1].is_symb_of_sommet(at_break)){
2134 	    // repeat until condv[0] loop, loopf except the end is the loop
2135 	    vecteur corps=vecteur(loopf._VECTptr->begin(),loopf._VECTptr->end()-1);
2136 	    res = maplemode==4?"REPEAT ":"repeat ";
2137 	    res += printasinnerbloc(corps,contextptr);
2138 	    res += indent(contextptr);
2139 	    res += maplemode==4?"UNTIL ":"until ";
2140 	    res += condv[0].print();
2141 	    return res;
2142 	  }
2143 	}
2144       }
2145       bool dodone=false;
2146       if (it->is_symb_of_sommet(at_for) && it->_SYMBptr->feuille.type==_VECT && it->_SYMBptr->feuille._VECTptr->size()==2){
2147 	res = "for "+it->_SYMBptr->feuille._VECTptr->front().print(contextptr)+" in "+ it->_SYMBptr->feuille._VECTptr->back().print(contextptr)+ " do ";
2148 	dodone=true;
2149       }
2150       else {
2151 	if (maplemode>0){
2152 	  if (maplemode==3 && is_one(*it) ){
2153 	    it += 2;
2154 	    res="Loop";
2155 	    if ((it->type==_SYMB) && (it->_SYMBptr->sommet==at_bloc))
2156 	      res += printasinnerbloc(it->_SYMBptr->feuille,contextptr);
2157 	    else
2158 	      res += it->print(contextptr) +";";
2159 	    return res+indent(contextptr)+"'EndLoop";
2160 	  }
2161 	  if (maplemode==3)
2162 	    res = "While "+ sametoequal(*it).print(contextptr) +indent(contextptr);
2163 	  else
2164 	    res = (maplemode==4?"WHILE ":"while ") + sametoequal(*it).print(contextptr) + (maplemode==4?" DO":" do ");
2165 	}
2166 	else
2167 	  res = "while("+it->print(contextptr)+")";
2168       }
2169       ++it;
2170       ++it;
2171       debug_ptr(contextptr)->indent_spaces += 2;
2172       if ((maplemode>0 || res.substr(res.size()-3,3)=="do ") && (it->type==_SYMB) && (it->_SYMBptr->sommet==at_bloc))
2173 	res += printasinnerbloc(it->_SYMBptr->feuille,contextptr)+";";
2174       else
2175 	res += it->print(contextptr) +";";
2176       debug_ptr(contextptr)->indent_spaces -= 2;
2177       if (maplemode==1 || dodone)
2178 	return res+indent(contextptr)+" od;";
2179       if (maplemode==2)
2180 	return res+indent(contextptr)+" end_while;";
2181       if (maplemode==3)
2182 	return res+indent(contextptr)+" EndWhile";
2183       if (maplemode==4)
2184 	return res+indent(contextptr)+" END;";
2185     }
2186     else {
2187       if (maplemode>0){// pb for generic loops for Maple translation
2188 	gen inc=from_increment(*(it+2));
2189 	if ( (it->type!=_SYMB) || (it->_SYMBptr->sommet!=at_sto) || (inc.type!=_SYMB) || inc._SYMBptr->sommet!=at_sto || (it->_SYMBptr->feuille._VECTptr->back()!=inc._SYMBptr->feuille._VECTptr->back()) )
2190 	  return gettext("Maple/Mupad/TI For: unable to convert");
2191 	gen var_name=it->_SYMBptr->feuille._VECTptr->back();
2192 	gen step=normal(inc._SYMBptr->feuille._VECTptr->front()-var_name,contextptr);
2193 	gen condition=*(it+1),limite=plus_inf;
2194 	if (is_positive(-step,contextptr))
2195 	  limite=minus_inf;
2196 	bool simple_loop=false,strict=true,ascending=true;
2197 	if (condition.type==_SYMB){
2198 	  unary_function_ptr op=condition._SYMBptr->sommet;
2199 	  if (condition._SYMBptr->feuille.type==_VECT){
2200 	    if (op==at_inferieur_strict)
2201 	      simple_loop=true;
2202 	    if (op==at_inferieur_egal){
2203 	      strict=false;
2204 	      simple_loop=true;
2205 	    }
2206 	    if (op==at_superieur_strict){
2207 	      simple_loop=(maplemode>=2);
2208 	      ascending=false;
2209 	    }
2210 	    if (op==at_superieur_egal){
2211 	      simple_loop=(maplemode>=2);
2212 	      ascending=false;
2213 	      strict=false;
2214 	    }
2215 	  }
2216 	  if (simple_loop){
2217 	    simple_loop=(condition._SYMBptr->feuille._VECTptr->front()==var_name);
2218 	    limite=condition._SYMBptr->feuille._VECTptr->back();
2219 	  }
2220 	}
2221 	if (maplemode==3)
2222 	  res="For ";
2223 	else
2224 	  res = (maplemode==4?"FOR ":"for ");
2225 	res += var_name.print(contextptr);
2226 	if (maplemode==3)
2227 	  res += ",";
2228 	else
2229 	  res += (maplemode==4?" FROM ":" from ");
2230 	res += it->_SYMBptr->feuille._VECTptr->front().print(contextptr);
2231 	if (maplemode==3){
2232 	  res += ","+limite.print(contextptr);
2233 	  if (!is_one(step))
2234 	    res += ","+step.print(contextptr);
2235 	  if (!simple_loop)
2236 	    res += indent(contextptr)+"If not("+(it+1)->print(contextptr)+")"+indent(contextptr)+"Exit";
2237 	  res += indent(contextptr);
2238 	}
2239 	else {
2240 	  gen absstep=step;
2241 	  if (simple_loop){
2242 	    absstep = abs(step,contextptr);
2243 	    if (ascending)
2244 	      res += maplemode==4?" TO ":" to ";
2245 	    else
2246 	      res += maplemode==4?" DOWNTO ":" downto ";
2247 	    res += limite.print(contextptr);
2248 #ifndef BCD
2249 	    if (!strict && !is_integer(step)){
2250 	      if (ascending)
2251 		res +="+";
2252 	      else
2253 		res += "-";
2254 	      res += absstep.print(contextptr);
2255 	      res += "/2";
2256 	    }
2257 #endif
2258 	  }
2259 	  if (!is_one(absstep)){
2260 	    if (maplemode==2)
2261 	      res += " step ";
2262 	    else
2263 	      res += maplemode==4?" STEP ":" by ";
2264 	    res += step.print(contextptr);
2265 	  }
2266 	  if (!simple_loop){
2267 	    res += (maplemode==4)?" WHILE ":" while ";
2268 	    res += (it+1)->print(contextptr);
2269 	  }
2270 	  res += maplemode==4?" DO ":" do ";
2271 	}
2272 	it += 3;
2273 	if ((it->type==_SYMB) && (it->_SYMBptr->sommet==at_bloc))
2274 	  res += printasinnerbloc(it->_SYMBptr->feuille,contextptr)+";";
2275 	else
2276 	  res += it->print(contextptr)+";" ;
2277 	if (maplemode==1)
2278 	  return res + indent(contextptr)+" od;";
2279 	if (maplemode==2)
2280 	  return res + indent(contextptr)+" end_for;";
2281 	if (maplemode==3)
2282 	  return res + indent(contextptr)+"EndFor";
2283 	if (maplemode==4)
2284 	  return res + indent(contextptr)+"END;";
2285       }
2286       res="for (";
2287       res += it->print(contextptr) + ';';
2288       ++it;
2289       res += it->print(contextptr) + ';';
2290       ++it;
2291       res += it->print(contextptr) + ") ";
2292       ++it;
2293       debug_ptr(contextptr)->indent_spaces += 2;
2294       res += it->print(contextptr) ;
2295       debug_ptr(contextptr)->indent_spaces -= 2;
2296     }
2297     if (res[res.size()-1]!='}')
2298       res += "; ";
2299     return res;
2300   }
symb_for(const gen & e)2301   symbolic symb_for(const gen & e){
2302     return symbolic(at_for,e);
2303   }
symb_for(const gen & a,const gen & b,const gen & c,const gen & d)2304   symbolic symb_for(const gen & a,const gen & b,const gen & c,const gen & d){
2305     return symbolic(at_for,gen(makevecteur(a,b,c,d),_SEQ__VECT));
2306   }
2307 
to_increment(const gen & g)2308   static gen to_increment(const gen & g){
2309     if (!g.is_symb_of_sommet(at_sto))
2310       return g;
2311     gen & f =g._SYMBptr->feuille;
2312     if (f.type!=_VECT || f._VECTptr->size()!=2)
2313       return g;
2314     gen & a = f._VECTptr->front();
2315     gen & b = f._VECTptr->back();
2316     if (b.type!=_IDNT || a.type!=_SYMB)
2317       return g;
2318     gen & af=a._SYMBptr->feuille;
2319     if (af.type!=_VECT || af._VECTptr->empty())
2320       return g;
2321     vecteur & av= *af._VECTptr;
2322     int s=int(av.size());
2323     int type=0;
2324     if (a.is_symb_of_sommet(at_plus))
2325       type=1;
2326     // there was a wrong test with at_minus for -= (type=-1)
2327     if (type && av.front()==b){
2328       if (s==2){
2329 	if (is_one(av.back()))
2330 	  return symbolic(type==1?at_increment:at_decrement,b);
2331 	if (is_minus_one(av.back()))
2332 	  return symbolic(type==1?at_decrement:at_increment,b);
2333 	return symbolic(type==1?at_increment:at_decrement,gen(makevecteur(b,av.back()),_SEQ__VECT));
2334       }
2335       if (type)
2336 	return symbolic(at_increment,gen(makevecteur(b,symbolic(at_plus,vecteur(av.begin()+1,av.end()))),_SEQ__VECT));
2337     }
2338     return g;
2339   }
ck_is_one(gen & g,GIAC_CONTEXT)2340   static bool ck_is_one(gen & g,GIAC_CONTEXT){
2341     if (is_one(g))
2342       return true;
2343     if (g.type==_VECT && python_compat(contextptr)){
2344       // OR test on a list
2345       const_iterateur it=g._VECTptr->begin(),itend=g._VECTptr->end();
2346       for (;it!=itend;++it){
2347 	if (!is_zero(*it,contextptr))
2348 	  return true;
2349       }
2350       return false;
2351     }
2352     if (g.type>_POLY){
2353       g=gensizeerr(gettext("Unable to eval test in loop : ")+g.print());
2354       return false; // this will stop the loop in caller
2355     }
2356     return false;
2357   }
set_for_in(int counter,int for_in,vecteur * v,string * s,const gen & name,GIAC_CONTEXT)2358   static bool set_for_in(int counter,int for_in,vecteur * v,string * s,const gen & name,GIAC_CONTEXT){
2359     int taille=int(v?v->size():s->size());
2360     if (counter>0 && counter<=taille){
2361       if (v)
2362 	(*v)[counter-1]=eval(name,1,contextptr);
2363       else {
2364 	if (s){
2365 	  gen g=eval(name,1,contextptr);
2366 	  if (g.type==_STRNG && !g._STRNGptr->empty())
2367 	    (*s)[counter-1]=(*g._STRNGptr)[0];
2368 	}
2369       }
2370     }
2371     if (counter<0 || counter>=taille)
2372       return false;
2373     gen res;
2374     if (v){
2375       res=(*v)[counter];
2376       res=sto(res,name,contextptr);
2377     }
2378     else {
2379       char ch=(*s)[counter];
2380       res=sto(string2gen(string(1,ch),false),name,contextptr);
2381     }
2382     return !is_undef(res);
2383   }
for_test(const gen & test,gen & testf,int eval_lev,context * contextptr)2384   inline bool for_test(const gen & test,gen & testf,int eval_lev,context * contextptr){
2385     // ck_is_one( (testf=test.eval(eval_lev,newcontextptr).evalf(1,newcontextptr)) )
2386     if (!test.in_eval(eval_lev,testf,contextptr))
2387       testf=test;
2388     //testf=test.eval(eval_lev,contextptr);
2389     if (testf.type==_INT_)
2390       return testf.val;
2391     if (testf.type==_FRAC)
2392       testf=testf._FRACptr->num;
2393     if (test.type<=_POLY)
2394       return !is_exactly_zero(test);
2395     if (testf.type==_MAP)
2396       return !testf._MAPptr->empty();
2397     testf=testf.evalf(1,contextptr);
2398     return ck_is_one(testf,contextptr);
2399   }
2400 
2401   // return false if forprog modifies index or stopg
2402   bool chk_forprog(const gen & forprog,const gen & index,const gen & stopg);
chk_forprog(const vecteur & forprog,const gen & index,const gen & stopg)2403   bool chk_forprog(const vecteur & forprog,const gen & index,const gen & stopg){
2404     const_iterateur it=forprog.begin(),itend=forprog.end();
2405     for (;it!=itend;++it){
2406       if (!chk_forprog(*it,index,stopg))
2407 	return false;
2408     }
2409     return true;
2410   }
chk_forprog(const gen & forprog,const gen & index,const gen & stopg)2411   bool chk_forprog(const gen & forprog,const gen & index,const gen & stopg){
2412     if (forprog.type==_VECT)
2413       return chk_forprog(*forprog._VECTptr,index,stopg);
2414     if (forprog.type!=_SYMB || forprog.subtype==_FORCHK__SYMB)
2415       return true;
2416     unary_function_ptr & u=forprog._SYMBptr->sommet;
2417     if (u==at_sto || u==at_array_sto){
2418       const gen * to=&(*forprog._SYMBptr->feuille._VECTptr)[1];
2419       if (*to==index || *to==stopg)
2420 	return false;
2421     }
2422     if (u==at_increment || u==at_decrement){
2423       const gen * to=&forprog._SYMBptr->feuille;
2424       if (to->type==_VECT) to=&to->_VECTptr->front();
2425       if (*to==index || *to==stopg)
2426 	return false;
2427     }
2428     if (!chk_forprog(forprog._SYMBptr->feuille,index,stopg))
2429       return false;
2430     ((gen *) &forprog)->subtype=_FORCHK__SYMB;
2431     return true;
2432   }
_for(const gen & args,const context * contextptr)2433   gen _for(const gen & args,const context * contextptr){
2434     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
2435     // for elem in list: for(elem,list), inert form
2436     if (args.type!=_VECT || args._VECTptr->size()==2)
2437       return symb_for(args);
2438     const vecteur & argsv = *args._VECTptr;
2439     if (argsv.size()!=4)
2440       return gensizeerr(gettext("For must have 4 args"));
2441     // Initialization
2442     gen initialisation=argsv.front(),forelse;
2443     // add assigned variables to be local
2444     bool bound=false;
2445     vecteur loop_var;
2446     int protect=0;
2447     context * newcontextptr=(context * ) contextptr;
2448     if ( (initialisation.type==_SYMB) && (initialisation._SYMBptr->sommet==at_sto)){
2449       gen variable=initialisation._SYMBptr->feuille._VECTptr->back();
2450       if (variable.type==_IDNT){
2451 	if (contextptr==context0 && (xcas_mode(contextptr)!=1 && (!variable._IDNTptr->localvalue || variable._IDNTptr->localvalue->empty() || (*variable._IDNTptr->localvalue)[variable._IDNTptr->localvalue->size()-2].val<protection_level-1) ) ){
2452 	  bound=true;
2453 	  loop_var=makevecteur(variable);
2454 	  protect=giac_bind(makevecteur(zero),loop_var,newcontextptr);
2455 	}
2456       }
2457       else {
2458 #ifndef NO_STDEXCEPT
2459 	throw(std::runtime_error(gettext("Invalid loop index (hint: i=sqrt(-1)!)")));
2460 #endif
2461 	return undeferr(gettext("Invalid loop index (hint: i=sqrt(-1)!)"));
2462       }
2463     }
2464     gen test=argsv[1];
2465     if (is_equal(test))
2466       test = symb_same(test._SYMBptr->feuille._VECTptr->front(),test._SYMBptr->feuille._VECTptr->back());
2467     // FIXME: eval local variables in test that are not in increment and prog
2468     gen increment=to_increment(argsv[2]);
2469     gen prog=argsv[3];
2470     if (prog.type==_SYMB && prog._SYMBptr->sommet==at_bloc)
2471       prog=prog._SYMBptr->feuille;
2472     vecteur forprog=prog.type==_VECT?*prog._VECTptr:vecteur(1,prog);
2473     iterateur it,itbeg=forprog.begin(),itend=forprog.end();
2474     for (it=itbeg;it!=itend;++it){
2475       *it=to_increment(equaltosto(*it,contextptr));
2476     }
2477     gen res,oldres;
2478     // loop
2479     int eval_lev=eval_level(newcontextptr);
2480     debug_struct * dbgptr=debug_ptr(newcontextptr);
2481     int & dbgptr_current_instruction = dbgptr->current_instruction;
2482     int save_current_instruction=dbgptr_current_instruction;
2483     gen testf;
2484 #ifndef NO_STDEXCEPT
2485     try {
2486 #endif
2487       bool findlabel=false;
2488       gen label,newres;
2489       int counter=0;
2490       int for_in=0; // 1 in list, 2 in string
2491       vecteur * for_in_v=0;
2492       string * for_in_s=0;
2493       gen index_name;
2494       gen gforin;
2495       size_t testsize=0;
2496       if ((test.is_symb_of_sommet(at_for) || test.is_symb_of_sommet(at_pour))&& test._SYMBptr->feuille.type==_VECT && (testsize=test._SYMBptr->feuille._VECTptr->size())>=2){
2497 	gen tmp=eval((*test._SYMBptr->feuille._VECTptr)[1],eval_lev,newcontextptr);
2498 	if (testsize==3)
2499 	  forelse=(*test._SYMBptr->feuille._VECTptr)[2];
2500 	bool ismap=tmp.type==_MAP;
2501 	if (ismap){
2502 	  // copy indices
2503 	  vecteur v;
2504 	  gen_map::iterator it=tmp._MAPptr->begin(),itend=tmp._MAPptr->end();
2505 	  for (;it!=itend;++it){
2506 	    v.push_back(it->first);
2507 	  }
2508 	  tmp=v;
2509 	}
2510 	if (tmp.type==_VECT){
2511 	  // re-store a copy of tmp because we might modify it inplace
2512 	  // (not for maps)
2513 	  gforin=gen(*tmp._VECTptr,tmp.subtype);
2514 	  if (!ismap && test._SYMBptr->feuille._VECTptr->back().type==_IDNT)
2515 	    sto(gforin,test._SYMBptr->feuille._VECTptr->back(),false,contextptr);
2516 	  for_in_v=gforin._VECTptr;
2517 	  for_in=1;
2518 	}
2519 	else {
2520 	  if (tmp.type==_STRNG){
2521 	    // re-store a copy of tmp because we might modify it inplace
2522 	    gforin=string2gen(*tmp._STRNGptr,false);
2523 	    if (test._SYMBptr->feuille._VECTptr->back().type==_IDNT)
2524 	      sto(gforin,test._SYMBptr->feuille._VECTptr->back(),false,contextptr);
2525 	    for_in_s=gforin._STRNGptr;
2526 	    for_in=2;
2527 	  }
2528 	  else
2529 	    return gensizeerr(contextptr);
2530 	}
2531 	index_name=test._SYMBptr->feuille._VECTptr->front();
2532       }
2533       // check if we have a standard for loop
2534       bool stdloop=(itend-it)<5 && contextptr && !for_in && is_inequation(test) && test._SYMBptr->feuille.type==_VECT && test._SYMBptr->feuille._VECTptr->size()==2 && !dbgptr->debug_mode;
2535       stdloop = stdloop && increment.type==_SYMB && (increment._SYMBptr->sommet==at_increment || increment._SYMBptr->sommet==at_decrement);
2536       gen index,stopg;
2537       int *idx=0,step,stop;
2538       if (stdloop){
2539 	index=increment._SYMBptr->feuille;
2540 	if (index.type==_VECT) index=index._VECTptr->front();
2541 	stdloop=index==test._SYMBptr->feuille._VECTptr->front();
2542       }
2543       // loop initialisation
2544       equaltosto(initialisation,contextptr).eval(eval_lev,newcontextptr);
2545       if (stdloop){
2546 	stopg=test._SYMBptr->feuille._VECTptr->back();
2547 	gen stopindex=eval(stopg,1,contextptr);
2548 	is_integral(stopindex);
2549 	stop=stopindex.val;
2550 	gen incrementstep=increment._SYMBptr->feuille;
2551 	incrementstep=incrementstep.type==_VECT?incrementstep._VECTptr->back():1;
2552 	is_integral(incrementstep);
2553 	step=incrementstep.val;
2554 	if (increment._SYMBptr->sommet==at_decrement)
2555 	  step=-step;
2556 	stdloop=index.type==_IDNT && incrementstep.type==_INT_ && stopindex.type==_INT_;
2557       }
2558       if (stdloop){
2559 	const context * cur=contextptr;
2560 	sym_tab::iterator it=cur->tabptr->end(),itend=it;
2561 	for (;cur->previous;cur=cur->previous){
2562 	  it=cur->tabptr->find(index._IDNTptr->id_name);
2563 	  itend=cur->tabptr->end();
2564 	  if (it!=itend)
2565 	    break;
2566 	}
2567 	if (it==itend){
2568 	  it=cur->tabptr->find(index._IDNTptr->id_name);
2569 	  itend=cur->tabptr->end();
2570 	}
2571 	// compute idx
2572 	if (it!=itend && it->second.type==_INT_
2573      	    && (stop-it->second.val)/step>=5){
2574 	  idx=&it->second.val;
2575 	  // adjust stop for a loop with condition *idx!=stop
2576 	  int niter=-1;
2577 	  unary_function_ptr & u=test._SYMBptr->sommet;
2578 	  if (u==at_inferieur_strict) {
2579 	    if (*idx>=stop)
2580 	      niter=0;
2581 	    else
2582 	      niter=step<0?-1:(stop+step-1-*idx)/step;
2583 	  }
2584 	  if (u==at_superieur_strict){
2585 	    if (*idx<=stop)
2586 	      niter=0;
2587 	    else
2588 	      niter=step>0?-1:(*idx-stop-step-1)/(-step);
2589 	  }
2590 	  if (u==at_inferieur_egal){
2591 	    if (*idx>stop)
2592 	      niter=0;
2593 	    else
2594 	      niter=step<0?-1:(stop+step-*idx)/step;
2595 	  }
2596 	  if (u==at_superieur_egal){
2597 	    if (*idx<stop)
2598 	      niter=0;
2599 	    else
2600 	      niter=step>0?-1:(*idx-stop-step)/(-step);
2601 	  }
2602 	  if (niter<0){
2603 	    if (bound)
2604 	      leave(protect,loop_var,newcontextptr);
2605 	    return gensizeerr("Infinite number of iterations");
2606 	  }
2607 	  stop=*idx+niter*step;
2608 	  // check that index and stopg are not modified inside the loop
2609 	  if (!chk_forprog(forprog,index,stopg))
2610 	    idx=0;
2611 	}
2612       }
2613       bool oneiter=idx && (itend-itbeg==1) && !dbgptr->debug_mode;
2614       if (oneiter){
2615 	for (;!interrupted && *idx!=stop;*idx+=step){
2616 #ifdef SMARTPTR64
2617 	  swapgen(oldres,res);
2618 #else
2619 	  oldres=res;
2620 #endif
2621 	  if (!itbeg->in_eval(eval_lev,res,newcontextptr))
2622 	    res=*itbeg;
2623 	  if (res.type!=_SYMB)
2624 	    continue;
2625 	  if (is_return(res,newres)) {
2626 	    if (bound)
2627 	      leave(protect,loop_var,newcontextptr);
2628 	    return res;
2629 	  }
2630 	  unary_function_ptr & u=res._SYMBptr->sommet;
2631 	  if (u==at_break){
2632 	    res=u; // res=oldres;
2633 	    break;
2634 	  }
2635 	  if (u==at_continue){
2636 	    res=oldres;
2637 	    break;
2638 	  }
2639 	}
2640       }
2641       else {
2642 	for (;
2643 #pragma clang diagnostic push
2644 #pragma clang diagnostic ignored "-Wunused-value"
2645 	     idx?*idx!=stop:((for_in && test.val)?set_for_in(counter,for_in,for_in_v,for_in_s,index_name,newcontextptr):for_test(test,testf,eval_lev,newcontextptr));
2646 	     ++counter,idx?*idx+=step:((test.val && increment.type)?increment.eval(eval_lev,newcontextptr).val:0)
2647 #pragma clang diagnostic pop
2648 	     ){
2649 	  if (interrupted || (testf.type!=_INT_ && is_undef(testf)))
2650 	    break;
2651 	  dbgptr_current_instruction=save_current_instruction;
2652 	  findlabel=false;
2653 	  // add a test for boucle of type program/composite
2654 	  // if that's the case call eval with test for break and continue
2655 	  for (it=itbeg;!interrupted && it!=itend;++it){
2656 #ifdef SMARTPTR64
2657 	    swapgen(oldres,res);
2658 #else
2659 	    oldres=res;
2660 #endif
2661 	    ++dbgptr_current_instruction;
2662 	    if (dbgptr->debug_mode){
2663 	      debug_loop(res,newcontextptr);
2664 	      if (is_undef(res)){
2665 		increment_instruction(it+1,itend,dbgptr);
2666 		if (bound)
2667 		  leave(protect,loop_var,newcontextptr);
2668 		return res;
2669 	      }
2670 	    }
2671 	    if (!findlabel){
2672 	      // res=it->eval(eval_lev,newcontextptr);
2673 	      if (!it->in_eval(eval_lev,res,newcontextptr))
2674 		res=*it;
2675 	      if (res.type<=_POLY)
2676 		continue;
2677 	    }
2678 	    else {
2679 #ifdef TIMEOUT
2680 	      control_c();
2681 #endif
2682 	      if (ctrl_c || interrupted || (res.type==_STRNG && res.subtype==-1)){
2683 		interrupted = true; ctrl_c=false;
2684 		*logptr(contextptr) << gettext("Stopped in loop") << '\n';
2685 		gensizeerr(gettext("Stopped by user interruption."),res);
2686 		break;
2687 	      }
2688 	      res=*it;
2689 	    }
2690 	    if (is_return(res,newres)) {
2691 	      increment_instruction(it+1,itend,dbgptr);
2692 	      if (bound)
2693 		leave(protect,loop_var,newcontextptr);
2694 	      return res;
2695 	    }
2696 	    if (res.type==_SYMB){
2697 	      unary_function_ptr & u=res._SYMBptr->sommet;
2698 	      if (!findlabel){
2699 		if (u==at_break){
2700 		  increment_instruction(it+1,itend,dbgptr);
2701 		  test=zero;
2702 		  idx=0;
2703 		  res=u; // res=oldres;
2704 		  break;
2705 		}
2706 		if (u==at_continue){
2707 		  increment_instruction(it+1,itend,dbgptr);
2708 		  res=oldres;
2709 		  break;
2710 		}
2711 	      }
2712 	      else {
2713 		if (u==at_label && label==res._SYMBptr->feuille)
2714 		  findlabel=false;
2715 	      }
2716 	      if (!findlabel && u==at_goto){
2717 		findlabel=true;
2718 		label=res._SYMBptr->feuille;
2719 	      }
2720 	    } // end res.type==_SYMB
2721 	    if (findlabel && it+1==itend)
2722 	      it=itbeg-1;
2723 	  } // end of loop of FOR bloc instructions
2724 	} // end of user FOR loop
2725       } // end else one iteration
2726       dbgptr->current_instruction=save_current_instruction;
2727       increment_instruction(itbeg,itend,dbgptr);
2728 #ifndef NO_STDEXCEPT
2729     } // end try
2730     catch (std::runtime_error & e){
2731       last_evaled_argptr(contextptr)=NULL;
2732       if (bound)
2733 	leave(protect,loop_var,newcontextptr);
2734       return gensizeerr(e.what());
2735       gen res(string2gen(e.what(),false));
2736       res.subtype=-1;
2737       return res;
2738     }
2739 #endif
2740     if (bound)
2741       leave(protect,loop_var,newcontextptr);
2742     if (is_undef(testf))
2743       return testf;
2744     if (res!=at_break && forelse!=0)
2745       forelse.in_eval(eval_lev,res,contextptr);
2746     return res==at_break?string2gen("breaked",false):res;
2747   }
2748 
2749   static const char _for_s []="for";
2750   static define_unary_function_eval2_index (143,__for,&_for,_for_s,&printasfor);
2751   define_unary_function_ptr5( at_for ,alias_at_for,&__for,_QUOTE_ARGUMENTS,0);
2752 
2753   // returns level or -RAND_MAX on error
giac_bind(const vecteur & vals_,const vecteur & vars_,context * & contextptr)2754   int giac_bind(const vecteur & vals_,const vecteur & vars_,context * & contextptr){
2755     vecteur vals(vals_),vars(vars_),vals1,vars1;
2756     // reorder: search in vals_ var=value and corresponding vars in vars_
2757     for (int i=0;i<vals_.size();++i){
2758       if (!vals[i].is_symb_of_sommet(at_equal))
2759 	continue;
2760       gen f=vals[i]._SYMBptr->feuille;
2761       if (f.type!=_VECT || f._VECTptr->size()!=2 || f._VECTptr->front().type!=_IDNT)
2762 	continue;
2763       gen var=f._VECTptr->front(),val=f._VECTptr->back();int j=0;
2764       for (;j<vars.size();++j){
2765 	if (!vars[i].is_symb_of_sommet(at_equal))
2766 	  continue;
2767 	f=vars[j]._SYMBptr->feuille;
2768 	if (f.type!=_VECT || f._VECTptr->size()!=2 || f._VECTptr->front()!=var)
2769 	  continue;
2770 	break;
2771       }
2772       if (j<vars.size()){
2773 	vars1.push_back(var);
2774 	vals1.push_back(val);
2775 	vars.erase(vars.begin()+j);
2776 	vals.erase(vals.begin()+i);
2777 	--i;
2778       }
2779     }
2780     // add remaining
2781     vals=mergevecteur(vals1,vals);
2782     vars=mergevecteur(vars1,vars);
2783 #if 1
2784     int ins=int(vals.size());
2785     for (int i=int(vars.size())-1;i>=0;--i){
2786       if (vars.size()<=vals.size())
2787 	break;
2788       if (vars[i].is_symb_of_sommet(at_equal))
2789 	vals.insert(vals.begin()+ins,eval(vars[i]._SYMBptr->feuille[1],prog_eval_level(contextptr),contextptr));
2790       else {
2791 	if (ins>0)
2792 	  --ins;
2793       }
2794     }
2795 #else
2796     for (;vars.size()>vals.size();){
2797       int s=int(vals.size());
2798       if (!vars[s].is_symb_of_sommet(at_equal))
2799 	break;
2800       vals.push_back(vars[s]._SYMBptr->feuille[1]);
2801     }
2802 #endif
2803     for (int i=0;i<vars.size();++i){
2804       if (vars[i].is_symb_of_sommet(at_equal))
2805 	vars[i]=vars[i]._SYMBptr->feuille[0];
2806     }
2807 #ifdef KHICAS
2808     if (vals.size()==1 && vars.size()!=1 && vals.front().type==_VECT)
2809       vals=*vals.front()._VECTptr;
2810 #endif
2811     if (vals.size()!=vars.size()){
2812 #ifdef DEBUG_SUPPORT
2813       setsizeerr(gen(vals).print(contextptr)+ " size() != " + gen(vars).print(contextptr));
2814 #endif
2815       return -RAND_MAX;
2816     }
2817     if (debug_ptr(contextptr)->debug_localvars)
2818       *debug_ptr(contextptr)->debug_localvars=vars;
2819     const_iterateur it=vals.begin(),itend=vals.end();
2820     const_iterateur jt=vars.begin();
2821     gen tmp;
2822     if (contextptr){
2823       context * newcontextptr = new context(* contextptr);
2824       newcontextptr->tabptr = new sym_tab;
2825       if (contextptr->globalcontextptr)
2826 	newcontextptr->globalcontextptr = contextptr->globalcontextptr;
2827       else
2828 	newcontextptr->globalcontextptr = contextptr;
2829       newcontextptr->previous=contextptr;
2830       contextptr=newcontextptr;
2831       if (debug_ptr(contextptr))
2832 	debug_ptr(contextptr)->debug_contextptr=contextptr;
2833     }
2834     for (;it!=itend;++it,++jt){
2835       if (jt->type==_SYMB){
2836 	if (jt->_SYMBptr->sommet==at_check_type){
2837 	  tmp=jt->_SYMBptr->feuille._VECTptr->back();
2838 	  if (is_undef(_check_type(makevecteur(jt->_SYMBptr->feuille._VECTptr->front(),*it),contextptr)))
2839 	    return -RAND_MAX;
2840 	}
2841 	else {
2842 	  if (jt->_SYMBptr->sommet==at_double_deux_points ){
2843 	    tmp=jt->_SYMBptr->feuille._VECTptr->front();
2844 	    if (is_undef(_check_type(makevecteur(jt->_SYMBptr->feuille._VECTptr->back(),*it),contextptr)))
2845 	      return -RAND_MAX;
2846 	  }
2847 	  else {
2848 	    if (jt->_SYMBptr->sommet==at_of){
2849 	      tmp=jt->_SYMBptr->feuille._VECTptr->front();
2850 	      *logptr(contextptr) << gettext("Invalid variable ")+jt->print(contextptr)+gettext(" using ")+tmp.print(contextptr)+gettext(" instead.");
2851 	    }
2852 	    else
2853 	      tmp=*jt;
2854 	  }
2855 	}
2856       }
2857       else
2858 	tmp=*jt;
2859       if (tmp.type==_IDNT){
2860 	const char * name=tmp._IDNTptr->id_name;
2861 	int bl=strlen(name);
2862 	gen a=*it;
2863 	if (bl>=2 && name[bl-2]=='_' && (a.type!=_STRNG || a.subtype!=-1)){
2864 	  switch (name[bl-1]){
2865 	  case 'd':
2866 	    if (a.type!=_INT_ && a.type!=_DOUBLE_ && a.type!=_FRAC){
2867 	      *logptr(contextptr) << gettext("Unable to convert to float ")+a.print(contextptr) << '\n';
2868 	      return -RAND_MAX;
2869 	    }
2870 	    break;
2871 	  case 'f':
2872 	    if (a.type==_FRAC)
2873 	      break;
2874 	  case 'i': case 'l':
2875 	    if (a.type==_DOUBLE_ && a._DOUBLE_val<=RAND_MAX && a._DOUBLE_val>=-RAND_MAX){
2876 	      int i=int(a._DOUBLE_val);
2877 	      if (i!=a._DOUBLE_val)
2878 		*logptr(contextptr) << gettext("Converting ") << a._DOUBLE_val << gettext(" to integer ") << i << '\n';
2879 	      a=i;
2880 	    }
2881 	    else{
2882 	      if (a.type!=_INT_){
2883 		if (a.type!=_ZINT || mpz_sizeinbase(*a._ZINTptr,2)>62){
2884 		  *logptr(contextptr) << gettext("Unable to convert to integer ")+a.print(contextptr) << '\n';
2885 		  return -RAND_MAX;
2886 		}
2887 	      }
2888 	    }
2889 	    break;
2890 	  case 'v':
2891 	    if (a.type!=_VECT){
2892 	      *logptr(contextptr) << gettext("Unable to convert to vector ")+a.print(contextptr) << '\n';
2893 	      return -RAND_MAX;
2894 	    }
2895 	    break;
2896 	  case 's':
2897 	    if (a.type!=_STRNG)
2898 	      a=string2gen(a.print(contextptr),false);
2899 	  }
2900 	}
2901 	if (contextptr)
2902 	  (*contextptr->tabptr)[tmp._IDNTptr->id_name]=globalize(a);
2903 	else
2904 	  tmp._IDNTptr->push(protection_level,globalize(a));
2905       }
2906       else {
2907 	if (tmp.type==_FUNC){
2908 #ifndef NO_STDEXCEPT
2909 	  setsizeerr(gettext("Reserved word:")+tmp.print(contextptr));
2910 #else
2911 	  *logptr(contextptr) << gettext("Reserved word:")+tmp.print(contextptr) << '\n';
2912 #endif
2913 	  return -RAND_MAX;
2914 	}
2915 	else {
2916 #ifndef NO_STDEXCEPT
2917 	  setsizeerr(gettext("Not bindable")+tmp.print(contextptr));
2918 #else
2919 	  *logptr(contextptr) << gettext("Not bindable")+tmp.print(contextptr) << '\n';
2920 #endif
2921 	  return -RAND_MAX;
2922 	}
2923       }
2924     }
2925     if (!contextptr)
2926       ++protection_level;
2927     return protection_level-1;
2928   }
2929 
leave(int protect,vecteur & vars,context * & contextptr)2930   bool leave(int protect,vecteur & vars,context * & contextptr){
2931     iterateur it=vars.begin(),itend=vars.end(),jt,jtend;
2932     gen tmp;
2933     if (contextptr){
2934       if (contextptr->previous){
2935 	context * tmpptr=contextptr;
2936 	contextptr=contextptr->previous;
2937 	if (debug_ptr(contextptr))
2938 	  debug_ptr(contextptr)->debug_contextptr=contextptr;
2939 	if (tmpptr->tabptr){
2940 	  delete tmpptr->tabptr;
2941 	  delete tmpptr;
2942 	  return true;
2943 	}
2944       }
2945       return false;
2946     }
2947     for (;it!=itend;++it){
2948       if (it->type==_SYMB && it->_SYMBptr->sommet==at_check_type)
2949 	tmp=it->_SYMBptr->feuille._VECTptr->back();
2950       else {
2951 	if (it->type==_SYMB && it->_SYMBptr->sommet==at_double_deux_points)
2952 	  tmp=it->_SYMBptr->feuille._VECTptr->front();
2953 	else
2954 	  tmp=*it;
2955       }
2956 #ifdef DEBUG_SUPPORT
2957       if (tmp.type!=_IDNT) setsizeerr(gettext("prog.cc/leave"));
2958 #endif
2959       if (tmp._IDNTptr->localvalue){
2960 	jt=tmp._IDNTptr->localvalue->begin(),jtend=tmp._IDNTptr->localvalue->end();
2961 	for (;;){
2962 	  if (jt==jtend)
2963 	    break;
2964 	  --jtend;
2965 	  --jtend;
2966 	  if (protect>jtend->val){
2967 	    ++jtend;
2968 	    ++jtend;
2969 	    break;
2970 	  }
2971 	}
2972 	tmp._IDNTptr->localvalue->erase(jtend,tmp._IDNTptr->localvalue->end());
2973       }
2974     }
2975     protection_level=protect;
2976     return true;
2977   }
2978 
printaslocal(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)2979   static string printaslocal(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
2980     if ( (feuille.type!=_VECT) || (feuille._VECTptr->size()!=2) )
2981       return string(sommetstr)+('('+feuille.print(contextptr)+')');
2982     const_iterateur it=feuille._VECTptr->begin(),itend=feuille._VECTptr->end();
2983     string res;
2984     gen local_global=*it,locals=gen2vecteur(*it),globals=vecteur(0);
2985     if (local_global.type==_VECT && local_global._VECTptr->size()==2){
2986       gen f=local_global._VECTptr->front(),b=local_global._VECTptr->back();
2987       if (f.type!=_IDNT){
2988 	locals=gen2vecteur(f);
2989 	globals=gen2vecteur(b);
2990       }
2991     }
2992     bool python=python_compat(contextptr) && !debug_ptr(contextptr)->debug_mode;
2993     if (python){
2994       int & ind=debug_ptr(contextptr)->indent_spaces;
2995       if (!locals._VECTptr->empty())
2996 	res += string(ind,' ')+"# local "+printaslocalvars(locals,contextptr)+"\n";
2997       if (!globals._VECTptr->empty())
2998 	res += string(ind,' ')+"global "+printaslocalvars(globals,contextptr)+"\n";
2999       ++it;
3000       if (it->is_symb_of_sommet(at_bloc)){
3001 	if (res.size() && res[res.size()-1]=='\n') res=res.substr(0,res.size()-1);
3002 	res += it->print(contextptr)+'\n';
3003       }
3004       else {
3005 	if (it->type==_VECT){
3006 	  const_iterateur jt=it->_VECTptr->begin(),jtend=it->_VECTptr->end();
3007 	  for (;jt!=jtend;++jt)
3008 	    res += string(ind,' ')+jt->print(contextptr)+'\n';
3009 	}
3010 	else
3011 	  res += string(ind,' ')+it->print(contextptr)+'\n';
3012       }
3013       return res;
3014     }
3015     if (!locals._VECTptr->empty()){
3016       res += indent(contextptr);
3017       if (abs_calc_mode(contextptr)==38)
3018 	res += "LOCAL ";
3019       else {
3020 	if (xcas_mode(contextptr)>0){
3021 	  if (xcas_mode(contextptr)==3)
3022 	    res += "Local ";
3023 	  else
3024 	    res += "local ";
3025 	}
3026 	else
3027 	  res += "{ local ";
3028       }
3029       res += printaslocalvars(locals,contextptr);
3030       if (xcas_mode(contextptr)!=3)
3031 	res +=';';
3032     }
3033     if (!globals._VECTptr->empty()){
3034       res += indent(contextptr);
3035       if (abs_calc_mode(contextptr)==38)
3036 	res += "GLOBAL ";
3037       else {
3038 	if (xcas_mode(contextptr)>0){
3039 	  if (xcas_mode(contextptr)==3)
3040 	    res += "Global ";
3041 	  else
3042 	    res += "global ";
3043 	}
3044 	else
3045 	  res += " global ";
3046       }
3047       res += printaslocalvars(globals,contextptr);
3048       if (xcas_mode(contextptr)!=3)
3049 	res +=';';
3050     }
3051     if (abs_calc_mode(contextptr)==38)
3052       res += indent(contextptr)+"BEGIN ";
3053     else {
3054       if (xcas_mode(contextptr)>0 && xcas_mode(contextptr)!=3)
3055 	res += indent(contextptr)+"begin ";
3056     }
3057     debug_ptr(contextptr)->indent_spaces +=2;
3058     ++it;
3059     for ( ;;){
3060       gen tmp=*it;
3061       if (tmp.is_symb_of_sommet(at_bloc))
3062 	tmp=tmp._SYMBptr->feuille;
3063       if (tmp.type!=_VECT)
3064 	res += indent(contextptr)+tmp.print(contextptr);
3065       else {
3066 	const_iterateur jt=tmp._VECTptr->begin(),jtend=tmp._VECTptr->end();
3067 	for (;jt!=jtend;++jt){
3068 	  res += indent(contextptr)+jt->print(contextptr);
3069 	  if (xcas_mode(contextptr)!=3)
3070 	    res += "; " ;
3071 	}
3072       }
3073       ++it;
3074       if (it==itend){
3075 	debug_ptr(contextptr)->indent_spaces -= 2;
3076 	if (abs_calc_mode(contextptr)==38)
3077 	  res += indent(contextptr)+"END;";
3078 	else {
3079 	  switch (xcas_mode(contextptr)){
3080 	  case 0:
3081 	    if (!locals._VECTptr->empty()) res += indent(contextptr)+"}";
3082 	    break;
3083 	  case 1: case 1+_DECALAGE:
3084 	    res+=indent(contextptr)+"end;";
3085 	    break;
3086 	  case 2:
3087 	    return res+=indent(contextptr)+"end_proc;";
3088 	  }
3089 	}
3090 	return res;
3091       }
3092       else
3093 	if (xcas_mode(contextptr)!=3)
3094 	  res +="; ";
3095     }
3096   }
symb_local(const gen & a,const gen & b,GIAC_CONTEXT)3097   gen symb_local(const gen & a,const gen & b,GIAC_CONTEXT){
3098     gen newa,newb;
3099     replace_keywords(a,b,newa,newb,contextptr);
3100     return symbolic(at_local,gen(makevecteur(newa,newb),_SEQ__VECT));
3101   }
symb_local(const gen & args,GIAC_CONTEXT)3102   gen symb_local(const gen & args,GIAC_CONTEXT){
3103     if (args.type==_VECT && args._VECTptr->size()==2)
3104       return symb_local(args._VECTptr->front(),args._VECTptr->back(),contextptr);
3105     return symbolic(at_local,args);
3106   }
3107 
_local(const gen & args,const context * contextptr)3108   gen _local(const gen & args,const context * contextptr) {
3109     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3110     if (args.type!=_VECT)
3111       return symb_local(args,contextptr);
3112     int s=int(args._VECTptr->size());
3113     if (s!=2)
3114       return gensizeerr(gettext("Local must have 2 args"));
3115     // Initialization
3116     gen vars=args._VECTptr->front();
3117     if (vars.type==_VECT && vars._VECTptr->size()==2 && vars._VECTptr->front().type!=_IDNT)
3118       vars = vars._VECTptr->front();
3119     if (vars.type!=_VECT)
3120       vars=makevecteur(vars);
3121     vecteur names,values;
3122     iterateur it=vars._VECTptr->begin(),itend=vars._VECTptr->end();
3123     names.reserve(itend-it);
3124     values.reserve(itend-it);
3125     for (;it!=itend;++it){
3126       if (it->type==_IDNT){
3127 	names.push_back(*it);
3128 #if 1
3129 	gen err=string2gen(gettext("Unitialized local variable ")+it->print(contextptr),false);
3130 	err.subtype=-1;
3131 	values.push_back(err);
3132 #else
3133 	values.push_back(0);
3134 #endif
3135 	continue;
3136       }
3137       if ( (it->type!=_SYMB) || (it->_SYMBptr->sommet!=at_sto && it->_SYMBptr->sommet!=at_equal))
3138 	return gentypeerr(contextptr);
3139       gen nom=it->_SYMBptr->feuille._VECTptr->back();
3140       gen val=it->_SYMBptr->feuille._VECTptr->front();
3141       if (it->_SYMBptr->sommet==at_equal)
3142 	swapgen(nom,val);
3143       val=val.eval(eval_level(contextptr),contextptr);
3144       if (nom.type!=_IDNT)
3145 	return gentypeerr(contextptr);
3146       names.push_back(nom);
3147       values.push_back(val);
3148     }
3149     context * newcontextptr = (context *) contextptr;
3150     int protect=giac_bind(values,names,newcontextptr);
3151     gen prog=args._VECTptr->back(),res,newres;
3152     if (protect!=-RAND_MAX){
3153       if (prog.type!=_VECT){
3154 	prog=equaltosto(prog,contextptr);
3155 	++debug_ptr(newcontextptr)->current_instruction;
3156 	if (debug_ptr(newcontextptr)->debug_mode){
3157 	  debug_loop(res,newcontextptr);
3158 	  if (!is_undef(res)){
3159 	    if (!prog.in_eval(eval_level(newcontextptr),res,newcontextptr))
3160 	      res=prog;
3161 	  }
3162 	}
3163 	else {
3164 	  if (!prog.in_eval(eval_level(newcontextptr),res,newcontextptr))
3165 	    res=prog;
3166 	}
3167       }
3168       else {
3169 	it=prog._VECTptr->begin(),itend=prog._VECTptr->end();
3170 	bool findlabel=false;
3171 	gen label;
3172 	for (;!ctrl_c && !interrupted && it!=itend;++it){
3173 #ifdef TIMEOUT
3174 	  control_c();
3175 #endif
3176 	  ++debug_ptr(newcontextptr)->current_instruction;
3177 	  // cout << *it << '\n';
3178 	  if (debug_ptr(newcontextptr)->debug_mode){
3179 	    debug_loop(res,newcontextptr);
3180 	    if (!is_undef(res)){
3181 	      if (!findlabel){
3182 		if (!equaltosto(*it,contextptr).in_eval(eval_level(newcontextptr),res,newcontextptr))
3183 		  res=*it;
3184 	      }
3185 	      else
3186 		res=*it;
3187 	    }
3188 	  }
3189 	  else {
3190 	    if (!findlabel){
3191 	      if (!equaltosto(*it,contextptr).in_eval(eval_level(newcontextptr),res,newcontextptr))
3192 		res=*it;
3193 	    }
3194 	    else
3195 	      res=*it;
3196 	  }
3197 	  if (res.type==_SYMB){
3198 	    unary_function_ptr & u=res._SYMBptr->sommet;
3199 	    if (findlabel && u==at_label && label==res._SYMBptr->feuille)
3200 	      findlabel=false;
3201 	    if (!findlabel && u==at_goto){
3202 	      findlabel=true;
3203 	      label=res._SYMBptr->feuille;
3204 	    }
3205 	  }
3206 	  if (findlabel && it+1==itend)
3207 	    it=prog._VECTptr->begin()-1;
3208 	  if (!findlabel && is_return(res,newres) ){
3209 	    // res=newres;
3210 	    break;
3211 	  }
3212 	}
3213       }
3214       leave(protect,names,newcontextptr);
3215     }
3216     else
3217       return gensizeerr(contextptr);
3218     return res;
3219   }
3220 
3221   static const char _local_s []="local";
3222   static define_unary_function_eval2_index (85,__local,&_local,_local_s,&printaslocal);
3223   define_unary_function_ptr5( at_local ,alias_at_local,&__local,_QUOTE_ARGUMENTS,0);
3224 
printasreturn(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)3225   static string printasreturn(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
3226     if ( abs_calc_mode(contextptr)==38 || (xcas_mode(contextptr)==1) || (xcas_mode(contextptr)==1+_DECALAGE) )
3227       return "RETURN("+feuille.print(contextptr)+")";
3228     if (xcas_mode(contextptr)==3)
3229       return "Return "+feuille.print(contextptr);
3230     return sommetstr+("("+feuille.print(contextptr)+")");
3231   }
symb_return(const gen & args,GIAC_CONTEXT)3232   static gen symb_return(const gen & args,GIAC_CONTEXT){
3233     return symbolic(at_return,args);
3234   }
3235   static const char _return_s []="return";
3236   static define_unary_function_eval2_index (86,__return,&symb_return,_return_s,&printasreturn);
3237   define_unary_function_ptr( at_return ,alias_at_return ,&__return);
3238 
printastry_catch(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)3239   static string printastry_catch(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
3240     if ( (feuille.type!=_VECT) || (feuille._VECTptr->size()<3) )
3241       return string(sommetstr)+('('+feuille.print(contextptr)+')');
3242     const_iterateur it=feuille._VECTptr->begin();//,itend=feuille._VECTptr->end();
3243     string res;
3244     if (feuille._VECTptr->size()==4){
3245       res = "IFERR ";
3246       res += printasinnerbloc(*it,contextptr);
3247       ++it;
3248       ++it;
3249       res += " THEN ";
3250       res += printasinnerbloc(*it,contextptr);
3251       ++it;
3252       res += " ELSE ";
3253       res += printasinnerbloc(*it,contextptr);
3254       res += " END";
3255       return res;
3256     }
3257     if (xcas_mode(contextptr)==3)
3258       res += "Try";
3259     else
3260       res += "try ";
3261     res += it->print(contextptr);
3262     ++it;
3263     if (xcas_mode(contextptr)==3){
3264       res += indent(contextptr)+"Else";
3265       ++it;
3266       if (!is_undef(*it))
3267 	res += printasinnerbloc(*it,contextptr);
3268       res += indent(contextptr)+"EndTry";
3269     }
3270     else {
3271       if (res[res.size()-1]!='}')
3272 	res += "; ";
3273       res += "catch(" + it->print(contextptr) + ")";
3274       ++it;
3275       res += it->print(contextptr);
3276       if (res[res.size()-1]!='}')
3277 	res += "; ";
3278     }
3279     return res;
3280   }
3281 
symb_try_catch(const gen & args)3282   gen symb_try_catch(const gen & args){
3283     return symbolic(at_try_catch,args);
3284   }
_try_catch(const gen & args,const context * contextptr)3285   gen _try_catch(const gen & args,const context * contextptr){
3286     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3287     if (args.type!=_VECT)
3288       return symb_try_catch(args);
3289     int args_size=int(args._VECTptr->size());
3290     if (args_size!=3 && args_size!=4)
3291       return gensizeerr(gettext("Try_catch must have 3 or 4 args"));
3292     gen res;
3293     int saveprotect=protection_level;
3294     vector< vector<int> > save_sst_at_stack(debug_ptr(contextptr)->sst_at_stack);
3295     vecteur save_args_stack(debug_ptr(contextptr)->args_stack);
3296     vector<int> save_current_instruction_stack=debug_ptr(contextptr)->current_instruction_stack;
3297     int save_current_instruction=debug_ptr(contextptr)->current_instruction;
3298     bool do_else_try=args_size==4;
3299 #ifndef NO_STDEXCEPT
3300     try {
3301       ++debug_ptr(contextptr)->current_instruction;
3302       if (debug_ptr(contextptr)->debug_mode)
3303 	debug_loop(res,contextptr);
3304       res=args._VECTptr->front().eval(eval_level(contextptr),contextptr);
3305     }
3306     catch (std::runtime_error & error ){
3307       last_evaled_argptr(contextptr)=NULL;
3308       ++debug_ptr(contextptr)->current_instruction;
3309       if (debug_ptr(contextptr)->debug_mode)
3310 	debug_loop(res,contextptr);
3311       // ??? res=args._VECTptr->front().eval(eval_level(contextptr),contextptr);
3312       do_else_try=false;
3313       if (!contextptr)
3314 	protection_level=saveprotect;
3315       debug_ptr(contextptr)->sst_at_stack=save_sst_at_stack;
3316       debug_ptr(contextptr)->args_stack=save_args_stack;
3317       debug_ptr(contextptr)->current_instruction_stack=save_current_instruction_stack;
3318       gen id=(*(args._VECTptr))[1];
3319       string er(error.what());
3320       er = '"'+er+'"'; // FIXME? string2gen(er,false) instead?
3321       gen tmpsto;
3322       if (id.type==_IDNT)
3323 	tmpsto=sto(gen(er,contextptr),id,contextptr);
3324       if (is_undef(tmpsto)) return tmpsto;
3325       debug_ptr(contextptr)->current_instruction=save_current_instruction;
3326       increment_instruction(args._VECTptr->front(),contextptr);
3327       ++debug_ptr(contextptr)->current_instruction;
3328       if (debug_ptr(contextptr)->debug_mode)
3329 	debug_loop(res,contextptr);
3330       res=(*args._VECTptr)[2].eval(eval_level(contextptr),contextptr);
3331     }
3332 #else
3333     ++debug_ptr(contextptr)->current_instruction;
3334     if (debug_ptr(contextptr)->debug_mode)
3335       debug_loop(res,contextptr);
3336     if (is_undef(res)) return res;
3337     res=args._VECTptr->front().eval(eval_level(contextptr),contextptr);
3338     if (is_undef(res)){
3339       do_else_try=false;
3340       if (!contextptr)
3341 	protection_level=saveprotect;
3342       debug_ptr(contextptr)->sst_at_stack=save_sst_at_stack;
3343       debug_ptr(contextptr)->args_stack=save_args_stack;
3344       debug_ptr(contextptr)->current_instruction_stack=save_current_instruction_stack;
3345       gen id=(*(args._VECTptr))[1];
3346       string er(gen2string(res));
3347       er = '"'+er+'"';
3348       gen tmpsto;
3349       if (id.type==_IDNT)
3350 	tmpsto=sto(gen(er,contextptr),id,contextptr);
3351       if (is_undef(tmpsto)) return tmpsto;
3352       debug_ptr(contextptr)->current_instruction=save_current_instruction;
3353       increment_instruction(args._VECTptr->front(),contextptr);
3354       ++debug_ptr(contextptr)->current_instruction;
3355       if (debug_ptr(contextptr)->debug_mode){
3356 	debug_loop(res,contextptr);
3357 	if (is_undef(res)) return res;
3358       }
3359       res=(*args._VECTptr)[2].eval(eval_level(contextptr),contextptr);
3360     }
3361 #endif
3362     if (do_else_try){
3363       if ((res.type==_SYMB && res._SYMBptr->sommet==at_return) || (res.type==_FUNC && (res==at_return || res==at_break || res==at_continue)))
3364 	;
3365       else
3366 	res=args._VECTptr->back().eval(eval_level(contextptr),contextptr);
3367     }
3368     debug_ptr(contextptr)->current_instruction=save_current_instruction;
3369     increment_instruction(args._VECTptr->front(),contextptr);
3370     increment_instruction(args._VECTptr->back(),contextptr);
3371     return res;
3372   }
3373   static const char _try_catch_s []="try_catch";
3374   static define_unary_function_eval2_index (177,__try_catch,&_try_catch,_try_catch_s,&printastry_catch);
3375   define_unary_function_ptr5( at_try_catch ,alias_at_try_catch,&__try_catch,_QUOTE_ARGUMENTS,0);
3376 
feuille_(const gen & g,const gen & interval,GIAC_CONTEXT)3377   static gen feuille_(const gen & g,const gen & interval,GIAC_CONTEXT){
3378     vecteur v;
3379     if (g.type==_SYMB){
3380       gen & f=g._SYMBptr->feuille;
3381       if (f.type==_VECT)
3382 	v=*f._VECTptr;
3383       else
3384 	v=vecteur(1,f);
3385     }
3386     else {
3387       if (g.type==_VECT)
3388 	v=*g._VECTptr;
3389       else
3390 	v=vecteur(1,g);
3391     }
3392     int s=int(v.size());
3393     if (interval.type==_INT_){
3394       int i=interval.val-array_start(contextptr); //-(xcas_mode(contextptr)!=0);
3395       if (i==-1 && g.type==_SYMB)
3396 	return g._SYMBptr->sommet;
3397       if (i<0 || i>=s)
3398 	return gendimerr(contextptr);
3399       return v[i];
3400     }
3401     if (interval.is_symb_of_sommet(at_interval)&& interval._SYMBptr->feuille.type==_VECT){
3402       vecteur & w=*interval._SYMBptr->feuille._VECTptr;
3403       if (w.size()!=2 || w.front().type!=_INT_ || w.back().type!=_INT_)
3404 	return gentypeerr(contextptr);
3405       int i=w.front().val,j=w.back().val;
3406       if (i>j)
3407 	return gen(vecteur(0),_SEQ__VECT);
3408       if (array_start(contextptr)){
3409 	--i;
3410 	--j;
3411       }
3412       if (i<0 || i>=s || j<0 || j>=s)
3413 	return gendimerr(contextptr);
3414       return gen(vecteur(v.begin()+i,v.begin()+j+1),_SEQ__VECT);
3415     }
3416     return gensizeerr(contextptr);
3417   }
_feuille(const gen & args,GIAC_CONTEXT)3418   gen _feuille(const gen & args,GIAC_CONTEXT){
3419     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3420     if (args.type==_VECT){
3421       if (args.subtype==_SEQ__VECT && args._VECTptr->size()==2)
3422 	return feuille_(args._VECTptr->front(),args._VECTptr->back(),contextptr);
3423       return gen(*args._VECTptr,_SEQ__VECT);
3424     }
3425     if (args.type!=_SYMB)
3426       return args;
3427     gen tmp=args._SYMBptr->feuille;
3428     if (tmp.type==_VECT)
3429       tmp.subtype=_SEQ__VECT;
3430     return tmp;
3431   }
3432   static const char _feuille_s []="op";
3433   static define_unary_function_eval2 (__feuille,&_feuille,_feuille_s,&printassubs);
3434   define_unary_function_ptr5( at_feuille ,alias_at_feuille,&__feuille,0,true);
3435 
_maple_op(const gen & args,GIAC_CONTEXT)3436   gen _maple_op(const gen & args,GIAC_CONTEXT){
3437     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3438     if (args.type==_VECT){
3439       vecteur & v=*args._VECTptr;
3440       if (args.subtype==_SEQ__VECT && v.size()>1)
3441 	return feuille_(v.back(),v.front(),contextptr);
3442       return gen(v,_SEQ__VECT);
3443     }
3444     if (args.type!=_SYMB)
3445       return args; // was symbolic(at_maple_op,args);
3446     return args._SYMBptr->feuille;
3447   }
3448   static const char _maple_op_s []="op";
3449   static define_unary_function_eval2 (__maple_op,&_maple_op,_maple_op_s,&printasmaple_subs);
3450   define_unary_function_ptr( at_maple_op ,alias_at_maple_op ,&__maple_op);
3451 
_sommet(const gen & args,GIAC_CONTEXT)3452   gen _sommet(const gen & args,GIAC_CONTEXT){
3453     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3454     if (args.type!=_SYMB)
3455       return at_id;
3456     int nargs;
3457     if (args._SYMBptr->feuille.type==_VECT)
3458         nargs=int(args._SYMBptr->feuille._VECTptr->size());
3459     else
3460         nargs=1;
3461     return gen(args._SYMBptr->sommet,nargs);
3462   }
3463   static const char _sommet_s []="sommet";
3464   static define_unary_function_eval (__sommet,&_sommet,_sommet_s);
3465   define_unary_function_ptr5( at_sommet ,alias_at_sommet,&__sommet,0,true);
3466 
3467   // replace in g using equalities in v
subsop(const vecteur & g,const vecteur & v,const gen & sommet,GIAC_CONTEXT)3468   gen subsop(const vecteur & g,const vecteur & v,const gen & sommet,GIAC_CONTEXT){
3469     if (v.size()==2 && !v[0].is_symb_of_sommet(at_equal))
3470       return subsop(g,vecteur(1,symb_equal(v[0],v[1])),sommet,contextptr);
3471     gen newsommet=sommet;
3472     vecteur res(g);
3473     const_iterateur it=v.begin(),itend=v.end();
3474     for (;it!=itend;++it){
3475       if ( (!is_equal(*it) && !it->is_symb_of_sommet(at_same)) || it->_SYMBptr->feuille.type!=_VECT || it->_SYMBptr->feuille._VECTptr->size()!=2){
3476 	*logptr(contextptr) << gettext("Unknown subsop rule ") << *it << '\n';
3477 	continue;
3478       }
3479       vecteur w=*it->_SYMBptr->feuille._VECTptr;
3480       if (w.front().type==_VECT){
3481 	vecteur rec=*w.front()._VECTptr;
3482 	if (rec.size()<1)
3483 	  return gendimerr(contextptr);
3484 	if (rec.size()==1)
3485 	  w.front()=rec.front();
3486 	else {
3487 	  int i=rec.front().val;
3488 	  if (i>=0 && array_start(contextptr))
3489 	    --i;
3490 	  if (i<0)
3491 	    i += int(res.size());
3492 	  if (rec.front().type!=_INT_ || i<0 || i>=signed(res.size()))
3493 	    return gendimerr(contextptr);
3494 	  if (is_undef( (res[i]=subsop(res[i],vecteur(1,symbolic(at_equal,gen(makevecteur(vecteur(rec.begin()+1,rec.end()),w.back()),_SEQ__VECT))),contextptr)) ) )
3495 	    return res[i];
3496 	  continue;
3497 	}
3498       }
3499       if (w.front().type!=_INT_)
3500 	continue;
3501       int i=w.front().val;
3502       if (i>=0 && array_start(contextptr))
3503 	--i;
3504       /*
3505       if (i==-1){
3506 	newsommet=w.back();
3507 	continue;
3508       }
3509       */
3510       if (i<0)
3511 	i += int(res.size());
3512       if (i<0 || i>=signed(res.size()))
3513 	return gendimerr(contextptr);
3514       res[i]=w.back();
3515     }
3516     it=res.begin();
3517     itend=res.end();
3518     vecteur res1;
3519     res1.reserve(itend-it);
3520     for (;it!=itend;++it){
3521       if (it->type!=_VECT || it->subtype!=_SEQ__VECT || !it->_VECTptr->empty() )
3522 	res1.push_back(*it);
3523     }
3524     if (newsommet.type!=_FUNC)
3525       return res1;
3526     else
3527       return symbolic(*newsommet._FUNCptr,res1);
3528   }
subsop(const gen & g,const vecteur & v,GIAC_CONTEXT)3529   gen subsop(const gen & g,const vecteur & v,GIAC_CONTEXT){
3530     if (g.type==_VECT)
3531       return subsop(*g._VECTptr,v,0,contextptr);
3532     if (g.type!=_SYMB)
3533       return g;
3534     vecteur w(gen2vecteur(g._SYMBptr->feuille));
3535     return subsop(w,v,g._SYMBptr->sommet,contextptr);
3536   }
_maple_subsop(const gen & args,GIAC_CONTEXT)3537   gen _maple_subsop(const gen & args,GIAC_CONTEXT){
3538     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3539     if (args.type!=_VECT)
3540       return gensizeerr(contextptr);
3541     vecteur & v=*args._VECTptr;
3542     int s=int(v.size());
3543     if (s<2)
3544       return gendimerr(contextptr);
3545     return subsop(v.back(),vecteur(v.begin(),v.end()-1),contextptr);
3546   }
3547   static const char _maple_subsop_s []="subsop";
3548   static define_unary_function_eval2 (__maple_subsop,&_maple_subsop,_maple_subsop_s,&printasmaple_subs);
3549   define_unary_function_ptr( at_maple_subsop ,alias_at_maple_subsop ,&__maple_subsop);
3550 
_subsop(const gen & args,GIAC_CONTEXT)3551   gen _subsop(const gen & args,GIAC_CONTEXT){
3552     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3553     if (args.type!=_VECT)
3554       return gensizeerr(contextptr);
3555     vecteur & v=*args._VECTptr;
3556     int s=int(v.size());
3557     if (s<2)
3558       return gendimerr(contextptr);
3559     return subsop(v.front(),vecteur(v.begin()+1,v.end()),contextptr);
3560   }
3561   static const char _subsop_s []="subsop";
3562   static define_unary_function_eval2 (__subsop,&_subsop,_subsop_s,&printassubs);
3563   define_unary_function_ptr( at_subsop ,alias_at_subsop ,&__subsop);
3564 
3565   // static gen symb_append(const gen & args){  return symbolic(at_append,args);  }
_append(const gen & args,GIAC_CONTEXT)3566   gen _append(const gen & args,GIAC_CONTEXT){
3567     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3568     if ( args.type!=_VECT || !args._VECTptr->size() )
3569       return gensizeerr(contextptr);
3570     const_iterateur it=args._VECTptr->begin(),itend=args._VECTptr->end();
3571     if (itend-it==2 && it->type==_STRNG && (it+1)->type==_STRNG)
3572       return string2gen(*it->_STRNGptr+*(it+1)->_STRNGptr,false);
3573     if (it->type!=_VECT)
3574       return gensizeerr(contextptr);
3575     vecteur v(*it->_VECTptr);
3576     int subtype=it->subtype;
3577     ++it;
3578     if (v.size()+(itend-it)>LIST_SIZE_LIMIT)
3579       return gendimerr(contextptr);
3580     for (;it!=itend;++it)
3581       v.push_back(*it);
3582     return gen(v,subtype);
3583   }
3584   static const char _append_s []="append";
3585   static define_unary_function_eval (__append,&_append,_append_s);
3586   define_unary_function_ptr5( at_append ,alias_at_append,&__append,0,true);
3587 
3588   // static gen symb_prepend(const gen & args){  return symbolic(at_prepend,args); }
_prepend(const gen & args,GIAC_CONTEXT)3589   gen _prepend(const gen & args,GIAC_CONTEXT){
3590     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3591     if (args.type==_VECT && args._VECTptr->size()==2 && args._VECTptr->front().type==_STRNG && args._VECTptr->back().type==_STRNG)
3592       return args._VECTptr->back()+args._VECTptr->front();
3593     if ( (args.type!=_VECT) || (!args._VECTptr->size()) || (args._VECTptr->front().type!=_VECT) )
3594       return gensizeerr(contextptr);
3595     gen debut=args._VECTptr->front();
3596     return gen(mergevecteur(cdr_VECT(*args._VECTptr),*debut._VECTptr),debut.subtype);
3597   }
3598   static const char _prepend_s []="prepend";
3599   static define_unary_function_eval (__prepend,&_prepend,_prepend_s);
3600   define_unary_function_ptr5( at_prepend ,alias_at_prepend,&__prepend,0,true);
3601 
_contains(const gen & args,GIAC_CONTEXT)3602   gen _contains(const gen & args,GIAC_CONTEXT){
3603     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3604     if ( (args.type!=_VECT) || (args._VECTptr->size()!=2))
3605       return gensizeerr(contextptr);
3606     gen a=args._VECTptr->front(),b=args._VECTptr->back();
3607     if (a.type==_STRNG && b.type==_STRNG){
3608       int pos=a._STRNGptr->find(*b._STRNGptr);
3609       if (pos<0 || pos>=a._STRNGptr->size())
3610 	return 0;
3611       else
3612 	return pos+1;
3613     }
3614     if (a.type!=_VECT){
3615       if (a.type==_REAL)
3616 	return contains(a,b);
3617       if (b==cst_i)
3618 	return has_i(a);
3619       return gensizeerr(contextptr);
3620     }
3621     return equalposcomp(*a._VECTptr,b);
3622   }
3623   static const char _contains_s []="contains";
3624   static define_unary_function_eval (__contains,&_contains,_contains_s);
3625   define_unary_function_ptr5( at_contains ,alias_at_contains,&__contains,0,true);
3626 
3627   // check if a set A is included in a set B
_is_included(const gen & args,GIAC_CONTEXT)3628   gen _is_included(const gen & args,GIAC_CONTEXT){
3629     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3630     if ( (args.type!=_VECT) || (args._VECTptr->size()!=2) || (args._VECTptr->front().type!=_VECT) || (args._VECTptr->back().type!=_VECT) )
3631       return gensizeerr(contextptr);
3632     vecteur a(*args._VECTptr->front()._VECTptr);
3633     vecteur b(*args._VECTptr->back()._VECTptr);
3634     islesscomplexthanf_sort(b.begin(),b.end());
3635     for (unsigned i=0;i<a.size();++i){
3636       if (!binary_search(b.begin(),b.end(),a[i],islesscomplexthanf))
3637 	return 0;
3638     }
3639     return 1;
3640   }
3641   static const char _is_included_s []="is_included";
3642   static define_unary_function_eval (__is_included,&_is_included,_is_included_s);
3643   define_unary_function_ptr5( at_is_included ,alias_at_is_included,&__is_included,0,true);
3644 
symb_select(const gen & args)3645   static gen symb_select(const gen & args){
3646     return symbolic(at_select,args);
3647   }
symb_remove(const gen & args)3648   static gen symb_remove(const gen & args){
3649     return symbolic(at_remove,args);
3650   }
select_remove(const gen & args,bool selecting,const context * contextptr)3651   static gen select_remove(const gen & args,bool selecting,const context * contextptr){
3652     if ( (args.type!=_VECT) || (args._VECTptr->size()<2)){
3653       if (selecting)
3654 	return symb_select(args);
3655       else
3656 	return symb_remove(args);
3657     }
3658     gen v((*(args._VECTptr))[1]);
3659     int subtype;
3660     gen fn=0;
3661     if (v.type==_SYMB){
3662       if (v._SYMBptr->feuille.type==_VECT)
3663 	v=v._SYMBptr->feuille;
3664       else
3665 	v=makevecteur(v._SYMBptr->feuille);
3666       subtype=-1;
3667       fn=v;
3668     }
3669     else
3670       subtype=v.subtype;
3671     gen f(args._VECTptr->front());
3672     if ( (v.type!=_VECT) && (v.type!=_SYMB)){
3673       if (selecting)
3674 	return symb_select(args);
3675       else {
3676 	if (f.type==_VECT){ // remove 1st occurence of v
3677 	  vecteur w=*f._VECTptr;
3678 	  for (unsigned i=0;i<w.size();++i){
3679 	    if (w[i]==v){
3680 	      w.erase(w.begin()+i);
3681 	      return gen(w,f.subtype);
3682 	    }
3683 	  }
3684 	  return gensizeerr(contextptr);
3685 	}
3686 	return symb_remove(args);
3687       }
3688     }
3689     bool prog=f.is_symb_of_sommet(at_program);
3690     vecteur otherargs(args._VECTptr->begin()+1,args._VECTptr->end());
3691     const_iterateur it=v._VECTptr->begin(),itend=v._VECTptr->end();
3692     vecteur res;
3693     res.reserve(itend-it);
3694     if (otherargs.size()==1){
3695       for (;it!=itend;++it){
3696 	if (prog){
3697 	  if (is_zero(f(*it,contextptr))!=selecting)
3698 	    res.push_back(*it);
3699 	}
3700 	else {
3701 	  if ((*it==f)==selecting )
3702 	    res.push_back(*it);
3703 	}
3704       }
3705     }
3706     else {
3707       for (;it!=itend;++it){
3708 	otherargs.front()=*it;
3709 	if (is_zero(f(otherargs,contextptr))!=selecting)
3710 	  res.push_back(*it);
3711       }
3712     }
3713     if (subtype<0 && fn.type==_SYMB)
3714       return symbolic(fn._SYMBptr->sommet,res);
3715     else
3716       return gen(res,subtype);
3717   }
_select(const gen & args,const context * contextptr)3718   gen _select(const gen & args,const context * contextptr){
3719     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3720     return select_remove(args,1,contextptr);
3721   }
3722   static const char _select_s []="select";
3723   static define_unary_function_eval (__select,&_select,_select_s);
3724   define_unary_function_ptr5( at_select ,alias_at_select,&__select,0,true);
3725 
3726   static const char _filter_s []="filter";
3727   static define_unary_function_eval (__filter,&_select,_filter_s);
3728   define_unary_function_ptr5( at_filter ,alias_at_filter,&__filter,0,true);
3729 
_remove(const gen & args,const context * contextptr)3730   gen _remove(const gen & args,const context * contextptr){
3731     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3732     return select_remove(args,0,contextptr);
3733   }
3734   static const char _remove_s []="remove";
3735   static define_unary_function_eval (__remove,&_remove,_remove_s);
3736   define_unary_function_ptr5( at_remove ,alias_at_remove,&__remove,0,true);
3737 
printnostring(const gen & g,GIAC_CONTEXT)3738   static string printnostring(const gen & g,GIAC_CONTEXT){
3739     if (g.type==_STRNG)
3740       return *g._STRNGptr;
3741     else
3742       return g.print(contextptr);
3743   }
symb_concat(const gen & args)3744   static gen symb_concat(const gen & args){
3745     return symbolic(at_concat,args);
3746   }
concat(const gen & g,bool glue_lines,GIAC_CONTEXT)3747   gen concat(const gen & g,bool glue_lines,GIAC_CONTEXT){
3748     if (g.type!=_VECT)
3749       return symb_concat(g);
3750     vecteur & v=*g._VECTptr;
3751     if (v.size()>2){
3752       gen h=concat(makesequence(v[0],v[1]),glue_lines,contextptr);
3753       for (unsigned i=2;i<v.size();++i){
3754 	h=concat(makesequence(h,v[i]),glue_lines,contextptr);
3755       }
3756       return h;
3757     }
3758     if (v.size()!=2){
3759       if (g.subtype==_SEQ__VECT)
3760 	return g;
3761       return symb_concat(g);
3762     }
3763     gen v0=v[0],v1=v[1];
3764     if (v0.type==_VECT && v1.type==_VECT){
3765       if (!glue_lines && v1.subtype!=_SEQ__VECT && ckmatrix(v0) && ckmatrix(v1) && v0._VECTptr->size()==v1._VECTptr->size() )
3766 	return gen(mtran(mergevecteur(mtran(*v0._VECTptr),mtran(*v1._VECTptr))));
3767       else
3768 	return gen(mergevecteur(*v0._VECTptr,*v1._VECTptr),v0.subtype);
3769     }
3770     if (v0.type==_VECT)
3771       return gen(mergevecteur(*v0._VECTptr,vecteur(1,v1)),v0.subtype);
3772     if (v1.type==_VECT)
3773       return gen(mergevecteur(vecteur(1,v0),*v1._VECTptr),v1.subtype);
3774     if ( (v0.type==_STRNG) || (v1.type==_STRNG) )
3775       return string2gen(printnostring(v0,contextptr) + printnostring(v1,contextptr),false);
3776     return 0;
3777   }
_concat(const gen & args,GIAC_CONTEXT)3778   gen _concat(const gen & args,GIAC_CONTEXT){
3779     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3780     return concat(args,false,contextptr);
3781   }
3782   static const char _concat_s []="concat";
3783   static define_unary_function_eval (__concat,&_concat,_concat_s);
3784   define_unary_function_ptr5( at_concat ,alias_at_concat,&__concat,0,true);
3785 
_extend(const gen & args,GIAC_CONTEXT)3786   gen _extend(const gen & args,GIAC_CONTEXT){
3787     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3788     if (args.type!=_VECT || args._VECTptr->size()!=2 || args._VECTptr->front().type!=_VECT || args._VECTptr->back().type!=_VECT)
3789       return gensizeerr(contextptr);
3790     return gen(mergevecteur(*args._VECTptr->front()._VECTptr,*args._VECTptr->back()._VECTptr),args._VECTptr->front().subtype);
3791   }
3792   static const char _extend_s []="extend";
3793   static define_unary_function_eval (__extend,&_extend,_extend_s);
3794   define_unary_function_ptr5( at_extend ,alias_at_extend,&__extend,0,true);
3795 
symb_option(const gen & args)3796   static gen symb_option(const gen & args){
3797     return symbolic(at_option,args);
3798   }
_option(const gen & args,GIAC_CONTEXT)3799   gen _option(const gen & args,GIAC_CONTEXT){
3800     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3801     return symb_option(args);
3802   }
3803   static const char _option_s []="option";
3804   static define_unary_function_eval (__option,&_option,_option_s);
3805   define_unary_function_ptr( at_option ,alias_at_option ,&__option);
3806 
printascase(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)3807   static string printascase(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
3808     if ( (feuille.type!=_VECT) || (feuille._VECTptr->size()!=2) || (feuille._VECTptr->back().type!=_VECT))
3809       return string(sommetstr)+('('+feuille.print(contextptr)+')');
3810     string res("switch (");
3811     res += feuille._VECTptr->front().print(contextptr);
3812     res += "){";
3813     debug_ptr(contextptr)->indent_spaces +=2;
3814     const_iterateur it=feuille._VECTptr->back()._VECTptr->begin(),itend=feuille._VECTptr->back()._VECTptr->end();
3815     for (;it!=itend;++it){
3816       ++it;
3817       if (it==itend){
3818 	res += indent(contextptr)+"default:";
3819 	--it;
3820 	debug_ptr(contextptr)->indent_spaces += 2;
3821 	res += indent(contextptr)+it->print(contextptr);
3822 	debug_ptr(contextptr)->indent_spaces -= 2;
3823 	break;
3824       }
3825       res += indent(contextptr)+"case "+(it-1)->print(contextptr)+":";
3826       debug_ptr(contextptr)->indent_spaces += 2;
3827       res += indent(contextptr)+it->print(contextptr);
3828       debug_ptr(contextptr)->indent_spaces -=2;
3829     }
3830     debug_ptr(contextptr)->indent_spaces -=2;
3831     res+=indent(contextptr)+"}";
3832     return res;
3833   }
symb_case(const gen & args)3834   gen symb_case(const gen & args){
3835     return symbolic(at_case,args);
3836   }
symb_case(const gen & a,const gen & b)3837   gen symb_case(const gen & a,const gen & b){
3838     return symbolic(at_case,gen(makevecteur(a,b),_SEQ__VECT));
3839   }
_case(const gen & args,GIAC_CONTEXT)3840   gen _case(const gen & args,GIAC_CONTEXT){ // FIXME DEBUGGER
3841     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
3842     if ( (args.type!=_VECT) || (args._VECTptr->size()!=2) || (args._VECTptr->back().type!=_VECT) )
3843       return symb_case(args);
3844     gen expr=args._VECTptr->front().eval(eval_level(contextptr),contextptr),res=undef,oldres,newres;
3845     const_iterateur it=args._VECTptr->back()._VECTptr->begin(),itend=args._VECTptr->back()._VECTptr->end();
3846     for (;it!=itend;){
3847       if (it+1==itend){
3848 	res=it->eval(eval_level(contextptr),contextptr);
3849 	break;
3850       }
3851       if (expr==it->eval(eval_level(contextptr),contextptr)){
3852 	++it;
3853 	oldres=res;
3854 	res=it->eval(eval_level(contextptr),contextptr);
3855 	if (res==symbolic(at_break,zero)){
3856 	  res=oldres;
3857 	  break;
3858 	}
3859 	if (res.is_symb_of_sommet(at_return))
3860 	  break;
3861       }
3862       else
3863 	++it;
3864       if (it!=itend)
3865 	++it;
3866     }
3867     return res;
3868   }
3869   static const char _case_s []="case";
3870   static define_unary_function_eval2_index (123,__case,&_case,_case_s,&printascase);
3871   define_unary_function_ptr5( at_case ,alias_at_case,&__case,_QUOTE_ARGUMENTS,0);
3872 
symb_rand(const gen & args)3873   static gen symb_rand(const gen & args){
3874     return symbolic(at_rand,args);
3875   }
rand_integer_interval(const gen & x1,const gen & x2,GIAC_CONTEXT)3876   static gen rand_integer_interval(const gen & x1,const gen & x2,GIAC_CONTEXT){
3877     gen x2x1=x2-x1;
3878     if (!is_positive(x2x1,contextptr))
3879       return rand_integer_interval(x2,x1,contextptr);
3880     int n=x2x1.bindigits()/gen(rand_max2).bindigits()+1;
3881     gen res=zero;
3882 #ifndef USE_GMP_REPLACEMENTS
3883     if (unsigned(rand_max2)==(1u<<31)-1){
3884       mpz_t tmp;
3885       mpz_init(tmp);
3886       for (int i=0;i<n;++i){
3887 	mpz_mul_2exp(tmp,tmp,31);
3888 	mpz_add_ui(tmp,tmp,giac_rand(contextptr));
3889       }
3890       if (x2x1.type==_INT_)
3891 	mpz_mul_si(tmp,tmp,x2x1.val);
3892       else
3893 	mpz_mul(tmp,tmp,*x2x1._ZINTptr);
3894       mpz_tdiv_q_2exp(tmp,tmp,31*n);
3895       if (x1.type==_INT_){
3896 	if (x1.val>0) mpz_add_ui(tmp,tmp,x1.val); else mpz_sub_ui(tmp,tmp,-x1.val);
3897       }
3898       else
3899 	mpz_add(tmp,tmp,*x1._ZINTptr);
3900       res=tmp;
3901       mpz_clear(tmp);
3902       return res;
3903     }
3904 #endif
3905 #ifdef FXCG
3906     gen rand_max_plus_one=gen(rand_max2)+1;
3907 #else
3908     static gen rand_max_plus_one=gen(rand_max2)+1;
3909 #endif
3910     // Make n random numbers
3911     for (int i=0;i<n;++i)
3912       res=rand_max_plus_one*res+giac_rand(contextptr);
3913     // Now res is in [0,(RAND_MAX+1)^n-1]
3914     // Rescale in x1..x2
3915     return x1+_iquo(makevecteur(res*x2x1,pow(rand_max_plus_one,n)),contextptr);
3916   }
rand_interval(const vecteur & v,bool entier,GIAC_CONTEXT)3917   gen rand_interval(const vecteur & v,bool entier,GIAC_CONTEXT){
3918     gen x1=v.front(),x2=v.back();
3919     if (x1==x2)
3920       return x1;
3921     if ((entier || xcas_mode(contextptr)==1) && is_integer(x1) && is_integer(x2) )
3922       return rand_integer_interval(x1,x2,contextptr);
3923 #ifdef FXCG
3924     gen rand_max_plus_one=gen(rand_max2)+1;
3925 #else
3926     static gen rand_max_plus_one=gen(rand_max2)+1;
3927 #endif
3928 #ifdef HAVE_LIBMPFR
3929     if (x1.type==_REAL && x2.type==_REAL){
3930       int n=mpfr_get_prec(x1._REALptr->inf);
3931       int nr=int(n*std::log(2.0)/std::log(rand_max2+1.0));
3932       gen xr=0;
3933       for (int i=0;i<=nr;++i){
3934 	xr=xr*rand_max_plus_one+giac_rand(contextptr);
3935       }
3936       return x1+((x2-x1)*xr)/pow(rand_max_plus_one,nr+1);
3937     }
3938 #endif
3939     gen x=evalf_double(x1,1,contextptr),y=evalf_double(x2,1,contextptr);
3940     if ( (x.type==_DOUBLE_) && (y.type==_DOUBLE_) ){
3941       double xd=x._DOUBLE_val,yd=y._DOUBLE_val;
3942       double xr= (giac_rand(contextptr)/evalf_double(rand_max_plus_one,1,contextptr)._DOUBLE_val)*(yd-xd)+xd;
3943       return xr;
3944     }
3945     return symb_rand(gen(v,_SEQ__VECT));
3946   }
3947 
shuffle(vector<int> & temp,GIAC_CONTEXT)3948   void shuffle(vector<int> & temp,GIAC_CONTEXT){
3949     int n=int(temp.size());
3950     // source wikipedia Fisher-Yates shuffle article
3951     for (int i=0;i<n-1;++i){
3952       // j ← random integer such that i ≤ j < n
3953       // exchange a[i] and a[j]
3954       int j=int(i+(giac_rand(contextptr)/double(rand_max2))*(n-i));
3955       std::swap(temp[i],temp[j]);
3956     }
3957   }
3958 
rand_k_n(int k,int n,bool sorted,GIAC_CONTEXT)3959   vector<int> rand_k_n(int k,int n,bool sorted,GIAC_CONTEXT){
3960     if (k<=0 || n<=0 || k>n)
3961       return vector<int>(0);
3962     if (//n>=65536 &&
3963 	k*double(k)<=n/4){
3964       vector<int> t(k),ts(k);
3965       for (int essai=20;essai>=0;--essai){
3966 	int i;
3967 	for (i=0;i<k;++i)
3968 	  ts[i]=t[i]=int(giac_rand(contextptr)/double(rand_max2)*n);
3969 	sort(ts.begin(),ts.end());
3970 	for (i=1;i<k;++i){
3971 	  if (ts[i]==ts[i-1])
3972 	    break;
3973 	}
3974 	if (i==k)
3975 	  return sorted?ts:t;
3976       }
3977     }
3978     if (k>=n/3 || (sorted && k*std::log(double(k))>n) ){
3979       vector<int> t; t.reserve(k);
3980       // (algorithm suggested by O. Garet)
3981       while (n>0){
3982 	int r=int(giac_rand(contextptr)/double(rand_max2)*n);
3983 	if (r<n-k) // (n-k)/n=proba that the current n is not in the list
3984 	  --n;
3985 	else {
3986 	  --n;
3987 	  t.push_back(n);
3988 	  --k;
3989 	}
3990       }
3991       if (sorted)
3992 	reverse(t.begin(),t.end());
3993       else
3994 	shuffle(t);
3995       return t;
3996     }
3997     vector<bool> tab(n,true);
3998     vector<int> v(k);
3999     for (int j=0;j<k;++j){
4000       int r=-1;
4001       for (;;){
4002 	r=int(giac_rand(contextptr)/double(rand_max2)*n);
4003 	if (tab[r]){ tab[r]=false;  break; }
4004       }
4005       v[j]=r;
4006     }
4007     if (sorted)
4008       sort(v.begin(),v.end());
4009     return v;
4010   }
4011 
randperm(const int & n,GIAC_CONTEXT)4012   vector<int> randperm(const int & n,GIAC_CONTEXT){
4013     //renvoie une permutation au hasard de long n
4014     vector<int> temp(n);
4015     for (int k=0;k<n;k++)
4016       temp[k]=k;
4017     shuffle(temp,contextptr);
4018     return temp;
4019   }
4020 
rand_n_in_list(int n,const vecteur & v,GIAC_CONTEXT)4021   static gen rand_n_in_list(int n,const vecteur & v,GIAC_CONTEXT){
4022     n=absint(n);
4023     if (signed(v.size())<n)
4024       return gendimerr(contextptr);
4025 #if 1
4026     vector<int> w=rand_k_n(n,int(v.size()),false,contextptr);
4027     vecteur res(n);
4028     for (int i=0;i<n;++i)
4029       res[i]=v[w[i]];
4030     return res;
4031 #else
4032     // would be faster with randperm
4033     vecteur w(v);
4034     vecteur res;
4035     for (int i=0;i<n;++i){
4036       int tmp=int((double(giac_rand(contextptr))*w.size())/rand_max2);
4037       res.push_back(w[tmp]);
4038       w.erase(w.begin()+tmp);
4039     }
4040     return res;
4041 #endif
4042   }
_rand(const gen & args,GIAC_CONTEXT)4043   gen _rand(const gen & args,GIAC_CONTEXT){
4044     int argsval;
4045     if (args.type==_INT_ && (argsval=args.val)){
4046 #ifndef FXCG
4047       global * ptr; int c;
4048       if (argsval>0 && contextptr && (ptr=contextptr->globalptr) && ptr->_xcas_mode_!=3 && (c=ptr->_calc_mode_)!=-38 && c!=38) {
4049 	tinymt32_t * rs=&ptr->_rand_seed;
4050 	unsigned r;
4051 	for (;;){
4052 	  r=tinymt32_generate_uint32(rs) >> 1;
4053 	  if (!(r>>31))
4054 	    break;
4055 	}
4056 	return int(argsval*(r*inv_rand_max2_p1));
4057       }
4058 #endif
4059       if (argsval<0)
4060 	return -(xcas_mode(contextptr)==3)+int(argsval*(giac_rand(contextptr)/(rand_max2+1.0)));
4061       else
4062 	return (xcas_mode(contextptr)==3 || abs_calc_mode(contextptr)==38)+int(argsval*(giac_rand(contextptr)/(rand_max2+1.0)));
4063     }
4064     if (args.type==_STRNG &&  args.subtype==-1) return  args;
4065     if (is_zero(args) && args.type!=_VECT)
4066       return giac_rand(contextptr);
4067     if (args.type==_ZINT)
4068       return rand_integer_interval(zero,args,contextptr);
4069     if (args.type==_FRAC)
4070       return _rand(args._FRACptr->num,contextptr)/args._FRACptr->den;
4071     if (args.type==_USER)
4072       return args._USERptr->rand(contextptr);
4073     if (args.is_symb_of_sommet(at_rootof))
4074       return vranm(1,args,contextptr)[0];
4075 #ifndef USE_GMP_REPLACEMENTS
4076     if (args.is_symb_of_sommet(at_discreted))
4077       return vranm(1,args,contextptr)[0];
4078 #endif
4079     if (args.type==_VECT && args._VECTptr->front()==at_multinomial) {
4080       vecteur v=*args._VECTptr;
4081       v.insert(v.begin(),1);
4082       return _randvector(v,contextptr)._VECTptr->at(0);
4083     }
4084     int nd=is_distribution(args);
4085     if (nd==1 && args.type==_FUNC)
4086       return randNorm(contextptr);
4087     if (args.is_symb_of_sommet(at_exp))
4088       return _randexp(args._SYMBptr->feuille,contextptr);
4089     if (nd && args.type==_SYMB){
4090       vecteur v=gen2vecteur(args._SYMBptr->feuille);
4091       if (nd==1){
4092 	if (v.size()!=2)
4093 	  return gensizeerr(contextptr);
4094 	return randNorm(contextptr)*v[1]+v[0];
4095       }
4096       if (nd==2){
4097 	if (v.size()!=2 || !is_integral(v[0]) || v[0].type!=_INT_ || (v[1]=evalf_double(v[1],1,contextptr)).type!=_DOUBLE_)
4098 	  return gensizeerr(contextptr);
4099 	return randbinomial(v[0].val,v[1]._DOUBLE_val,contextptr);
4100       }
4101       double p=giac_rand(contextptr)/(rand_max2+1.0);
4102       v.push_back(p);
4103       return icdf(nd)(gen(v,_SEQ__VECT),contextptr);
4104     }
4105     if (args.type==_VECT){
4106       if (args._VECTptr->empty()){
4107 	if (xcas_mode(contextptr)==1)
4108 	  return giac_rand(contextptr);
4109 	else
4110 	  return giac_rand(contextptr)/(rand_max2+1.0);
4111       }
4112       if (args.subtype==0){
4113 	double d=giac_rand(contextptr)*double(args._VECTptr->size())/(rand_max2+1.0);
4114 	return (*args._VECTptr)[int(d)];
4115       }
4116       vecteur & v=*args._VECTptr;
4117       int s=int(v.size());
4118       if ((nd=is_distribution(v[0]))){
4119 	if (s==1)
4120 	  return _rand(v[0],contextptr);
4121 	return _rand(v[0] (gen(vecteur(v.begin()+1,v.end()),_SEQ__VECT),contextptr),contextptr);
4122       }
4123       if (s==2){
4124 	if (v[0]==at_exp)
4125 	  return _randexp(v[1],contextptr);
4126 	if (v.front().type==_INT_ && v.back().type==_VECT){ // rand(n,list) choose n in list
4127 	  return rand_n_in_list(v.front().val,*v.back()._VECTptr,contextptr);
4128 	}
4129 	if ( (v.back().type==_SYMB) && (v.back()._SYMBptr->sommet==at_interval) ){
4130 	  // arg1=loi, arg2=intervalle
4131 	}
4132 	if (v[0].type==_DOUBLE_ && v[1].type==_INT_)
4133 	  return _randvector(makesequence(v[1],symb_interval(0,1)),contextptr);
4134 	return rand_interval(v,args.subtype==0,contextptr);
4135       }
4136       if (s==3 && v[0].type==_DOUBLE_ && v[1].type==_INT_ && v[2].type==_INT_)
4137 	return _ranm(makesequence(v[1],v[2],symb_interval(0,1)),contextptr);
4138       if (s==3 && v[0].type==_INT_ && v[1].type==_INT_ && v[2].type==_INT_){
4139 	// 3 integers expected, rand(n,min,max) choose n in min..max
4140 	int n=v[0].val;
4141 	int m=v[1].val;
4142 	int M=v[2].val;
4143 	if (m>M){ int tmp=m; m=M; M=tmp; }
4144 #if 1
4145 	vector<int> v=rand_k_n(n,M-m+1,false,contextptr);
4146 	if (v.empty()) return gendimerr(contextptr);
4147 	for (int i=0;i<n;++i)
4148 	  v[i] += m;
4149 	vecteur res;
4150 	vector_int2vecteur(v,res);
4151 	return res;
4152 #else
4153 	vecteur v;
4154 	for (int i=m;i<=M;++i) v.push_back(i);
4155 	return rand_n_in_list(n,v,contextptr);
4156 #endif
4157       }
4158     }
4159     if ( (args.type==_SYMB) && (args._SYMBptr->sommet==at_interval) ){
4160       vecteur & v=*args._SYMBptr->feuille._VECTptr;
4161       return symb_program(vecteur(0),vecteur(0),symb_rand(gen(v,_SEQ__VECT)),contextptr);
4162       // return rand_interval(v);
4163     }
4164     return symb_rand(args);
4165   }
4166   static const char _rand_s []="rand";
4167   static define_unary_function_eval (__rand,&_rand,_rand_s);
4168   define_unary_function_ptr5( at_rand ,alias_at_rand,&__rand,0,true);
4169 
4170   static const char _random_s []="random";
4171   static define_unary_function_eval (__random,&_rand,_random_s);
4172   define_unary_function_ptr5( at_random ,alias_at_random,&__random,0,true);
4173 
_randint(const gen & args,GIAC_CONTEXT)4174   gen _randint(const gen & args,GIAC_CONTEXT){
4175     if (args.type==_INT_ || args.type==_ZINT)
4176       return (abs_calc_mode(contextptr)==38?0:1)+_rand(args,contextptr);
4177     if (args.type!=_VECT || args._VECTptr->size()!=2)
4178       return gensizeerr(contextptr);
4179     gen a=args._VECTptr->front(),b=args._VECTptr->back();
4180     if (!is_integral(a) || !is_integral(b))
4181       return gentypeerr(contextptr);
4182     return (abs_calc_mode(contextptr)==38?a-1:a)+_rand(b-a+1,contextptr);
4183   }
4184   static const char _randint_s []="randint";
4185   static define_unary_function_eval (__randint,&_randint,_randint_s);
4186   define_unary_function_ptr5( at_randint ,alias_at_randint,&__randint,0,true);
4187 
_randrange(const gen & args,GIAC_CONTEXT)4188   gen _randrange(const gen & args,GIAC_CONTEXT){
4189     if (args.type==_INT_)
4190       return (abs_calc_mode(contextptr)==38?-1:0)+_rand(args,contextptr);
4191     if (args.type!=_VECT || args._VECTptr->size()!=2)
4192       return gensizeerr(contextptr);
4193     gen a=args._VECTptr->front(),b=args._VECTptr->back();
4194     if (!is_integral(a) || !is_integral(b))
4195       return gentypeerr(contextptr);
4196     return (abs_calc_mode(contextptr)==38?a-1:a)+_rand(b-a,contextptr);
4197   }
4198   static const char _randrange_s []="randrange";
4199   static define_unary_function_eval (__randrange,&_randrange,_randrange_s);
4200   define_unary_function_ptr5( at_randrange ,alias_at_randrange,&__randrange,0,true);
4201 
_choice(const gen & args,GIAC_CONTEXT)4202   gen _choice(const gen & args,GIAC_CONTEXT){
4203     if (args.type!=_VECT || args.subtype==_SEQ__VECT || args._VECTptr->empty())
4204       return gensizeerr(contextptr);
4205     int n=int(args._VECTptr->size());
4206     gen g=_rand(n,contextptr)+(abs_calc_mode(contextptr)==38?-1:0);
4207     if (g.type!=_INT_ || g.val<0 || g.val>=n)
4208       return gendimerr(contextptr);
4209     return args[g.val];
4210   }
4211   static const char _choice_s []="choice";
4212   static define_unary_function_eval (__choice,&_choice,_choice_s);
4213   define_unary_function_ptr5( at_choice ,alias_at_choice,&__choice,0,true);
4214 
_shuffle(const gen & a,GIAC_CONTEXT)4215   gen _shuffle(const gen & a,GIAC_CONTEXT){
4216     gen args(a);
4217     if (is_integral(args))
4218       return _randperm(args,contextptr);
4219     if (args.type!=_VECT || args._VECTptr->empty())
4220       return gensizeerr(contextptr);
4221     vecteur v(*args._VECTptr);
4222     int n=int(v.size());
4223     vecteur w(n);
4224     vector<int> p=randperm(n,contextptr);
4225     for (int i=0;i<n;++i){
4226       w[i]=v[p[i]];
4227     }
4228     return gen(w,args.subtype);
4229   }
4230   static const char _shuffle_s []="shuffle";
4231   static define_unary_function_eval (__shuffle,&_shuffle,_shuffle_s);
4232   define_unary_function_ptr5( at_shuffle ,alias_at_shuffle,&__shuffle,0,true);
4233 
4234 #ifndef USE_GMP_REPLACEMENTS
_sample(const gen & args,GIAC_CONTEXT)4235   gen _sample(const gen & args,GIAC_CONTEXT){
4236     if (args.is_symb_of_sommet(at_discreted) || is_distribution(args)>0)
4237       return _rand(args,contextptr);
4238     if (args.type==_SYMB)
4239       return _randvector(makesequence(1,args),contextptr)._VECTptr->front();
4240     if (args.type!=_VECT || args._VECTptr->size()<2)
4241       return gensizeerr(contextptr);
4242     vecteur &argv=*args._VECTptr;
4243     gen a=argv.front(),b=argv.back();
4244     if (a==at_multinomial) {
4245       if (argv.size()==3) {
4246         vecteur v=argv;
4247         v.insert(v.begin(),1);
4248         return _randvector(v,contextptr)._VECTptr->at(0);
4249       } if (argv.size()==4 && b.is_integer()) {
4250         return _randvector(makesequence(b,at_multinomial,argv[1],argv[2]),contextptr);
4251       }
4252       return gensizeerr(contextptr);
4253     }
4254     if (args._VECTptr->size()!=2 || !is_integral(b) || b.type==_ZINT || b.val<0)
4255       return gensizeerr(contextptr);
4256     if (a.is_symb_of_sommet(at_discreted) || is_distribution(a)>0 || a.type==_SYMB)
4257       return _randvector(makesequence(b,a),contextptr);
4258     if (a.type!=_VECT)
4259       return gensizeerr(contextptr);
4260     return _rand(makesequence(b,a),contextptr);
4261   }
4262   static const char _sample_s []="sample";
4263   static define_unary_function_eval (__sample,&_sample,_sample_s);
4264   define_unary_function_ptr5( at_sample ,alias_at_sample,&__sample,0,true);
4265 #endif
4266 
_srand(const gen & args,GIAC_CONTEXT)4267   gen _srand(const gen & args,GIAC_CONTEXT){
4268     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
4269     if (args.type==_INT_){
4270       int n=args.val;
4271 #ifdef GIAC_HAS_STO_38
4272       n = (1000000000*ulonglong(n))% 2147483647;
4273 #endif
4274 #ifndef FXCG
4275       srand(n);
4276 #endif
4277       rand_seed(n,contextptr);
4278       return args;
4279     }
4280     else {
4281 #if defined RTOS_THREADX || defined BESTA_OS
4282       int t=PrimeGetNow();
4283 #else
4284 #ifdef FXCG
4285       int t=RTC_GetTicks();
4286 #else
4287       int t=int(time(NULL));
4288 #endif // FXCG
4289 #endif // RTOS/BESTA
4290       t = (1000000000*ulonglong(t))% 2147483647;
4291 #ifdef VISUALC
4292       // srand48(t);
4293 #endif
4294       rand_seed(t,contextptr);
4295 #ifndef FXCG
4296       srand(t);
4297 #endif
4298       return t;
4299     }
4300   }
4301   static const char _srand_s []="srand";
4302   static define_unary_function_eval (__srand,&_srand,_srand_s);
4303   define_unary_function_ptr5( at_srand ,alias_at_srand ,&__srand,0,T_RETURN);
4304 
symb_char(const gen & args)4305   static gen symb_char(const gen & args){
4306     return symbolic(at_char,args);
4307   }
_char(const gen & args_,GIAC_CONTEXT)4308   gen _char(const gen & args_,GIAC_CONTEXT){
4309     if ( args_.type==_STRNG &&  args_.subtype==-1) return  args_;
4310     string s;
4311     gen args(args_);
4312     if (is_integral(args)){
4313       s += char(args.val) ;
4314     }
4315     else {
4316       if (args.type==_VECT){
4317 	vecteur v=*args._VECTptr;
4318 	iterateur it=v.begin(),itend=v.end();
4319 	for (;it!=itend;++it){
4320 	  if (is_integral(*it))
4321 	    s += char(it->val);
4322 	  else return gensizeerr(contextptr);
4323 	}
4324       }
4325       else return gensizeerr(contextptr);
4326     }
4327     gen tmp=string2gen(s,false);
4328     return tmp;
4329   }
4330   static const char _char_s []="char";
4331   static define_unary_function_eval (__char,&_char,_char_s);
4332   define_unary_function_ptr5( at_char ,alias_at_char,&__char,0,true);
4333 
4334   static const char _chr_s []="chr";
4335   static define_unary_function_eval (__chr,&_char,_chr_s);
4336   define_unary_function_ptr5( at_chr ,alias_at_chr,&__chr,0,true);
4337 
symb_asc(const gen & args)4338   static gen symb_asc(const gen & args){
4339     return symbolic(at_asc,args);
4340   }
_asc(const gen & args,GIAC_CONTEXT)4341   gen _asc(const gen & args,GIAC_CONTEXT){
4342     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
4343     if (args.type==_STRNG){
4344       int l=int(args._STRNGptr->size());
4345       vecteur v(l);
4346       for (int i=0;i<l;++i)
4347 	v[i]=int( (unsigned char) ((*args._STRNGptr)[i]));
4348       if (abs_calc_mode(contextptr)==38)
4349 	return gen(v,_LIST__VECT);
4350       return v;
4351     }
4352     if (args.type==_VECT){
4353       if ( (args._VECTptr->size()!=2) ||(args._VECTptr->front().type!=_STRNG) || (args._VECTptr->back().type!=_INT_) )
4354 	return gensizeerr(gettext("asc"));
4355       return int( (unsigned char) (*args._VECTptr->front()._STRNGptr)[args._VECTptr->back().val]);
4356     }
4357     else return symb_asc(args);
4358   }
4359 
4360   static const char _asc_s []="asc";
4361   static define_unary_function_eval (__asc,&_asc,_asc_s);
4362   define_unary_function_ptr5( at_asc ,alias_at_asc,&__asc,0,true);
4363 
symb_map(const gen & args)4364   static gen symb_map(const gen & args){
4365     return symbolic(at_map,args);
4366   }
_map(const gen & args,const context * contextptr)4367   gen _map(const gen & args,const context * contextptr){
4368     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
4369     if (args.type!=_VECT)
4370       return symb_map(args);
4371     vecteur v=*args._VECTptr;
4372     int s=int(v.size());
4373     if (s<2)
4374       return gentoofewargs("");
4375     gen objet=v.front();
4376     gen to_map=v[1];
4377     // FIXME: should have maple_map and mupad_map functions
4378     if (xcas_mode(contextptr)==1 || (to_map.type!=_FUNC && !to_map.is_symb_of_sommet(at_program) && (objet.type==_FUNC || objet.is_symb_of_sommet(at_program)))){
4379       objet=v[1];
4380       to_map=v.front();
4381     }
4382     bool matrix = ckmatrix(objet) && s>2;
4383     if (matrix){
4384       matrix=false;
4385       for (int i=2;i<s;++i){
4386 	if (v[i]==at_matrix){
4387 	  v.erase(v.begin()+i);
4388 	  --s;
4389 	  matrix=true;
4390 	  break;
4391 	}
4392       }
4393     }
4394     if (to_map.type==_VECT)
4395       return gensizeerr(contextptr);
4396     if (v.size()==2){
4397       if (objet.type==_SYMB){
4398 	gen & f=objet._SYMBptr->feuille;
4399 	gen tmp;
4400 	if (xcas_mode(contextptr)==1)
4401 	  tmp=_map(makevecteur(to_map,f),contextptr);
4402 	else
4403 	  tmp=_map(makevecteur(f,to_map),contextptr);
4404 	if (f.type==_VECT && tmp.type==_VECT)
4405 	  tmp.subtype=f.subtype;
4406 	if (is_equal(objet) || objet._SYMBptr->sommet==at_same)
4407 	  return symbolic(at_equal,tmp);
4408 	return objet._SYMBptr->sommet(tmp,contextptr);
4409       }
4410       // if (to_map.type==_FUNC) return apply(objet,*to_map._FUNCptr);
4411       if (objet.type==_POLY){
4412 	int dim=objet._POLYptr->dim;
4413 	polynome res(dim);
4414 	vector< monomial<gen> >::const_iterator it=objet._POLYptr->coord.begin(),itend=objet._POLYptr->coord.end();
4415 	res.coord.reserve(itend-it);
4416 	vecteur argv(dim+1);
4417 	for (;it!=itend;++it){
4418 	  argv[0]=it->value;
4419 	  index_t::const_iterator i=it->index.begin();
4420 	  for (int j=0;j<dim;++j,++i)
4421 	    argv[j+1]=*i;
4422 	  gen g=to_map(gen(argv,_SEQ__VECT),contextptr);
4423 	  if (!is_zero(g))
4424 	    res.coord.push_back(monomial<gen>(g,it->index));
4425 	}
4426 	return res;
4427       }
4428       if (objet.type!=_VECT)
4429 	return to_map(objet,contextptr);
4430       const_iterateur it=objet._VECTptr->begin(),itend=objet._VECTptr->end();
4431       vecteur res;
4432       res.reserve(itend-it);
4433       for (;it!=itend;++it){
4434 	if (matrix && it->type==_VECT){
4435 	  const vecteur & tmp = *it->_VECTptr;
4436 	  const_iterateur jt=tmp.begin(),jtend=tmp.end();
4437 	  vecteur tmpres;
4438 	  tmpres.reserve(jtend-jt);
4439 	  for (;jt!=jtend;++jt){
4440 	    tmpres.push_back(to_map(*jt,contextptr));
4441 	  }
4442 	  res.push_back(tmpres);
4443 	}
4444 	else
4445 	  res.push_back(to_map(*it,contextptr));
4446       }
4447       return res;
4448     }
4449     if (objet.type==_POLY){
4450       int dim=objet._POLYptr->dim;
4451       vecteur opt(v.begin()+2,v.end());
4452       opt=mergevecteur(vecteur(dim+1),opt);
4453       polynome res(dim);
4454       vector< monomial<gen> >::const_iterator it=objet._POLYptr->coord.begin(),itend=objet._POLYptr->coord.end();
4455       res.coord.reserve(itend-it);
4456       for (;it!=itend;++it){
4457 	opt[0]=it->value;
4458 	index_t::const_iterator i=it->index.begin();
4459 	for (int j=0;j<dim;++j,++i)
4460 	  opt[j+1]=*i;
4461 	gen g=to_map(gen(opt,_SEQ__VECT),contextptr);
4462 	if (!is_zero(g))
4463 	  res.coord.push_back(monomial<gen>(g,it->index));
4464       }
4465       return res;
4466     }
4467     vecteur opt(v.begin()+1,v.end());
4468     opt[0]=objet;
4469     if (objet.type!=_VECT)
4470       return to_map(opt,contextptr);
4471     bool multimap=!matrix && opt.size()>1 && ckmatrix(opt);
4472     const_iterateur it=objet._VECTptr->begin(),itend=objet._VECTptr->end();
4473     vecteur res;
4474     res.reserve(itend-it);
4475     for (int k=0;it!=itend;++it,++k){
4476       if (matrix && it->type==_VECT){
4477 	const vecteur & tmp = *it->_VECTptr;
4478 	const_iterateur jt=tmp.begin(),jtend=tmp.end();
4479 	vecteur tmpres;
4480 	tmpres.reserve(jtend-jt);
4481 	for (;jt!=jtend;++jt){
4482 	  opt[0]=*jt;
4483 	  tmpres.push_back(to_map(gen(opt,_SEQ__VECT),contextptr));
4484 	}
4485 	res.push_back(tmpres);
4486       }
4487       else {
4488 	opt[0]=*it;
4489 	gen arg=gen(opt,_SEQ__VECT);
4490 	if (multimap){
4491 	  vecteur & v=*arg._VECTptr;
4492 	  for (int j=1;j<v.size();++j)
4493 	    v[j]=(*v[j]._VECTptr)[k];
4494 	}
4495 	res.push_back(to_map(arg,contextptr));
4496       }
4497     }
4498     return res;
4499   }
4500   static const char _map_s []="map";
4501   static define_unary_function_eval (__map,&_map,_map_s);
4502   define_unary_function_ptr5( at_map ,alias_at_map,&__map,0,true);
4503 
symb_apply(const gen & args)4504   static gen symb_apply(const gen & args){
4505     return symbolic(at_apply,args);
4506   }
_apply(const gen & args,const context * contextptr)4507   gen _apply(const gen & args,const context * contextptr){
4508     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
4509     if (args.type!=_VECT)
4510       return symb_apply(args);
4511     if (args._VECTptr->empty())
4512       return gensizeerr(gettext("apply"));
4513     vecteur v=*args._VECTptr;
4514     gen to_apply=v.front();
4515     int n=to_apply.subtype;
4516     int n2=int(v.size());
4517     int subt=0;
4518     if (n2>=2 && v[1].type==_VECT)
4519       subt=v[1].subtype;
4520     for (int i=2;i<n2;++i){
4521       if (v[i]==at_matrix){
4522 	swapgen(v[0],v[1]);
4523 	return _map(gen(v,args.subtype),contextptr);
4524       }
4525     }
4526     if (to_apply.type!=_FUNC)
4527       n=n2-1;
4528     int nargs=1;
4529     if (to_apply.is_symb_of_sommet(at_program) && to_apply._SYMBptr->feuille[0].type==_VECT)
4530       nargs=to_apply._SYMBptr->feuille[0]._VECTptr->size();
4531     if (n && (n2==n+1) ){
4532       vecteur res;
4533       for (int i=0;;++i){
4534 	vecteur tmp;
4535 	bool finished=true;
4536 	for (int j=1;j<=n;++j){
4537 	  gen g=v[j];
4538 	  if (g.type==_STRNG){
4539 	    vecteur w(g._STRNGptr->size());
4540 	    for (size_t i=0;i<g._STRNGptr->size();++i)
4541 	      w[i]=string2gen(g._STRNGptr->substr(i,1),false);
4542 	    g=w;
4543 	  }
4544 	  if (g.type!=_VECT)
4545 	    tmp.push_back(g);
4546 	  else {
4547 	    if (signed(g._VECTptr->size())>i){
4548 	      finished=false;
4549 	      tmp.push_back((*g._VECTptr)[i]);
4550 	    }
4551 	    else
4552 	      tmp.push_back(zero);
4553 	  }
4554 	}
4555 	if (finished)
4556 	  break;
4557 	if (n==1){
4558 	  gen tmp1=tmp.front();
4559 	  if (nargs>1 && tmp1.type==_VECT) // for apply((j,k)->j*k,matrix 2 cols)
4560 	    tmp1.subtype=_SEQ__VECT;
4561 	  res.push_back(to_apply(tmp1,contextptr));
4562 	}
4563 	else
4564 	  res.push_back(to_apply(tmp,contextptr));
4565       }
4566       return gen(res,subt);
4567     }
4568     else
4569       return gensizeerr(contextptr);
4570     return 0;
4571   }
4572   static const char _apply_s []="apply";
4573   static define_unary_function_eval (__apply,&_apply,_apply_s);
4574   define_unary_function_ptr5( at_apply ,alias_at_apply,&__apply,0,true);
4575 
4576   // static gen symb_makelist(const gen & args){  return symbolic(at_makelist,args);  }
_makelist(const gen & args,GIAC_CONTEXT)4577   gen _makelist(const gen & args,GIAC_CONTEXT){
4578     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
4579     if (args.type==_INT_){
4580       if (args.val>=0 && args.val<LIST_SIZE_LIMIT)
4581 	return vecteur(args.val);
4582       if (args.val<0 && args.val>-LIST_SIZE_LIMIT){
4583 	gen res=new_ref_vecteur(vecteur(0));
4584 	res._VECTptr->reserve(-args.val);
4585 	return res;
4586       }
4587     }
4588     if (args.type!=_VECT)
4589       return gensizeerr();
4590     vecteur v(*args._VECTptr);
4591     int s=int(v.size());
4592     if (s<2)
4593       return gensizeerr(contextptr);
4594     gen f(v[0]),debut,fin,step(1);
4595     if (v[1].is_symb_of_sommet(at_interval)){
4596       debut=v[1]._SYMBptr->feuille._VECTptr->front();
4597       fin=v[1]._SYMBptr->feuille._VECTptr->back();
4598       if (s>2)
4599 	step=v[2];
4600     }
4601     else {
4602       if (s<3)
4603 	return gensizeerr(contextptr);
4604       debut=v[1];
4605       fin=v[2];
4606       if (s>3)
4607 	step=v[3];
4608     }
4609     if (is_zero(step))
4610       return gensizeerr(gettext("Invalid null step"));
4611     if (is_greater((fin-debut)/step,LIST_SIZE_LIMIT,contextptr))
4612       return gendimerr(contextptr);
4613     vecteur w;
4614     if (is_greater(fin,debut,contextptr)){
4615       step=abs(step,contextptr);
4616       for (gen i=debut;is_greater(fin,i,contextptr);i=i+step)
4617 	w.push_back(f(i,contextptr));
4618     }
4619     else {
4620       step=-abs(step,contextptr);
4621       for (gen i=debut;is_greater(i,fin,contextptr);i=i+step)
4622 	w.push_back(f(i,contextptr));
4623     }
4624     return w;
4625   }
4626   static const char _makelist_s []="makelist";
4627   static define_unary_function_eval (__makelist,&_makelist,_makelist_s);
4628   define_unary_function_ptr5( at_makelist ,alias_at_makelist,&__makelist,0,true);
4629 
symb_interval(const gen & args)4630   static gen symb_interval(const gen & args){
4631     return symbolic(at_interval,args);
4632   }
symb_interval(const gen & a,const gen & b)4633   gen symb_interval(const gen & a,const gen & b){
4634     return symbolic(at_interval,gen(makevecteur(a,b),_SEQ__VECT));
4635   }
_interval(const gen & args,GIAC_CONTEXT)4636   gen _interval(const gen & args,GIAC_CONTEXT){
4637     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
4638     return symb_interval(args);
4639   }
4640   static const char _interval_s []=" .. ";
4641   static define_unary_function_eval4_index (56,__interval,&_interval,_interval_s,&printsommetasoperator,&texprintsommetasoperator);
4642   define_unary_function_ptr( at_interval ,alias_at_interval ,&__interval);
4643 
printascomment(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)4644   static string printascomment(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
4645     if (feuille.type!=_STRNG)
4646       return string(sommetstr)+('('+feuille.print(contextptr)+')');
4647     string chaine=*feuille._STRNGptr;
4648     int s=int(chaine.size());
4649     if ( (xcas_mode(contextptr)==1) || (xcas_mode(contextptr)==1+_DECALAGE)){
4650       string res("# ");
4651       for (int i=0;i<s;++i){
4652 	if ((i==s-1)||(chaine[i]!='\n'))
4653 	  res +=chaine[i];
4654 	else
4655 	  res += indent(contextptr)+"# ";
4656       }
4657       return res;
4658     }
4659     int l=int(chaine.find_first_of('\n'));
4660     if ((l<0)|| (l>=s))
4661         return "//"+chaine + indent(contextptr);
4662     return "/*"+chaine+"*/";
4663   }
symb_comment(const gen & args)4664   static gen symb_comment(const gen & args){
4665     return symbolic(at_comment,args);
4666   }
_comment(const gen & args,GIAC_CONTEXT)4667   gen _comment(const gen & args,GIAC_CONTEXT){
4668     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
4669     return symb_comment(args);
4670   }
4671   static const char _comment_s []="comment";
4672   static define_unary_function_eval2 (__comment,&_comment,_comment_s,&printascomment);
4673   define_unary_function_ptr5( at_comment ,alias_at_comment ,&__comment,0,true);
4674 
4675   // static gen symb_throw(const gen & args){  return symbolic(at_throw,args);  }
_throw(const gen & args,GIAC_CONTEXT)4676   gen _throw(const gen & args,GIAC_CONTEXT){
4677     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
4678     return gensizeerr(args.print(contextptr));
4679   }
4680   static const char _throw_s []="throw";
4681   static define_unary_function_eval (__throw,&_throw,_throw_s);
4682   define_unary_function_ptr5( at_throw ,alias_at_throw ,&__throw,0,T_RETURN);
4683 
symb_union(const gen & args)4684   gen symb_union(const gen & args){
4685     return symbolic(at_union,args);
4686   }
_union(const gen & args,GIAC_CONTEXT)4687   gen _union(const gen & args,GIAC_CONTEXT){
4688     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
4689     if (args.type!=_VECT)
4690       return gensizeerr(contextptr);
4691     vecteur & v =*args._VECTptr;
4692     if (v.empty())
4693       return args;
4694     if (v.size()==1 && v.front().type==_VECT)
4695       return gen(v,_SET__VECT).eval(1,contextptr);
4696     if (v.size()!=2)
4697       return gensizeerr(contextptr);
4698     gen a=v.front(),b=v.back();
4699 #if defined HAVE_LIBMPFI && !defined NO_RTTI
4700     if (a.type==_REAL && b.type==_REAL){
4701       if (real_interval * aptr=dynamic_cast<real_interval *>(a._REALptr)){
4702 	if (real_interval * bptr=dynamic_cast<real_interval *>(b._REALptr)){
4703 	  mpfi_t tmp;
4704 	  mpfi_init2(tmp,giacmin(mpfi_get_prec(aptr->infsup),mpfi_get_prec(bptr->infsup)));
4705 	  mpfi_union(tmp,aptr->infsup,bptr->infsup);
4706 	  gen res=real_interval(tmp);
4707 	  mpfi_clear(tmp);
4708 	  return res;
4709 	}
4710 	else {
4711 	  if (contains(a,b))
4712 	    return a;
4713 	  else
4714 	    return _union(makesequence(a,eval(gen(makevecteur(b,b),_INTERVAL__VECT),1,contextptr)),contextptr);
4715 	}
4716       }
4717       if (contains(b,a))
4718 	return b;
4719       else
4720 	return _union(makesequence(b,eval(gen(makevecteur(a,a),_INTERVAL__VECT),1,contextptr)),contextptr);
4721     }
4722     if (a.type==_REAL){
4723       if (contains(a,b))
4724 	return a;
4725       else
4726 	return _union(makesequence(a,eval(gen(makevecteur(b,b),_INTERVAL__VECT),1,contextptr)),contextptr);
4727     }
4728     if (b.type==_REAL){
4729       if (contains(b,a))
4730 	return b;
4731       else
4732 	return _union(makesequence(a,eval(gen(makevecteur(b,b),_INTERVAL__VECT),1,contextptr)),contextptr);
4733     }
4734 #endif
4735     if ( (a.type!=_VECT) || (b.type!=_VECT))
4736       return gensizeerr(gettext("Union"));
4737     return gen(mergevecteur(*a._VECTptr,*b._VECTptr),_SET__VECT).eval(1,contextptr);
4738   }
4739   static const char _union_s []=" union ";
4740   static define_unary_function_eval4_index (58,__union,&_union,_union_s,&printsommetasoperator,&texprintsommetasoperator);
4741   define_unary_function_ptr( at_union ,alias_at_union ,&__union);
4742 
chk_set(gen & a)4743   void chk_set(gen & a){
4744     if (a.type==_VECT && a.subtype!=_SET__VECT){
4745       vecteur av=*a._VECTptr; comprim(av); a=av;
4746     }
4747   }
symb_intersect(const gen & args)4748   gen symb_intersect(const gen & args){
4749     return symbolic(at_intersect,args);
4750   }
_intersect(const gen & args,GIAC_CONTEXT)4751   gen _intersect(const gen & args,GIAC_CONTEXT){
4752     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
4753     if ((args.type!=_VECT) || (args._VECTptr->size()!=2))
4754       return gensizeerr();
4755     gen a=args._VECTptr->front(),b=args._VECTptr->back();
4756 #if defined HAVE_LIBMPFI && !defined NO_RTTI
4757     if (a.type==_REAL && b.type==_REAL){
4758       if (real_interval * aptr=dynamic_cast<real_interval *>(a._REALptr)){
4759 	if (real_interval * bptr=dynamic_cast<real_interval *>(b._REALptr)){
4760 	  mpfi_t tmp;
4761 	  mpfi_init2(tmp,giacmin(mpfi_get_prec(aptr->infsup),mpfi_get_prec(bptr->infsup)));
4762 	  mpfi_intersect(tmp,aptr->infsup,bptr->infsup);
4763 	  gen res;
4764 	  if (mpfi_is_empty(tmp))
4765 	    res=vecteur(0);
4766 	  else
4767 	    res=real_interval(tmp);
4768 	  mpfi_clear(tmp);
4769 	  return res;
4770 	}
4771 	else {
4772 	  if (contains(a,b))
4773 	    return eval(gen(makevecteur(b,b),_INTERVAL__VECT),1,contextptr);
4774 	  return vecteur(0);
4775 	}
4776       }
4777       if (contains(b,a))
4778 	return eval(gen(makevecteur(a,a),_INTERVAL__VECT),1,contextptr);
4779       return vecteur(0);
4780     }
4781     if (a.type==_REAL){
4782       if (contains(a,b))
4783 	return eval(gen(makevecteur(b,b),_INTERVAL__VECT),1,contextptr);
4784       else
4785 	return vecteur(0);
4786     }
4787     if (b.type==_REAL){
4788       if (contains(b,a))
4789 	return a;
4790       else
4791 	return vecteur(0);
4792     }
4793 #endif
4794     if ( a.type==_VECT && b.type==_VECT){
4795       chk_set(a);
4796       chk_set(b);
4797       vecteur v;
4798       const_iterateur it=a._VECTptr->begin(),itend=a._VECTptr->end();
4799       for (;it!=itend;++it){
4800 	if (equalposcomp(*b._VECTptr,*it))
4801 	  v.push_back(*it);
4802       }
4803       return gen(v,_SET__VECT);
4804     }
4805     return gensizeerr(contextptr);
4806   }
4807   static const char _intersect_s []=" intersect ";
4808   static define_unary_function_eval4_index (62,__intersect,&_intersect,_intersect_s,&printsommetasoperator,&texprintsommetasoperator);
4809   define_unary_function_ptr( at_intersect ,alias_at_intersect ,&__intersect);
4810 
symb_minus(const gen & args)4811   gen symb_minus(const gen & args){
4812     return symbolic(at_minus,args);
4813   }
_minus(const gen & args,GIAC_CONTEXT)4814   gen _minus(const gen & args,GIAC_CONTEXT){
4815     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
4816     if ((args.type!=_VECT) || (args._VECTptr->size()!=2))
4817       return symb_minus(args);
4818     gen a=args._VECTptr->front(),b=args._VECTptr->back();
4819     if ( (a.type!=_VECT) || (b.type!=_VECT))
4820       return gensizeerr(gettext("Minus"));
4821     chk_set(a);
4822     chk_set(b);
4823     vecteur v;
4824     const_iterateur it=a._VECTptr->begin(),itend=a._VECTptr->end();
4825     for (;it!=itend;++it){
4826       if (!equalposcomp(*b._VECTptr,*it))
4827 	v.push_back(*it);
4828     }
4829     return gen(v,_SET__VECT);
4830   }
4831   static const char _minus_s []=" minus ";
4832   static define_unary_function_eval4_index (60,__minus,&_minus,_minus_s,&printsommetasoperator,&texprintsommetasoperator);
4833   define_unary_function_ptr( at_minus ,alias_at_minus ,&__minus);
4834 
printasdollar(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)4835   static string printasdollar(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
4836     if (feuille.type!=_VECT)
4837       return sommetstr+feuille.print(contextptr);
4838     vecteur & v=*feuille._VECTptr;
4839     int s=int(v.size());
4840     if (s==2)
4841       return printsommetasoperator(feuille,sommetstr,contextptr);
4842     if (s==3)
4843       return v[0].print(contextptr)+sommetstr+v[1].print(contextptr)+" in "+v[2].print(contextptr);
4844     return gettext("error");
4845   }
symb_dollar(const gen & args)4846   gen symb_dollar(const gen & args){
4847     return symbolic(at_dollar,args);
4848   }
_dollar(const gen & args,GIAC_CONTEXT)4849   gen _dollar(const gen & args,GIAC_CONTEXT){
4850     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
4851     if (abs_calc_mode(contextptr)==38){
4852       int r,c;
4853       if (iscell(args,r,c,contextptr)){
4854 	string s=symbolic(at_dollar,args).print(contextptr);
4855 	identificateur cellule(s);
4856 	return eval(cellule,1,contextptr);
4857       }
4858       if (args.type==_VECT && args._VECTptr->size()==2 && args._VECTptr->back().type==_INT_ && args._VECTptr->back().val>0){
4859 	string s=args._VECTptr->front().print(contextptr)+"$"+print_INT_(args._VECTptr->back().val);
4860 	identificateur cellule(s);
4861 	return eval(cellule,1,contextptr);
4862       }
4863     }
4864     vecteur vargs;
4865     if (args.type!=_VECT){
4866       identificateur tmp(" _t");
4867       vargs=makevecteur(tmp,symbolic(at_equal,gen(makevecteur(tmp,args),_SEQ__VECT)));
4868     }
4869     else
4870       vargs=*args._VECTptr;
4871     int s=int(vargs.size());
4872     if (s<2)
4873       return symb_dollar(args);
4874     gen a=vargs.front(),b=vargs[1],b1=eval(b,eval_level(contextptr),contextptr);
4875     if (b1.type==_VECT && b1.subtype==_SEQ__VECT && b1._VECTptr->size()==2){
4876       gen b11=b1._VECTptr->front();
4877       if (b.type==_VECT && b.subtype==_SEQ__VECT && b._VECTptr->size()==2 && b11.is_symb_of_sommet(at_equal) && b._VECTptr->front().is_symb_of_sommet(at_equal))
4878 	b11=symb_equal(b._VECTptr->front()[1],b11[2]);
4879       return _dollar(gen(makevecteur(a,b11,b1._VECTptr->back()),_SEQ__VECT),contextptr);
4880     }
4881     if (a.is_symb_of_sommet(at_interval) && a._SYMBptr->feuille.type==_VECT && a._SYMBptr->feuille._VECTptr->size()==2){
4882       a=eval(a,1,contextptr);
4883       gen a1=a._SYMBptr->feuille._VECTptr->front(),a2=a._SYMBptr->feuille._VECTptr->back();
4884       gen nstep=(a2-a1)/b1;
4885       if (nstep.type==_DOUBLE_)
4886 	nstep=(1+1e-12)*nstep;
4887       if (ck_is_positive(nstep,contextptr))
4888 	nstep=_floor(nstep,contextptr);
4889       else {
4890 	nstep=_floor(-nstep,contextptr);
4891 	b1=-b1;
4892       }
4893       if (nstep.type!=_INT_ || nstep.val<0 || nstep.val>LIST_SIZE_LIMIT)
4894 	return gendimerr(contextptr);
4895       vecteur res;
4896       for (unsigned i=0;int(i)<=nstep.val;++i){
4897 	res.push_back(a1);
4898 	a1 += b1;
4899       }
4900       return gen(res,_SEQ__VECT);
4901     }
4902     if (b1.type==_INT_ && b1.val>=0){
4903       if (b1.val>LIST_SIZE_LIMIT)
4904 	return gendimerr(contextptr);
4905       return gen(vecteur(b1.val,eval(a,eval_level(contextptr),contextptr)),_SEQ__VECT);
4906     }
4907     gen var,intervalle,step=1;
4908     if ( (b.type==_SYMB) && (is_equal(b) || b._SYMBptr->sommet==at_same ) ){
4909       var=b._SYMBptr->feuille._VECTptr->front();
4910       if (var.type!=_IDNT)
4911 	return gensizeerr(contextptr);
4912       /* Commented example seq(irem(g&^((p-1)/(Div[i])),p),i=(1 .. 2))
4913 	 int status=*var._IDNTptr->quoted;
4914 	 *var._IDNTptr->quoted=1;
4915 	 a=eval(a,contextptr);
4916 	 *var._IDNTptr->quoted=status;
4917       */
4918       intervalle=eval(b._SYMBptr->feuille._VECTptr->back(),eval_level(contextptr),contextptr);
4919       if (s>=3)
4920 	step=vargs[2];
4921     }
4922     else {
4923       if (s>=3){
4924 	var=vargs[1];
4925 	intervalle=eval(vargs[2],eval_level(contextptr),contextptr);
4926       }
4927       if (s>=4)
4928 	step=vargs[3];
4929     }
4930     if (intervalle.type==_VECT){
4931       const_iterateur it=intervalle._VECTptr->begin(),itend=intervalle._VECTptr->end();
4932       vecteur res;
4933       for (;it!=itend;++it)
4934 	res.push_back(eval(quotesubst(a,var,*it,contextptr),eval_level(contextptr),contextptr));
4935       return gen(res,_SEQ__VECT);
4936       // return gen(res,intervalle.subtype);
4937     }
4938     if ( (intervalle.type==_SYMB) && (intervalle._SYMBptr->sommet==at_interval)){
4939       gen c=intervalle._SYMBptr->feuille._VECTptr->front(),d=intervalle._SYMBptr->feuille._VECTptr->back();
4940       if ( (!is_integral(c) || !is_integral(d)) && abs_calc_mode(contextptr)==38)
4941 	return gensizeerr(contextptr);
4942       gen debut=c,fin=d;
4943       bool reverse=ck_is_greater(debut,fin,contextptr);
4944       step=abs(step,contextptr);
4945       if (is_positive(abs(fin-debut,contextptr)-LIST_SIZE_LIMIT*step,contextptr))
4946 	return gendimerr(contextptr);
4947       step=eval(reverse?-step:step,eval_level(contextptr),contextptr);
4948       vecteur res;
4949       for (;;debut+=step){
4950 	if (ck_is_strictly_greater(reverse?fin:debut,reverse?debut:fin,contextptr))
4951 	  break;
4952 	res.push_back(eval(quotesubst(a,var,debut,contextptr),eval_level(contextptr),contextptr));
4953 	if (debut==fin)
4954 	  break;
4955       }
4956       return gen(res,_SEQ__VECT);
4957     }
4958     return symb_dollar(args);
4959   }
4960   static const char _dollar_s []="$";
texprintasdollar(const gen & g,const char * s,GIAC_CONTEXT)4961   string texprintasdollar(const gen & g,const char * s,GIAC_CONTEXT){
4962     if ( (g.type==_VECT) && (g._VECTptr->size()==2))
4963       return gen2tex(g._VECTptr->front(),contextptr)+"\\$"+gen2tex(g._VECTptr->back(),contextptr);
4964     return "\\$ "+g.print(contextptr);
4965   }
4966   static define_unary_function_eval4_index (125,__dollar,&_dollar,_dollar_s,&printasdollar,&texprintasdollar);
4967   define_unary_function_ptr5( at_dollar ,alias_at_dollar,&__dollar,_QUOTE_ARGUMENTS,0);
4968 
symb_makemat(const gen & args)4969   static gen symb_makemat(const gen & args){
4970     return symbolic(at_makemat,args);
4971   }
_makemat(const gen & args,const context * contextptr)4972   gen _makemat(const gen & args,const context * contextptr){
4973     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
4974     if (args.type==_INT_ && args.val>0 && double(args.val)*args.val<LIST_SIZE_LIMIT){
4975       vecteur res;
4976       for (int i=0;i<args.val;++i)
4977 	res.push_back(vecteur(args.val,0));
4978       return gen(res,_MATRIX__VECT);
4979     }
4980     if (args.type!=_VECT)
4981       return symb_makemat(args);
4982     int s=int(args._VECTptr->size());
4983     if ( (s!=3) && (s!=2) )
4984       return symb_makemat(args);
4985     gen fonction,intervalle1,intervalle2;
4986     if (s==3){
4987       fonction=args._VECTptr->front();
4988       intervalle1=(*(args._VECTptr))[1];
4989       intervalle2=args._VECTptr->back();
4990     }
4991     else {
4992       intervalle1=args._VECTptr->front();
4993       intervalle2=args._VECTptr->back();
4994     }
4995     if (is_integral(intervalle1) && intervalle1.type==_INT_)
4996       intervalle1=symb_interval(makevecteur(zero,giacmax(intervalle1.val,1)-1));
4997     if (is_integral(intervalle2) && intervalle2.type==_INT_)
4998       intervalle2=symb_interval(makevecteur(zero,giacmax(intervalle2.val,1)-1));
4999     if ( (intervalle1.type!=_SYMB) || (intervalle1._SYMBptr->sommet!=at_interval) ||(intervalle2.type!=_SYMB) || (intervalle2._SYMBptr->sommet!=at_interval))
5000       return gensizeerr(gettext("makemat"));
5001     intervalle1=intervalle1._SYMBptr->feuille;
5002     intervalle2=intervalle2._SYMBptr->feuille;
5003     if ((intervalle1.type!=_VECT) || (intervalle1._VECTptr->size()!=2) || (intervalle2.type!=_VECT) || (intervalle2._VECTptr->size()!=2))
5004       return gensizeerr(gettext("interval"));
5005     gen debut_i=intervalle1._VECTptr->front(),fin_i=intervalle1._VECTptr->back();
5006     gen debut_j=intervalle2._VECTptr->front(),fin_j=intervalle2._VECTptr->back();
5007     if ( (debut_i.type!=_INT_) || (fin_i.type!=_INT_) || (debut_j.type!=_INT_) || (fin_j.type!=_INT_) )
5008       return gensizeerr(gettext("Boundaries not integer"));
5009     int di=debut_i.val,fi=fin_i.val,dj=debut_j.val,fj=fin_j.val;
5010     if (array_start(contextptr)){
5011       ++di; ++fi; ++dj; ++fj;
5012     }
5013     int stepi=1,stepj=1;
5014     if (di>fi)
5015       stepi=-1;
5016     if (dj>fj)
5017       stepj=-1;
5018     if ((fonction.type!=_SYMB) || (fonction._SYMBptr->sommet!=at_program)){
5019       int s=(fj-dj+1)*stepj;
5020       vecteur w(s,fonction);
5021       int t=(fi-di+1)*stepi;
5022       vecteur res(t);
5023       for (int i=0;i<t;++i)
5024 	res[i]=w; // each element of res will be a free line, so that =< works
5025       return gen(res,_MATRIX__VECT);
5026     }
5027     vecteur v,w,a(2);
5028     v.reserve((fi-di)*stepi);
5029     w.reserve((fj-dj)*stepj);
5030     for (;;di+=stepi){
5031       a[0]=di;
5032       w.clear();
5033       for (int djj=dj;;djj+=stepj){
5034 	a[1]=djj;
5035 	w.push_back(fonction(gen(a,_SEQ__VECT),contextptr));
5036 	if (djj==fj)
5037 	  break;
5038       }
5039       v.push_back(w);
5040       if (di==fi)
5041 	break;
5042     }
5043     return gen(v,_MATRIX__VECT);
5044   }
5045   static const char _makemat_s []="makemat";
5046   static define_unary_function_eval (__makemat,&_makemat,_makemat_s);
5047   define_unary_function_ptr5( at_makemat ,alias_at_makemat,&__makemat,0,true);
5048 
symb_compose(const gen & args)5049   gen symb_compose(const gen & args){
5050     return symbolic(at_compose,args);
5051   }
_compose(const gen & args,GIAC_CONTEXT)5052   gen _compose(const gen & args,GIAC_CONTEXT){
5053     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5054     if (args.type==_VECT && args.subtype==_SEQ__VECT && args._VECTptr->size()==2&& args._VECTptr->back().type==_SPOL1){
5055       gen g=args._VECTptr->front();
5056       gen s=args._VECTptr->back();
5057       sparse_poly1 res;
5058       int shift=0;
5059       if (g.type==_SPOL1){
5060 	vecteur v;
5061 	if (sparse_poly12vecteur(*g._SPOL1ptr,v,shift))
5062 	  g=v;
5063       }
5064       if (g.type==_VECT){
5065 	vecteur v=*g._VECTptr;
5066 	reverse(v.begin(),v.end());
5067 	if (!pcompose(v,*s._SPOL1ptr,res,contextptr))
5068 	  return sparse_poly1(1,monome(1,undef));
5069 	if (shift==0)
5070 	  return res;
5071 	return spmul(res,sppow(*s._SPOL1ptr,shift,contextptr),contextptr);
5072       }
5073     }
5074     if (args.type==_VECT && args.subtype==_SEQ__VECT && args._VECTptr->size()==2){
5075       gen g=args._VECTptr->front();
5076       gen s=args._VECTptr->back();
5077       if (g.type==_VECT && (g.subtype==_POLY1__VECT || s.type==_SPOL1 || (s.type==_VECT && s.subtype==_POLY1__VECT)) )
5078 	return horner(*g._VECTptr,s,contextptr);
5079       if (ckmatrix(g) && ckmatrix(s))
5080 	return g*s;
5081     }
5082     return symb_compose(args);
5083   }
5084   static const char _compose_s []="@";
5085   static define_unary_function_eval4 (__compose,&_compose,_compose_s,&printsommetasoperator,&texprintsommetasoperator);
5086   define_unary_function_ptr( at_compose ,alias_at_compose ,&__compose);
5087 
_composepow(const gen & args,GIAC_CONTEXT)5088   gen _composepow(const gen & args,GIAC_CONTEXT){
5089     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5090     if (args.type==_VECT && args.subtype==_SEQ__VECT && args._VECTptr->size()==2){
5091       gen base=args._VECTptr->front();
5092       gen expo=args._VECTptr->back();
5093       if (expo.type==_INT_){
5094 	if (base.type==_SPOL1){
5095 	  int n=expo.val;
5096 	  sparse_poly1 s=*base._SPOL1ptr;
5097 	  if (n<0){
5098 	    gen tmp=_revert(s,contextptr);
5099 	    if (tmp.type!=_SPOL1)
5100 	      return tmp;
5101 	    s=*tmp._SPOL1ptr;
5102 	    n=-n;
5103 	  }
5104 	  gen res=sparse_poly1(1,monome(1,1)); // identity
5105 	  for (;n>0;n/=2){
5106 	    if (n%2) res=_compose(makesequence(res,s),contextptr);
5107 	    gen tmp=_compose(makesequence(s,s),contextptr);
5108 	    if (tmp.type!=_SPOL1)
5109 	      return tmp;
5110 	    s=*tmp._SPOL1ptr;
5111 	  }
5112 	  return res;
5113 	}
5114 	if (base.type==_VECT && base.subtype==_POLY1__VECT && expo.val>=0){
5115 	  int n=expo.val;
5116 	  vecteur v(2); v[0]=1;
5117 	  gen res=gen(v,_POLY1__VECT);
5118 	  gen s=base;
5119 	  for (;n>0;n/=2){
5120 	    if (n%2) res=horner(*res._VECTptr,s,contextptr);
5121 	    s=horner(*s._VECTptr,s,contextptr);
5122 	  }
5123 	  return res;
5124 	}
5125 	if (ckmatrix(base))
5126 	  return _pow(args,contextptr);
5127       }
5128     }
5129     return symbolic(at_composepow,args);
5130   }
5131   static const char _composepow_s []="@@";
5132   static define_unary_function_eval4 (__composepow,&_composepow,_composepow_s,&printsommetasoperator,&texprintsommetasoperator);
5133   define_unary_function_ptr( at_composepow ,alias_at_composepow ,&__composepow);
5134 
symb_args(const gen & args)5135   gen symb_args(const gen & args){
5136     return symbolic(at_args,args);
5137   }
_args(const gen & args,const context * contextptr)5138   gen _args(const gen & args,const context * contextptr){
5139     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5140     gen e;
5141     if (debug_ptr(contextptr)->args_stack.empty())
5142       e=vecteur(0);
5143     else
5144       e=debug_ptr(contextptr)->args_stack.back();
5145     if ( (args.type==_VECT) && (args._VECTptr->empty()))
5146       return e;
5147     else
5148       return e(args,contextptr);
5149   }
5150   static const char _args_s []="args";
5151   static define_unary_function_eval (__args,&_args,_args_s);
5152   define_unary_function_ptr( at_args ,alias_at_args ,&__args);
5153 
5154   // static gen symb_lname(const gen & args){  return symbolic(at_lname,args);  }
lidnt(const vecteur & v,vecteur & res,bool with_at)5155   static void lidnt(const vecteur & v,vecteur & res,bool with_at){
5156     const_iterateur it=v.begin(),itend=v.end();
5157     for (;it!=itend;++it)
5158       lidnt(*it,res,with_at);
5159   }
5160 
5161   extern const unary_function_ptr * const  at_int;
5162 
lidnt(const gen & args,vecteur & res,bool with_at)5163   void lidnt(const gen & args,vecteur & res,bool with_at){
5164     switch (args.type){
5165     case _IDNT:
5166       if (!equalposcomp(res,args))
5167 	res.push_back(args);
5168       break;
5169     case _SYMB:
5170       if (with_at && args._SYMBptr->sommet==at_at){
5171 	res.push_back(args);
5172 	return;
5173       }
5174       if (args._SYMBptr->sommet==at_program && args._SYMBptr->feuille.type==_VECT && args._SYMBptr->feuille._VECTptr->size()==3){
5175 	lidnt(args._SYMBptr->feuille._VECTptr->front(),res,with_at);
5176 	lidnt(args._SYMBptr->feuille._VECTptr->back(),res,with_at);
5177 	return;
5178       }
5179       if (args._SYMBptr->sommet==at_pnt && args._SYMBptr->feuille.type==_VECT && args._SYMBptr->feuille._VECTptr->size()==3){
5180 	lidnt(args._SYMBptr->feuille._VECTptr->front(),res,with_at);
5181 	lidnt((*args._SYMBptr->feuille._VECTptr)[1],res,with_at);
5182 	return;
5183       }
5184       if ( (args._SYMBptr->sommet==at_integrate || args._SYMBptr->sommet==at_int || args._SYMBptr->sommet==at_sum) && args._SYMBptr->feuille.type==_VECT && args._SYMBptr->feuille._VECTptr->size()==4){
5185 	vecteur & v =*args._SYMBptr->feuille._VECTptr;
5186 	vecteur w(1,v[1]);
5187 	lidnt(v[0],w,with_at);
5188 	const_iterateur it=w.begin(),itend=w.end();
5189 	for (++it;it!=itend;++it)
5190 	  lidnt(*it,res,with_at);
5191 	lidnt(v[2],res,with_at);
5192 	lidnt(v.back(),res,with_at);
5193 	return;
5194       }
5195       lidnt(args._SYMBptr->feuille,res,with_at);
5196       break;
5197     case _VECT:
5198       lidnt(*args._VECTptr,res,with_at);
5199       break;
5200     }
5201   }
lidnt(const gen & args)5202   vecteur lidnt(const gen & args){
5203     vecteur res;
5204     lidnt(args,res,false);
5205     return res;
5206   }
lidnt_with_at(const gen & args)5207   vecteur lidnt_with_at(const gen & args){
5208     vecteur res;
5209     lidnt(args,res,true);
5210     return res;
5211   }
_lname(const gen & args,GIAC_CONTEXT)5212   gen _lname(const gen & args,GIAC_CONTEXT){
5213     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5214     vecteur res=makevecteur(cst_pi,cst_euler_gamma);
5215     lidnt(args,res,false);
5216     return vecteur(res.begin()+2,res.end());
5217   }
5218   static const char _lname_s []="lname";
5219   static define_unary_function_eval (__lname,&_lname,_lname_s);
5220   define_unary_function_ptr5( at_lname ,alias_at_lname,&__lname,0,true);
5221 
symb_has(const gen & args)5222   static gen symb_has(const gen & args){
5223     return symbolic(at_has,args);
5224   }
_has(const gen & args,GIAC_CONTEXT)5225   gen _has(const gen & args,GIAC_CONTEXT){
5226     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5227     if ( (args.type!=_VECT) || (args._VECTptr->size()!=2))
5228       return symb_has(args);
5229     gen tmp(_lname(args._VECTptr->front(),contextptr));
5230     if (tmp.type!=_VECT) return tmp;
5231     return equalposcomp(*tmp._VECTptr,args._VECTptr->back());
5232   }
5233   static const char _has_s []="has";
5234   static define_unary_function_eval (__has,&_has,_has_s);
5235   define_unary_function_ptr5( at_has ,alias_at_has,&__has,0,true);
5236 
_kill(const gen & args,GIAC_CONTEXT)5237   gen _kill(const gen & args,GIAC_CONTEXT){
5238     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5239     if (args.type==_VECT && args._VECTptr->empty()){
5240       if (!contextptr)
5241 	protection_level=0;
5242       debug_ptr(contextptr)->debug_mode=false;
5243       debug_ptr(contextptr)->current_instruction_stack.clear();
5244       debug_ptr(contextptr)->sst_at_stack.clear();
5245       debug_ptr(contextptr)->args_stack.clear();
5246       return gensizeerr(gettext("Program killed"));
5247     }
5248 #ifdef HAVE_LIBPTHREAD
5249     if (args.type==_VECT)
5250       return apply(args,_kill,contextptr);
5251     if (args.type==_POINTER_ && args.subtype==_THREAD_POINTER){
5252       context * cptr=(context *) args._POINTER_val;
5253       thread_param * tptr =thread_param_ptr(cptr);
5254       if (cptr
5255 #ifndef __MINGW_H
5256 	  && tptr->eval_thread
5257 #endif
5258 	  ){
5259 	gen g=tptr->v[0];
5260 	if (g.type==_VECT && g._VECTptr->size()==2 && g._VECTptr->front().is_symb_of_sommet(at_quote)){
5261 	  pthread_mutex_lock(cptr->globalptr->_mutex_eval_status_ptr);
5262 	  gen tmpsto=sto(undef,g._VECTptr->front()._SYMBptr->feuille,cptr);
5263 	  if (is_undef(tmpsto)) return tmpsto;
5264 	  pthread_mutex_unlock(cptr->globalptr->_mutex_eval_status_ptr);
5265 	}
5266       }
5267       kill_thread(true,cptr);
5268       return 1;
5269     }
5270 #endif
5271     return gentypeerr(contextptr);
5272   }
5273   static const char _kill_s []="kill";
5274   static define_unary_function_eval (__kill,&_kill,_kill_s);
5275   define_unary_function_ptr5( at_kill ,alias_at_kill,&__kill,0,true);
5276 
_halt(const gen & args,GIAC_CONTEXT)5277   gen _halt(const gen & args,GIAC_CONTEXT){
5278     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5279     if (debug_ptr(contextptr)->debug_allowed){
5280       debug_ptr(contextptr)->debug_mode=true;
5281       debug_ptr(contextptr)->sst_mode=true;
5282       return plus_one;
5283     }
5284     return zero;
5285   }
5286   static const char _halt_s []="halt";
5287   static define_unary_function_eval_quoted (__halt,&_halt,_halt_s);
5288   define_unary_function_ptr5( at_halt ,alias_at_halt,&__halt,_QUOTE_ARGUMENTS,true);
5289 
_debug(const gen & args,GIAC_CONTEXT)5290   gen _debug(const gen & args,GIAC_CONTEXT){
5291     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5292     if (child_id && thread_eval_status(contextptr)!=1)
5293       return args;
5294     if (debug_ptr(contextptr)->debug_allowed){
5295       debug_ptr(contextptr)->debug_mode=true;
5296       debug_ptr(contextptr)->sst_in_mode=true;
5297       debug_ptr(contextptr)->debug_prog_name=0;
5298     }
5299     return args.eval(eval_level(contextptr),contextptr);
5300   }
5301   static const char _debug_s []="debug";
5302   static define_unary_function_eval_quoted (__debug,&_debug,_debug_s);
5303   define_unary_function_ptr5( at_debug ,alias_at_debug,&__debug,_QUOTE_ARGUMENTS,true);
5304 
_sst_in(const gen & args,GIAC_CONTEXT)5305   gen _sst_in(const gen & args,GIAC_CONTEXT){
5306     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5307     if (child_id)
5308       return zero;
5309     if (debug_ptr(contextptr)->debug_allowed){
5310       debug_ptr(contextptr)->debug_mode=true;
5311       debug_ptr(contextptr)->sst_in_mode=true;
5312       return plus_one;
5313     }
5314     return zero;
5315   }
5316   static const char _sst_in_s []="sst_in";
5317   static define_unary_function_eval_quoted (__sst_in,&_sst_in,_sst_in_s);
5318   define_unary_function_ptr5( at_sst_in ,alias_at_sst_in,&__sst_in,_QUOTE_ARGUMENTS,true);
5319 
_sst(const gen & args,GIAC_CONTEXT)5320   gen _sst(const gen & args,GIAC_CONTEXT){
5321     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5322     if (child_id)
5323       return args;
5324     if (debug_ptr(contextptr)->debug_allowed){
5325       debug_ptr(contextptr)->debug_mode=true;
5326       debug_ptr(contextptr)->sst_mode=true;
5327       return plus_one;
5328     }
5329     return zero;
5330   }
5331   static const char _sst_s []="sst";
5332   static define_unary_function_eval_quoted (__sst,&_sst,_sst_s);
5333   define_unary_function_ptr5( at_sst ,alias_at_sst,&__sst,_QUOTE_ARGUMENTS,true);
5334 
_cont(const gen & args,GIAC_CONTEXT)5335   gen _cont(const gen & args,GIAC_CONTEXT){
5336     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5337     if (child_id)
5338       return args;
5339     if (debug_ptr(contextptr)->debug_allowed){
5340       debug_ptr(contextptr)->sst_mode=false;
5341       return plus_one;
5342     }
5343     return zero;
5344   }
5345   static const char _cont_s []="cont";
5346   static define_unary_function_eval_quoted (__cont,&_cont,_cont_s);
5347   define_unary_function_ptr5( at_cont ,alias_at_cont,&__cont,_QUOTE_ARGUMENTS,true);
5348 
watch(const gen & args,GIAC_CONTEXT)5349   static gen watch(const gen & args,GIAC_CONTEXT){
5350     if (!equalposcomp(debug_ptr(contextptr)->debug_watch,args))
5351       debug_ptr(contextptr)->debug_watch.push_back(args);
5352     return args;
5353   }
_watch(const gen & args,GIAC_CONTEXT)5354   gen _watch(const gen & args,GIAC_CONTEXT){
5355     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5356     if (child_id && thread_eval_status(contextptr)!=1 )
5357       return args;
5358     if (args.type==_VECT && args._VECTptr->empty() && debug_ptr(contextptr)->debug_localvars)
5359       apply( *debug_ptr(contextptr)->debug_localvars,contextptr,watch);
5360     else
5361       apply(args,contextptr,watch);
5362     return debug_ptr(contextptr)->debug_watch;
5363   }
5364   static const char _watch_s []="watch";
5365   static define_unary_function_eval_quoted (__watch,&_watch,_watch_s);
5366   define_unary_function_ptr5( at_watch ,alias_at_watch,&__watch,_QUOTE_ARGUMENTS,true);
5367 
rmwatch(const gen & args,GIAC_CONTEXT)5368   static gen rmwatch(const gen & args,GIAC_CONTEXT){
5369     int pos;
5370     if (args.type==_INT_){
5371       pos=args.val+1;
5372       if (pos>signed(debug_ptr(contextptr)->debug_watch.size()))
5373 	return debug_ptr(contextptr)->debug_watch;
5374     }
5375     else
5376       pos=equalposcomp(debug_ptr(contextptr)->debug_watch,args);
5377     if (pos){
5378       debug_ptr(contextptr)->debug_watch.erase(debug_ptr(contextptr)->debug_watch.begin()+pos-1,debug_ptr(contextptr)->debug_watch.begin()+pos);
5379       return debug_ptr(contextptr)->debug_watch;
5380     }
5381     return zero;
5382   }
5383 
_rmwatch(const gen & args,GIAC_CONTEXT)5384   gen _rmwatch(const gen & args,GIAC_CONTEXT){
5385     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5386     if (args.type==_VECT && args._VECTptr->empty() && debug_ptr(contextptr)->debug_localvars)
5387       return apply( *debug_ptr(contextptr)->debug_localvars,contextptr,rmwatch);
5388     else
5389       return apply(args,contextptr,rmwatch);
5390   }
5391   static const char _rmwatch_s []="rmwatch";
5392   static define_unary_function_eval_quoted (__rmwatch,&_rmwatch,_rmwatch_s);
5393   define_unary_function_ptr5( at_rmwatch ,alias_at_rmwatch,&__rmwatch,_QUOTE_ARGUMENTS,true);
5394 
_breakpoint(const gen & args,GIAC_CONTEXT)5395   gen _breakpoint(const gen & args,GIAC_CONTEXT){
5396     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5397     if (child_id && thread_eval_status(contextptr)!=1)
5398       return args;
5399     if ( (args.type!=_VECT) || (args._VECTptr->size()!=2) || (args._VECTptr->front().type!=_IDNT) || (args._VECTptr->back().type!=_INT_) )
5400       return zero;
5401     if (!equalposcomp(debug_ptr(contextptr)->debug_breakpoint,args)){
5402       debug_ptr(contextptr)->debug_breakpoint.push_back(args);
5403       // FIXME should also modify debug_ptr(contextptr)->sst_at_stack if the breakpoint applies
5404       // to a program != current program
5405       if (!debug_ptr(contextptr)->args_stack.empty() && debug_ptr(contextptr)->args_stack.back().type==_VECT && debug_ptr(contextptr)->args_stack.back()._VECTptr->front()==args._VECTptr->front())
5406 	debug_ptr(contextptr)->sst_at.push_back(args._VECTptr->back().val);
5407     }
5408     return debug_ptr(contextptr)->debug_breakpoint;
5409   }
5410   static const char _breakpoint_s []="breakpoint";
5411   static define_unary_function_eval_quoted (__breakpoint,&_breakpoint,_breakpoint_s);
5412   define_unary_function_ptr5( at_breakpoint ,alias_at_breakpoint,&__breakpoint,_QUOTE_ARGUMENTS,true);
5413 
_rmbreakpoint(const gen & args,GIAC_CONTEXT)5414   gen _rmbreakpoint(const gen & args,GIAC_CONTEXT){
5415     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
5416     if (child_id&& thread_eval_status(contextptr)!=1)
5417       return args;
5418     int pos;
5419     if (args.type==_INT_){
5420       pos=args.val;
5421       if (pos<1 || pos>signed(debug_ptr(contextptr)->debug_breakpoint.size())){
5422 	adjust_sst_at(*debug_ptr(contextptr)->debug_prog_name,contextptr);
5423 	return debug_ptr(contextptr)->debug_breakpoint;
5424       }
5425     }
5426     else
5427       pos=equalposcomp(debug_ptr(contextptr)->debug_breakpoint,args);
5428     if (pos){
5429       debug_ptr(contextptr)->debug_breakpoint.erase(debug_ptr(contextptr)->debug_breakpoint.begin()+pos-1,debug_ptr(contextptr)->debug_breakpoint.begin()+pos);
5430       adjust_sst_at(*debug_ptr(contextptr)->debug_prog_name,contextptr);
5431       return debug_ptr(contextptr)->debug_breakpoint;
5432     }
5433     return zero;
5434   }
5435   static const char _rmbreakpoint_s []="rmbreakpoint";
5436   static define_unary_function_eval_quoted (__rmbreakpoint,&_rmbreakpoint,_rmbreakpoint_s);
5437   define_unary_function_ptr5( at_rmbreakpoint ,alias_at_rmbreakpoint,&__rmbreakpoint,_QUOTE_ARGUMENTS,true);
5438 
5439 #ifdef KHICAS
5440 #ifdef NSPIRE_NEWLIB
5441 #define lineh 14
5442 #else
5443 #define lineh 12
5444 #endif
debug_loop(gen & res,GIAC_CONTEXT)5445   void debug_loop(gen &res,GIAC_CONTEXT){
5446     if (!debug_ptr(contextptr)->debug_allowed || (!debug_ptr(contextptr)->sst_mode && !equalposcomp(debug_ptr(contextptr)->sst_at,debug_ptr(contextptr)->current_instruction)) )
5447       return;
5448     // Fill dbgptr->debug_info_ptr and fast_debug_info_ptr
5449     // with debugging infos to be displayed
5450     debug_struct * dbgptr=debug_ptr(contextptr);
5451     vecteur w;
5452     string progs;
5453     // w[0]=function, args,
5454     // w[1]=breakpoints
5455     // w[2] = instruction to eval or program if debugging a prog
5456     // w[3]= evaluation result
5457     // w[4]= current instruction number
5458     // w[5] = watch vector, w[6] = watch values
5459     if (!debug_ptr(contextptr)->args_stack.empty()){
5460       w.push_back(debug_ptr(contextptr)->args_stack.back());
5461       w.push_back(vector_int_2_vecteur(debug_ptr(contextptr)->sst_at,contextptr));
5462     }
5463     else {
5464       w.push_back(undef);
5465       w.push_back(undef);
5466     }
5467     gen w2=(*debug_ptr(contextptr)->fast_debug_info_ptr);
5468     if (w2.type==_VECT && w2._VECTptr->size()>3)
5469       w2=w2[2];
5470     //*logptr(contextptr) << w2 << endl;
5471     w.push_back(w2);
5472     w.push_back(res);
5473     w.push_back(debug_ptr(contextptr)->current_instruction);
5474     vecteur dw=debug_ptr(contextptr)->debug_watch;
5475     if (contextptr && dw.empty()){
5476       // put the last 2 environments
5477       const context * cur=contextptr;
5478       sym_tab::const_iterator it=cur->tabptr->begin(),itend=cur->tabptr->end();
5479       for (;it!=itend;++it){
5480 	dw.push_back(identificateur(it->first));
5481       }
5482       if (cur->previous && cur->previous!=cur->globalcontextptr){
5483 	cur=cur->previous;
5484 	sym_tab::const_iterator it=cur->tabptr->begin(),itend=cur->tabptr->end();
5485 	for (;it!=itend;++it){
5486 	  dw.push_back(identificateur(it->first));
5487 	}
5488       }
5489     }
5490     w.push_back(dw);
5491     os_fill_rect(0,0,LCD_WIDTH_PX,LCD_HEIGHT_PX,_WHITE);
5492     int dispx=0,dispy=12;
5493     // print debugged program instructions from current-2 to current+3
5494     progs="debug "+w[0].print(contextptr)+'\n';
5495     if (w[4].type==_INT_){
5496       vector<string> ws;
5497 #if 1
5498       ws.push_back("");
5499       debug_print(w[2],ws,contextptr);
5500 #else
5501       int l=s.size();
5502       string cur;
5503       for (int i=0;i<l;++i){
5504 	if (s[i]=='\n'){
5505 	  ws.push_back(cur);
5506 	  cur="";
5507 	}
5508 	else cur+=s[i];
5509       }
5510       ws.push_back(cur);
5511 #endif
5512       int m=giacmax(0,w[4].val-2),M=giacmin(w[4].val+3,ws.size()-1);
5513       if (M-m<5)
5514 	M=giacmin(m+5,ws.size()-1);
5515       if (M-m<5)
5516 	m=giacmax(0,M-5);
5517       for (int i=m;i<=M;++i){
5518 	os_draw_string_small(dispx,dispy,(i==w[4].val?_WHITE:_BLACK),(i==w[4].val?_BLACK:_WHITE),(print_INT_(i)+":"+ws[i]).c_str());
5519 	//mPrintXY(dispx,dispy,(print_INT_(i)+":"+ws[i]).c_str(),(i==w[4].val?TEXT_MODE_INVERT:TEXT_MODE_TRANSPARENT_BACKGROUND),TEXT_COLOR_BLACK);
5520 	dispy+=lineh;
5521 	dispx=0;
5522 	// progs += print_INT_(i)+((i==w[4].val)?" => ":"    ")+ws[i]+'\n';
5523       }
5524     }
5525     else {
5526       string s=w[2].print(contextptr);
5527       progs += "\nprg: "+s+" # "+w[4].print(contextptr);
5528     }
5529     os_draw_string_small_(dispx,dispy,"----------------");
5530     dispx=0;
5531     dispy += lineh-3;
5532     // progs += "======\n";
5533     // evaluate watch with debug_ptr(contextptr)->debug_allowed=false
5534     debug_ptr(contextptr)->debug_allowed=false;
5535     string evals,breaks;
5536     iterateur it=dw.begin(),itend=dw.end();
5537     int nvars=itend-it;
5538     bool fewvars=nvars<7;
5539     for (int nv=0;it!=itend;++nv,++it){
5540       evals += it->print(contextptr)+"=";
5541       gen tmp=protecteval(*it,1,contextptr);
5542       string s=tmp.print(contextptr);
5543       if (!fewvars && s.size()>37)
5544 	s=s.substr(0,35)+"...";
5545       evals += s+",";
5546       if (fewvars || (nv % 2)==1 || nv==nvars-1){
5547 	os_draw_string_small_(dispx,dispy,evals.c_str());
5548 	dispy+=lineh;
5549 	evals="";
5550 	// evals += '\n';
5551       }
5552       else
5553 	evals += "    ";
5554     }
5555     if (evals.size()!=0)
5556       os_draw_string_small_(dispx,dispy,evals.c_str());
5557     dispx=0;
5558     dispy=LCD_HEIGHT_PX-18;
5559     os_draw_string_small_(dispx,dispy,"down: next, right: in, EXE: cont. EXIT: kill");
5560     w.push_back(dw);
5561     debug_ptr(contextptr)->debug_allowed=true;
5562     *dbgptr->debug_info_ptr=w;
5563     while (1){
5564       clear_abort();
5565       int key;
5566       GetKey(&key);
5567       set_abort();
5568       // convert key to i
5569       int i=0;
5570       if (key==KEY_CTRL_DOWN || key==KEY_CTRL_OK){
5571 	i=-1;
5572       }
5573       if (key==KEY_CTRL_RIGHT){
5574 	i=-2;
5575       }
5576       if (key==KEY_CTRL_EXE){
5577 	i=-3;
5578       }
5579       if (key==KEY_CTRL_EXIT){
5580 	i=-4;
5581       }
5582       if (key==KEY_CTRL_F5){
5583 	i=-5;
5584       }
5585       if (key==KEY_CTRL_F6){
5586 	i=-6;
5587       }
5588       if (i>0){
5589 	gen tmp=i;
5590 	if (tmp.is_symb_of_sommet(at_equal))
5591 	  tmp=equaltosto(tmp,contextptr);
5592 	evals=string("eval: ")+tmp.print(contextptr)+" => "+protecteval(tmp,1,contextptr).print(contextptr)+'\n';
5593 	cout << evals ;
5594 	iterateur it=dw.begin(),itend=dw.end();
5595 	for (;it!=itend;++it){
5596 	  evals += it->print(contextptr)+"=";
5597 	  gen tmp=protecteval(*it,1,contextptr);
5598 	  evals += tmp.print(contextptr)+",";
5599 	}
5600       }
5601       // CERR << i << endl;
5602       if (i==-1){
5603 	dbgptr->sst_in_mode=false;
5604 	dbgptr->sst_mode=true;
5605 	os_hide_graph();
5606 	return;
5607       }
5608       if (i==-2){
5609 	dbgptr->sst_in_mode=true;
5610 	dbgptr->sst_mode=true;
5611 	os_hide_graph();
5612 	return;
5613       }
5614       if (i==-3){
5615 	dbgptr->sst_in_mode=false;
5616 	dbgptr->sst_mode=false;
5617 	os_hide_graph();
5618 	return;
5619       }
5620       if (i==-4){
5621 	dbgptr->sst_in_mode=false;
5622 	dbgptr->sst_mode=false;
5623 	//debug_ptr(contextptr)->current_instruction_stack.clear();
5624 	//debug_ptr(contextptr)->sst_at_stack.clear();
5625 	//debug_ptr(contextptr)->args_stack.clear();
5626 	ctrl_c=interrupted=true;
5627 	os_hide_graph();
5628 	return;
5629       }
5630       if (i==-5){
5631 	breaks="break line "+print_INT_(w[4].val)+'\n';
5632 	_breakpoint(makesequence(w[0][0],w[4]),contextptr);
5633       }
5634       if (i==-6){
5635 	breaks="remove break line "+print_INT_(w[4].val)+'\n';
5636 	_rmbreakpoint(makesequence(w[0][0],w[4]),contextptr);
5637       }
5638     } // end while(1)
5639   }
5640 #else // KHICAS
5641 #if defined EMCC && !defined GIAC_GGB
debug_loop(gen & res,GIAC_CONTEXT)5642   void debug_loop(gen &res,GIAC_CONTEXT){
5643     if (!debug_ptr(contextptr)->debug_allowed || (!debug_ptr(contextptr)->sst_mode && !equalposcomp(debug_ptr(contextptr)->sst_at,debug_ptr(contextptr)->current_instruction)) )
5644       return;
5645     // Fill dbgptr->debug_info_ptr and fast_debug_info_ptr
5646     // with debugging infos to be displayed
5647     debug_struct * dbgptr=debug_ptr(contextptr);
5648     vecteur w;
5649     string progs;
5650     // w[0]=function, args,
5651     // w[1]=breakpoints
5652     // w[2] = instruction to eval or program if debugging a prog
5653     // w[3]= evaluation result
5654     // w[4]= current instruction number
5655     // w[5] = watch vector, w[6] = watch values
5656     if (!debug_ptr(contextptr)->args_stack.empty()){
5657       w.push_back(debug_ptr(contextptr)->args_stack.back());
5658       w.push_back(vector_int_2_vecteur(debug_ptr(contextptr)->sst_at,contextptr));
5659     }
5660     else {
5661       w.push_back(undef);
5662       w.push_back(undef);
5663     }
5664     gen w2=(*debug_ptr(contextptr)->fast_debug_info_ptr);
5665     if (w2.type==_VECT && w2._VECTptr->size()>3)
5666       w2=w2[2];
5667     //*logptr(contextptr) << w2 << '\n';
5668     w.push_back(w2);
5669     w.push_back(res);
5670     w.push_back(debug_ptr(contextptr)->current_instruction);
5671     vecteur dw=debug_ptr(contextptr)->debug_watch;
5672     if (contextptr && dw.empty()){
5673       // put the last 2 environments
5674       const context * cur=contextptr;
5675       sym_tab::const_iterator it=cur->tabptr->begin(),itend=cur->tabptr->end();
5676       for (;it!=itend;++it){
5677 	dw.push_back(identificateur(it->first));
5678       }
5679       if (cur->previous && cur->previous!=cur->globalcontextptr){
5680 	cur=cur->previous;
5681 	sym_tab::const_iterator it=cur->tabptr->begin(),itend=cur->tabptr->end();
5682 	for (;it!=itend;++it){
5683 	  dw.push_back(identificateur(it->first));
5684 	}
5685       }
5686     }
5687     w.push_back(dw);
5688     // print debugged program instructions from current-2 to current+3
5689     progs="debug "+w[0].print(contextptr)+'\n';
5690     if (w[4].type==_INT_){
5691       vector<string> ws;
5692 #if 1
5693       ws.push_back("");
5694       debug_print(w[2],ws,contextptr);
5695 #else
5696       int l=s.size();
5697       string cur;
5698       for (int i=0;i<l;++i){
5699 	if (s[i]=='\n'){
5700 	  ws.push_back(cur);
5701 	  cur="";
5702 	}
5703 	else cur+=s[i];
5704       }
5705       ws.push_back(cur);
5706 #endif
5707       int m=giacmax(0,w[4].val-2),M=giacmin(w[4].val+3,ws.size()-1);
5708       for (int i=m;i<=M;++i){
5709 	progs += print_INT_(i)+((i==w[4].val)?" => ":"    ")+ws[i]+'\n';
5710       }
5711     }
5712     else {
5713       string s=w[2].print(contextptr);
5714       progs += "\nprg: "+s+" # "+w[4].print(contextptr);
5715     }
5716     progs += "======\n";
5717     // evaluate watch with debug_ptr(contextptr)->debug_allowed=false
5718     debug_ptr(contextptr)->debug_allowed=false;
5719     string evals,breaks;
5720     iterateur it=dw.begin(),itend=dw.end();
5721     int nvars=itend-it;
5722     for (int nv=0;it!=itend;++nv,++it){
5723       evals += it->print(contextptr)+"=";
5724       gen tmp=protecteval(*it,1,contextptr);
5725       string s=tmp.print(contextptr);
5726       if (s.size()>100) s=s.substr(0,97)+"...";
5727       evals += s+",";
5728       if (nvars<4 || (nv % 2)==1 || nv==nvars-1)
5729 	evals += '\n';
5730       else
5731 	evals += "    ";
5732     }
5733     w.push_back(dw);
5734     debug_ptr(contextptr)->debug_allowed=true;
5735     *dbgptr->debug_info_ptr=w;
5736     // dbgptr->debug_refresh=false;
5737     // need a way to pass w to EM_ASM like environment and call HTML5 prompt
5738 #if 0
5739     EM_ASM_ARGS({
5740         var msg = Pointer_stringify($0); // Convert message to JS string
5741         alert(msg);                      // Use JS version of alert
5742       }, (progs+evals).c_str());
5743 #else
5744     while (1){
5745       int i=EM_ASM_INT({
5746 	  var msg = Pointer_stringify($0); // Convert message to JS string
5747 	  var tst=prompt(msg,'n');             // Use JS version of alert
5748 	  if (tst==null) return -4;
5749 	  if (tst=='next' || tst=='n' || tst=='sst') return -1;
5750 	  if (tst=='sst_in' || tst=='s' ) return -2;
5751 	  if (tst=='cont' || tst=='c' ) return -3;
5752 	  if (tst=='kill' || tst=='k' ) return -4;
5753 	  if (tst=='break' || tst=='b' ) return -5;
5754 	  if (tst=='delete' || tst=='d' ) return -6;
5755 	  return allocate(intArrayFromString(tst), 'i8', ALLOC_NORMAL);
5756 	}, (progs+breaks+evals+"======\nn: next, s:step in, c:cont, b: break, d:del").c_str());
5757       breaks="";
5758       if (i>0){
5759 	char *ptr=(char *)i;
5760 	gen tmp=gen(ptr,contextptr);
5761 	free(ptr);
5762 	if (tmp.is_symb_of_sommet(at_equal)) tmp=equaltosto(tmp,contextptr);
5763 	evals=(string("eval: ")+ptr)+" => "+protecteval(tmp,1,contextptr).print(contextptr)+'\n';
5764 	CERR << evals ;
5765 	iterateur it=dw.begin(),itend=dw.end();
5766 	for (;it!=itend;++it){
5767 	  evals += it->print(contextptr)+"=";
5768 	  gen tmp=protecteval(*it,1,contextptr);
5769 	  evals += tmp.print(contextptr)+",";
5770 	}
5771       }
5772       // CERR << i << '\n';
5773       if (i==-1){
5774 	dbgptr->sst_in_mode=false;
5775 	dbgptr->sst_mode=true;
5776 	return;
5777       }
5778       if (i==-2){
5779 	dbgptr->sst_in_mode=true;
5780 	dbgptr->sst_mode=true;
5781 	return;
5782       }
5783       if (i==-3){
5784 	dbgptr->sst_in_mode=false;
5785 	dbgptr->sst_mode=false;
5786 	return;
5787       }
5788       if (i==-4){
5789 	if (!contextptr)
5790 	  protection_level=0;
5791 	debug_ptr(contextptr)->debug_mode=false;
5792 	debug_ptr(contextptr)->current_instruction_stack.clear();
5793 	debug_ptr(contextptr)->sst_at_stack.clear();
5794 	debug_ptr(contextptr)->args_stack.clear();
5795 	ctrl_c=interrupted=true;
5796 	return;
5797       }
5798       if (i==-5){
5799 	breaks="break line "+print_INT_(w[4].val)+'\n';
5800 	_breakpoint(makesequence(w[0][0],w[4]),contextptr);
5801       }
5802       if (i==-6){
5803 	breaks="remove break line "+print_INT_(w[4].val)+'\n';
5804 	_rmbreakpoint(makesequence(w[0][0],w[4]),contextptr);
5805       }
5806     } // end while(i>0)
5807 #endif
5808    }
5809 #else // EMCC
5810 
5811 #ifdef GIAC_HAS_STO_38
5812   void aspen_debug_loop(gen & res,GIAC_CONTEXT);
5813 
debug_loop(gen & res,GIAC_CONTEXT)5814   void debug_loop(gen &res,GIAC_CONTEXT){
5815     aspen_debug_loop(res,contextptr);
5816   }
5817 
5818 #else // GIAC_HAS_STO_38
5819 
debug_loop(gen & res,GIAC_CONTEXT)5820   void debug_loop(gen &res,GIAC_CONTEXT){
5821     if (!debug_ptr(contextptr)->debug_allowed || (!debug_ptr(contextptr)->sst_mode && !equalposcomp(debug_ptr(contextptr)->sst_at,debug_ptr(contextptr)->current_instruction)) )
5822       return;
5823     // Detect thread debugging
5824     int thread_debug=thread_eval_status(contextptr);
5825     if (thread_debug>1)
5826       return;
5827     if (thread_debug==1){
5828       // Fill dbgptr->debug_info_ptr and fast_debug_info_ptr
5829       // with debugging infos to be displayed
5830       debug_struct * dbgptr=debug_ptr(contextptr);
5831       vecteur w;
5832       // w[0]=function, args,
5833       // w[1]=breakpoints
5834       // w[2] = instruction to eval or program if debugging a prog
5835       // w[3]= evaluation result
5836       // w[4]= current instruction number
5837       // w[5] = watch vector, w[6] = watch values
5838       if (!debug_ptr(contextptr)->args_stack.empty()){
5839 	w.push_back(debug_ptr(contextptr)->args_stack.back());
5840 	w.push_back(vector_int_2_vecteur(debug_ptr(contextptr)->sst_at,contextptr));
5841       }
5842       else {
5843 	w.push_back(undef);
5844 	w.push_back(undef);
5845       }
5846       w.push_back((*debug_ptr(contextptr)->fast_debug_info_ptr));
5847       w.push_back(res);
5848       w.push_back(debug_ptr(contextptr)->current_instruction);
5849       vecteur dw=debug_ptr(contextptr)->debug_watch;
5850       if (contextptr && dw.empty()){
5851 	// put the last 2 environments
5852 	const context * cur=contextptr;
5853 	sym_tab::const_iterator it=cur->tabptr->begin(),itend=cur->tabptr->end();
5854 	for (;it!=itend;++it){
5855 	  dw.push_back(identificateur(it->first));
5856 	}
5857 	if (cur->previous && cur->previous!=cur->globalcontextptr){
5858 	  cur=cur->previous;
5859 	  sym_tab::const_iterator it=cur->tabptr->begin(),itend=cur->tabptr->end();
5860 	  for (;it!=itend;++it){
5861 	    dw.push_back(identificateur(it->first));
5862 	  }
5863 	}
5864       }
5865       w.push_back(dw);
5866       // evaluate watch with debug_ptr(contextptr)->debug_allowed=false
5867       debug_ptr(contextptr)->debug_allowed=false;
5868       iterateur it=dw.begin(),itend=dw.end();
5869       for (;it!=itend;++it)
5870 	*it=protecteval(*it,1,contextptr);
5871       w.push_back(dw);
5872       debug_ptr(contextptr)->debug_allowed=true;
5873       *dbgptr->debug_info_ptr=w;
5874       dbgptr->debug_refresh=false;
5875       // Switch to level 2, waiting for main
5876       thread_eval_status(2,contextptr);
5877       for (;;){
5878 	// Wait until status is put back by main to level 1
5879 	wait_1ms(10);
5880 	if (thread_eval_status(contextptr)==1){
5881 	  // the wait function of the main thread should put in debug_info_ptr
5882 	  // the next instruction, here we check for sst/sst_in/cont/kill
5883 	  if (dbgptr->fast_debug_info_ptr){
5884 	    gen test=*dbgptr->fast_debug_info_ptr;
5885 	    if (test.type==_SYMB)
5886 	      test=test._SYMBptr->sommet;
5887 	    if (test.type==_FUNC){
5888 	      if (test==at_sst){
5889 		dbgptr->sst_in_mode=false;
5890 		dbgptr->sst_mode=true;
5891 		return;
5892 	      }
5893 	      if (test==at_sst_in){
5894 		dbgptr->sst_in_mode=true;
5895 		dbgptr->sst_mode=true;
5896 		return;
5897 	      }
5898 	      if (test==at_cont){
5899 		dbgptr->sst_in_mode=false;
5900 		dbgptr->sst_mode=false;
5901 		return;
5902 	      }
5903 	      if (test==at_kill){
5904 		_kill(0,contextptr);
5905 		return;
5906 	      }
5907 	    } // end type _FUNC
5908 	    // eval
5909 	    w[2] = *dbgptr->fast_debug_info_ptr;
5910 	    w[3] = *dbgptr->fast_debug_info_ptr = protecteval(w[2],1,contextptr);
5911 	    *dbgptr->debug_info_ptr=w;
5912 	    dbgptr->debug_refresh=true;
5913 	  } // end if (*dbgptr->debug_info_ptr)
5914 	  thread_eval_status(2,contextptr); // Back to level 2
5915 	} // end if (thread_eval_status()==1)
5916       } // end '\n'ess for loop
5917     } // end thread debugging
5918 #if (defined WIN32) || (!defined HAVE_SIGNAL_H_OLD)
5919     *logptr(contextptr) << gettext("Sorry! Debugging requires a true operating system") << '\n';
5920     *logptr(contextptr) << gettext("Please try xcas on Linux or an Unix") << '\n';
5921     return;
5922 #else // WIN32
5923     if (child_id)
5924       return;
5925     vecteur w;
5926     // w[0]=[function + args, breakpoints]
5927     // w[2]= res of last evaluation,
5928     // w[3] = next instruction, w[4]=debug_ptr(contextptr)->current_instruction
5929     // w[5] = watch vector, w[6] = watch values
5930     // evaluate watch with debug_ptr(contextptr)->debug_allowed=false
5931     debug_ptr(contextptr)->debug_allowed=false;
5932     debug_ptr(contextptr)->debug_allowed=true;
5933     if (!debug_ptr(contextptr)->args_stack.empty()){
5934       w.push_back(makevecteur(debug_ptr(contextptr)->args_stack.back(),vector_int_2_vecteur(debug_ptr(contextptr)->sst_at,contextptr)));
5935     }
5936     else
5937       w.push_back(undef);
5938     w.push_back(undef);
5939     w.push_back(res);
5940     w.push_back((*debug_ptr(contextptr)->fast_debug_info_ptr));
5941     (*debug_ptr(contextptr)->fast_debug_info_ptr)=undef;
5942     w.push_back(debug_ptr(contextptr)->current_instruction);
5943     w.push_back(debug_ptr(contextptr)->debug_watch);
5944     w.push_back(undef);
5945     bool in_debug_loop=true;
5946     for (;in_debug_loop;){
5947 #ifndef NO_STDEXCEPT
5948       try {
5949 #endif
5950 	vecteur tmp=gen2vecteur(debug_ptr(contextptr)->debug_watch);
5951 	iterateur it=tmp.begin(),itend=tmp.end();
5952 	for (;it!=itend;++it)
5953 	  *it=it->eval(1,contextptr);
5954 	w[6]=tmp;
5955 #ifndef NO_STDEXCEPT
5956       }
5957       catch (std::runtime_error & error){
5958 	last_evaled_argptr(contextptr)=NULL;
5959 	w[6]=string2gen(error.what(),false);
5960       }
5961 #endif
5962       ofstream child_out(cas_sortie_name().c_str());
5963       gen e(symbolic(at_debug,w));
5964       *logptr(contextptr) << gettext("Archiving ") << e << '\n';
5965       archive(child_out,e,contextptr);
5966       archive(child_out,zero,contextptr);
5967       child_out << "Debugging\n" << '¤' ;
5968       child_out.close();
5969       kill_and_wait_sigusr2();
5970       ifstream child_in(cas_entree_name().c_str());
5971       w[1]= unarchive(child_in,contextptr);
5972       child_in.close();
5973       *logptr(contextptr) << gettext("Click reads ") << w[1] << '\n';
5974       if (w[1].type==_SYMB){
5975 	if (w[1]._SYMBptr->sommet==at_sst){
5976 	  debug_ptr(contextptr)->sst_in_mode=false;
5977 	  debug_ptr(contextptr)->sst_mode=true;
5978 	  return;
5979 	}
5980 	if (w[1]._SYMBptr->sommet==at_sst_in){
5981 	  debug_ptr(contextptr)->sst_in_mode=true;
5982 	  debug_ptr(contextptr)->sst_mode=true;
5983 	  return;
5984 	}
5985 	if (w[1]._SYMBptr->sommet==at_cont){
5986 	  debug_ptr(contextptr)->sst_in_mode=false;
5987 	  debug_ptr(contextptr)->sst_mode=false;
5988 	  return;
5989 	}
5990 	if (w[1]._SYMBptr->sommet==at_kill){
5991 	  _kill(0,contextptr);
5992 	}
5993       }
5994 #ifndef NO_STDEXCEPT
5995       try {
5996 #endif
5997 	w[2] =w[1].eval(1,contextptr);
5998 #ifndef NO_STDEXCEPT
5999       }
6000       catch (std::runtime_error & error ){
6001 	last_evaled_argptr(contextptr)=NULL;
6002 	w[2]=string2gen(error.what(),false);
6003       }
6004 #endif
6005     }
6006 #endif // WIN32
6007   }
6008 #endif // GIAC_HAS_STO_38
6009 #endif // EMCC
6010 #endif // KHICAS
printasbackquote(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)6011   static string printasbackquote(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
6012     return "`"+feuille.print(contextptr)+"`";
6013   }
_backquote(const gen & args,GIAC_CONTEXT)6014   gen _backquote(const gen & args,GIAC_CONTEXT){
6015     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
6016     return args;
6017   }
6018   static const char _backquote_s []="backquote";
6019   static define_unary_function_eval2 (__backquote,&_backquote,_backquote_s,&printasbackquote);
6020   define_unary_function_ptr( at_backquote ,alias_at_backquote ,&__backquote);
6021 
printasdouble_deux_points(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)6022   static string printasdouble_deux_points(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
6023     gen a,b;
6024     check_binary(feuille,a,b);
6025     string s=b.print(contextptr);
6026     if (b.type==_SYMB && b._SYMBptr->sommet!=at_of && b._SYMBptr->sommet.ptr()->printsommet)
6027       s = '('+s+')';
6028     if (b.type==_FUNC && s.size()>2 && s[0]=='\'' && s[s.size()-1]=='\'')
6029       s=s.substr(1,s.size()-2);
6030 #ifdef GIAC_HAS_STO_38
6031     return a.print(contextptr)+"::"+s; // removed final space, otherwise A::B::C adds a _ in prime + " ";
6032 #else
6033     return a.print(contextptr)+"::"+s+" ";
6034 #endif
6035   }
symb_double_deux_points(const gen & args)6036   gen symb_double_deux_points(const gen & args){
6037     return symbolic(at_double_deux_points,args);
6038   }
_double_deux_points(const gen & args,GIAC_CONTEXT)6039   gen _double_deux_points(const gen & args,GIAC_CONTEXT){
6040     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
6041     gen a,b,c;
6042     if (!check_binary(args,a,b))
6043       return a;
6044     if (b==at_index)
6045       return _struct_dot(eval(args,1,contextptr),contextptr);
6046     if (b==at_revlist || b==at_reverse || b==at_sort || b==at_sorted || b==at_append || b==at_prepend || b==at_concat || b==at_extend || b==at_rotate || b==at_shift || b==at_suppress || b==at_clear ){
6047 #if 1
6048 	return _struct_dot(args,contextptr);
6049 #else
6050 	return symbolic(at_struct_dot,args);
6051 #endif
6052     }
6053     if (b.type==_SYMB){
6054       unary_function_ptr c=b._SYMBptr->sommet;
6055       if (c==at_index)
6056 	return _struct_dot(eval(args,1,contextptr),contextptr);
6057       if (c==at_revlist || c==at_reverse || c==at_sort || c==at_sorted || c==at_append || c==at_prepend || c==at_concat || c==at_extend || c==at_rotate || c==at_shift || c==at_suppress || c==at_clear ){
6058 #if 1
6059 	return _struct_dot(args,contextptr);
6060 #else
6061 	gen d=eval(a,eval_level(contextptr),contextptr);
6062 	if (b._SYMBptr->feuille.type==_VECT && b._SYMBptr->feuille.subtype==_SEQ__VECT && b._SYMBptr->feuille._VECTptr->empty())
6063 	  ;
6064 	else
6065 	  d=makesuite(d,b._SYMBptr->feuille);
6066 	d=c(d,contextptr);
6067 	return sto(d,a,contextptr);
6068 #endif
6069       }
6070     }
6071     if (storcl_38 && abs_calc_mode(contextptr)==38 && a.type==_IDNT){
6072       gen value;
6073       if (storcl_38(value,a._IDNTptr->id_name,b.type==_IDNT?b._IDNTptr->id_name:b.print().c_str(),undef,false,contextptr,NULL,false)){
6074 	return value;
6075       }
6076     }
6077 #ifndef RTOS_THREADX
6078 #if !defined BESTA_OS && !defined NSPIRE && !defined FXCG && !defined KHICAS
6079 #ifdef HAVE_LIBPTHREAD
6080     pthread_mutex_lock(&context_list_mutex);
6081 #endif
6082     if (a.type==_INT_ && a.subtype==0 && a.val>=0 && a.val<(int)context_list().size()){
6083       context * ptr = context_list()[a.val];
6084 #ifdef HAVE_LIBPTHREAD
6085       pthread_mutex_unlock(&context_list_mutex);
6086 #endif
6087       return eval(b,1,ptr);
6088     }
6089     if (context_names){
6090       map<string,context *>::iterator nt=context_names->find(a.print(contextptr)),ntend=context_names->end();
6091       if (nt!=ntend){
6092 	context * ptr = nt->second;
6093 #ifdef HAVE_LIBPTHREAD
6094 	pthread_mutex_unlock(&context_list_mutex);
6095 #endif
6096 	return eval(b,1,ptr);
6097       }
6098     }
6099 #ifdef HAVE_LIBPTHREAD
6100       pthread_mutex_unlock(&context_list_mutex);
6101 #endif
6102 #endif // RTOS
6103 #endif
6104     c=b;
6105     if (b.is_symb_of_sommet(at_of))
6106       c=b._SYMBptr->feuille[0];
6107     string cs=c.print(contextptr);
6108     /* // following code not used since qualified names after export
6109        // make b a symbolic not just the function name
6110     int l=cs.size(),j=0;
6111     for (;j<l-1;++j){
6112       if (cs[j]==':' && cs[j+1]==':')
6113 	break;
6114     }
6115     if (j==l-1)
6116     */
6117     cs=a.print(contextptr)+"::"+cs;
6118     std::pair<charptr_gen *,charptr_gen *> p= equal_range(builtin_lexer_functions_begin(),builtin_lexer_functions_end(),std::pair<const char *,gen>(cs.c_str(),0),tri);
6119     if (p.first!=p.second && p.first!=builtin_lexer_functions_end()){
6120       c=p.first->second;
6121       if (b.is_symb_of_sommet(at_of))
6122 	return c(b._SYMBptr->feuille[1],contextptr);
6123       else
6124 	return c;
6125     }
6126     map_charptr_gen::const_iterator it=lexer_functions().find(cs.c_str());
6127     if (it!=lexer_functions().end()){
6128       c=it->second;
6129       if (b.is_symb_of_sommet(at_of))
6130 	return c(b._SYMBptr->feuille[1],contextptr);
6131       else
6132 	return c;
6133     }
6134     if (b.type==_FUNC) // ? should be != _IDNT
6135       return b;
6136     if (b.type==_SYMB)
6137       return b.eval(eval_level(contextptr),contextptr);
6138     gen aa=a.eval(1,contextptr);
6139     if (aa.type==_VECT)
6140       return find_in_folder(*aa._VECTptr,b);
6141     return symb_double_deux_points(args);
6142   }
6143   static const char _double_deux_points_s []="double_deux_points";
6144   static define_unary_function_eval2_index(91,__double_deux_points,&_double_deux_points,_double_deux_points_s,&printasdouble_deux_points);
6145   define_unary_function_ptr5( at_double_deux_points ,alias_at_double_deux_points,&__double_deux_points,_QUOTE_ARGUMENTS,0);
6146 
is_binary(const gen & args)6147   bool is_binary(const gen & args){
6148     return (args.type==_VECT) && (args._VECTptr->size()==2) ;
6149   }
6150 
check_binary(const gen & args,gen & a,gen & b)6151   bool check_binary(const gen & args,gen & a,gen & b){
6152     if ( (args.type!=_VECT) || (args._VECTptr->size()!=2) ){
6153       a=gensizeerr(gettext("check_binary"));
6154       b=a;
6155       return false;
6156     }
6157     a=args._VECTptr->front();
6158     b=args._VECTptr->back();
6159     return true;
6160   }
6161 
maple2mupad(const gen & args,int in_maple_mode,int out_maple_mode,GIAC_CONTEXT)6162   static bool maple2mupad(const gen & args,int in_maple_mode,int out_maple_mode,GIAC_CONTEXT){
6163 #if defined NSPIRE || defined FXCG || defined GIAC_HAS_STO_38
6164     return false;
6165 #else
6166     if (is_undef(check_secure()))
6167       return false;
6168     gen a,b;
6169     if (!check_binary(args,a,b))
6170       return false;
6171     string as,bs;
6172     if (a.type==_IDNT)
6173       as=a._IDNTptr->name();
6174     if (a.type==_STRNG)
6175       as=*a._STRNGptr;
6176     if (b.type==_IDNT)
6177       bs=b._IDNTptr->name();
6178     if (b.type==_STRNG)
6179       bs=*b._STRNGptr;
6180     int save_maple_mode=xcas_mode(contextptr);
6181     xcas_mode(contextptr)=in_maple_mode;
6182     ifstream infile(as.c_str());
6183     vecteur v;
6184 #ifndef NO_STDEXCEPT
6185     try {
6186 #endif
6187       readargs_from_stream(infile,v,contextptr);
6188 #ifndef NO_STDEXCEPT
6189     }
6190     catch (std::runtime_error &  ){
6191       last_evaled_argptr(contextptr)=NULL;
6192       xcas_mode(contextptr)=save_maple_mode;
6193       return false;
6194     }
6195 #endif
6196     xcas_mode(contextptr)=out_maple_mode;
6197     ofstream outfile(bs.c_str());
6198     const_iterateur it=v.begin(),itend=v.end();
6199     for (;it!=itend;++it)
6200       outfile << *it << '\n';
6201     xcas_mode(contextptr)=save_maple_mode;
6202     return true;
6203 #endif
6204   }
6205 
_maple2mupad(const gen & args,GIAC_CONTEXT)6206   gen _maple2mupad(const gen & args,GIAC_CONTEXT){
6207     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
6208     return maple2mupad(args,1,2,contextptr);
6209   }
6210   static const char _maple2mupad_s []="maple2mupad";
6211   static define_unary_function_eval_quoted (__maple2mupad,&_maple2mupad,_maple2mupad_s);
6212   define_unary_function_ptr5( at_maple2mupad ,alias_at_maple2mupad,&__maple2mupad,_QUOTE_ARGUMENTS,true);
6213 
_maple2xcas(const gen & args,GIAC_CONTEXT)6214   gen _maple2xcas(const gen & args,GIAC_CONTEXT){
6215     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
6216     return maple2mupad(args,1,0,contextptr);
6217   }
6218   static const char _maple2xcas_s []="maple2xcas";
6219   static define_unary_function_eval_quoted (__maple2xcas,&_maple2xcas,_maple2xcas_s);
6220   define_unary_function_ptr5( at_maple2xcas ,alias_at_maple2xcas,&__maple2xcas,_QUOTE_ARGUMENTS,true);
6221 
_mupad2maple(const gen & args,GIAC_CONTEXT)6222   gen _mupad2maple(const gen & args,GIAC_CONTEXT){
6223     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
6224     return maple2mupad(args,2,1,contextptr);
6225   }
6226   static const char _mupad2maple_s []="mupad2maple";
6227   static define_unary_function_eval_quoted (__mupad2maple,&_mupad2maple,_mupad2maple_s);
6228   define_unary_function_ptr5( at_mupad2maple ,alias_at_mupad2maple,&__mupad2maple,_QUOTE_ARGUMENTS,true);
6229 
_mupad2xcas(const gen & args,GIAC_CONTEXT)6230   gen _mupad2xcas(const gen & args,GIAC_CONTEXT){
6231     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
6232     return maple2mupad(args,2,0,contextptr);
6233   }
6234   static const char _mupad2xcas_s []="mupad2xcas";
6235   static define_unary_function_eval_quoted (__mupad2xcas,&_mupad2xcas,_mupad2xcas_s);
6236   define_unary_function_ptr5( at_mupad2xcas ,alias_at_mupad2xcas,&__mupad2xcas,_QUOTE_ARGUMENTS,true);
6237 
6238   // py==0 Xcas, py==1 Python-like, py==2 JS-like
python_xcas(const gen & args,int py,GIAC_CONTEXT)6239   gen python_xcas(const gen & args,int py,GIAC_CONTEXT){
6240     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
6241     // parse in current mode and print in python mode
6242     gen g(eval(args,1,contextptr));
6243     int p=python_compat(contextptr);
6244     if (g.type==_STRNG){
6245       if (py==0)
6246 	return string2gen(python2xcas(*g._STRNGptr,contextptr),false);
6247       g=gen(*g._STRNGptr,contextptr);
6248     }
6249     python_compat(py==2?0:1,contextptr);
6250     string s(g.print(contextptr));
6251     python_compat(p,contextptr);
6252     if (py==0)
6253       return string2gen(python2xcas(s,contextptr),false);
6254     if (py==2){
6255       // TODO add function, replace := by =, local by var, -> by nothing
6256       s=args.print()+": function"+s;
6257     }
6258     g=string2gen(s,false);
6259     return g;
6260   }
6261 
_python(const gen & args,GIAC_CONTEXT)6262   gen _python(const gen & args,GIAC_CONTEXT){
6263     return python_xcas(args,1,contextptr);
6264   }
6265   static const char _python_s []="python";
6266   static define_unary_function_eval_quoted (__python,&_python,_python_s);
6267   define_unary_function_ptr5( at_python ,alias_at_python,&__python,_QUOTE_ARGUMENTS,true);
6268 
_xcas(const gen & args,GIAC_CONTEXT)6269   gen _xcas(const gen & args,GIAC_CONTEXT){
6270     return python_xcas(args,0,contextptr);
6271   }
6272   static const char _xcas_s []="xcas";
6273   static define_unary_function_eval_quoted (__xcas,&_xcas,_xcas_s);
6274   define_unary_function_ptr5( at_xcas ,alias_at_xcas,&__xcas,_QUOTE_ARGUMENTS,true);
6275 
_javascript(const gen & args,GIAC_CONTEXT)6276   gen _javascript(const gen & args,GIAC_CONTEXT){
6277     return python_xcas(args,2,contextptr);
6278   }
6279   static const char _javascript_s []="javascript";
6280   static define_unary_function_eval_quoted (__javascript,&_javascript,_javascript_s);
6281   define_unary_function_ptr5( at_javascript ,alias_at_javascript,&__javascript,_QUOTE_ARGUMENTS,true);
6282 
printasvirgule(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)6283   static string printasvirgule(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
6284     if ( (feuille.type!=_VECT) || (feuille._VECTptr->size()!=2) )
6285       return string(sommetstr)+('('+feuille.print(contextptr)+')');
6286     return feuille._VECTptr->front().print(contextptr)+','+feuille._VECTptr->back().print(contextptr);
6287   }
_virgule(const gen & args,GIAC_CONTEXT)6288   gen _virgule(const gen & args,GIAC_CONTEXT){
6289     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
6290     if (args.type!=_VECT)
6291       return args;
6292     const_iterateur it=args._VECTptr->begin(),itend=args._VECTptr->end();
6293     if (itend-it<2)
6294       return args;
6295     gen res=makesuite(*it,*(it+1));
6296     ++it;
6297     ++it;
6298     for (;it!=itend;++it)
6299       res=makesuite(res,*it);
6300     return res;
6301   }
6302   static const char _virgule_s []="virgule";
6303   static define_unary_function_eval2 (__virgule,&_virgule,_virgule_s,&printasvirgule);
6304   define_unary_function_ptr( at_virgule ,alias_at_virgule ,&__virgule);
6305 
_pwd(const gen & args,GIAC_CONTEXT)6306   gen _pwd(const gen & args,GIAC_CONTEXT){
6307     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
6308 #ifndef HAVE_NO_CWD
6309     char * buffer=getcwd(0,0);
6310     if (buffer){
6311       string s(buffer);
6312 #ifndef HAVE_LIBGC
6313       free(buffer);
6314 #endif
6315       return string2gen(s,false);
6316     }
6317 #endif
6318     return gensizeerr(contextptr);
6319   }
6320   static const char _pwd_s []="pwd";
6321   static define_unary_function_eval (__pwd,&_pwd,_pwd_s);
6322   define_unary_function_ptr5( at_pwd ,alias_at_pwd,&__pwd,0,true);
6323 
_cd(const gen & args,GIAC_CONTEXT)6324   gen _cd(const gen & args,GIAC_CONTEXT){
6325     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
6326     gen tmp=check_secure();
6327     if (is_undef(tmp)) return tmp;
6328     if (args.type!=_STRNG)
6329       return gentypeerr(contextptr);
6330     int res;
6331     string s(*args._STRNGptr);
6332     string ss(*_pwd(zero,contextptr)._STRNGptr+'/'),current;
6333     int l=int(s.size());
6334     for (int i=0;i<=l;i++){
6335       if ( (i==l) || (s[i]=='/') ){
6336 	if (i){
6337 	  if (current==".."){
6338 	    int t=int(ss.size())-2;
6339 	    for (;t>0;--t){
6340 	      if (ss[t]=='/')
6341 		break;
6342 	    }
6343 	    if (t)
6344 	      ss=ss.substr(0,t+1);
6345 	    else
6346 	      ss="/";
6347 	  }
6348 	  else { // not ..
6349 	    if (current[0]=='~'){
6350 	      if (current.size()==1){ // uid user directory
6351 		ss = home_directory();
6352 	      }
6353 	      else { // other user directory
6354 		current=current.substr(1,current.size()-1);
6355 #if !defined HAVE_NO_PWD_H && !defined NSPIRE_NEWLIB && !defined KHICAS
6356 		passwd * p=getpwnam(current.c_str());
6357 		if (!p)
6358 		  return gensizeerr(gettext("No such user ")+current);
6359 		ss = p->pw_dir ;
6360 		ss +='/';
6361 #else
6362 		ss = "/";
6363 #endif
6364 	      }
6365 	    }
6366 	    else
6367 	      ss+=current+"/";
6368 	  } // end .. detection
6369 	}
6370 	else // i==0 / means absolute path
6371 	  ss="/";
6372 	current="";
6373       } // end / detection
6374       else {
6375 	if (s[i]>' ')
6376 	  current += s[i];
6377       }
6378     } // end for
6379 #ifndef HAVE_NO_CWD
6380     res=chdir(ss.c_str());
6381 #else
6382     res=-1;
6383 #endif
6384     if (res)
6385       return gensizeerr(contextptr);
6386     gen g=symbolic(at_cd,_pwd(zero,contextptr));
6387 #ifdef HAVE_SIGNAL_H_OLD
6388     if (!child_id)
6389       _signal(symb_quote(g),contextptr);
6390 #endif
6391     // *logptr(contextptr) << g << '\n';
6392     return g;
6393   }
6394   static const char _cd_s []="cd";
6395   static define_unary_function_eval (__cd,&_cd,_cd_s);
6396   define_unary_function_ptr5( at_cd ,alias_at_cd,&__cd,0,true);
6397 
_scientific_format(const gen & g,GIAC_CONTEXT)6398   gen _scientific_format(const gen & g,GIAC_CONTEXT){
6399     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6400 #ifndef KHICAS
6401     gen tmp=check_secure();
6402     if (is_undef(tmp)) return tmp;
6403 #endif
6404     gen args(g);
6405     if (g.type==_DOUBLE_)
6406       args=int(g._DOUBLE_val);
6407     if (args.type!=_INT_)
6408       return scientific_format(contextptr);
6409     scientific_format(args.val,contextptr);
6410     return args;
6411   }
6412   static const char _scientific_format_s []="scientific_format";
6413   static define_unary_function_eval2 (__scientific_format,&_scientific_format,_scientific_format_s,&printasDigits);
6414   define_unary_function_ptr( at_scientific_format ,alias_at_scientific_format ,&__scientific_format);
6415 
_integer_format(const gen & g,GIAC_CONTEXT)6416   gen _integer_format(const gen & g,GIAC_CONTEXT){
6417     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6418 #ifndef KHICAS
6419     gen tmp=check_secure(); if (is_undef(tmp)) return tmp;
6420 #endif
6421     gen args(g);
6422     if (g.type==_DOUBLE_)
6423       args=int(g._DOUBLE_val);
6424     if (args.type!=_INT_)
6425       return integer_format(contextptr);
6426     integer_format(args.val,contextptr);
6427     return args;
6428   }
6429   static const char _integer_format_s []="integer_format";
6430   static define_unary_function_eval2 (__integer_format,&_integer_format,_integer_format_s,&printasDigits);
6431   define_unary_function_ptr5( at_integer_format ,alias_at_integer_format,&__integer_format,0,true);
6432 
6433   // 0: xcas, 1: maple, 2: mupad, 3: ti, 256:xcas/python
_xcas_mode(const gen & g,GIAC_CONTEXT)6434   gen _xcas_mode(const gen & g,GIAC_CONTEXT){
6435     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6436     gen args(g);
6437     if (g.type==_DOUBLE_)
6438       args=int(g._DOUBLE_val);
6439     if (args.type!=_INT_)
6440       return xcas_mode(contextptr);
6441     xcas_mode(contextptr)=args.val & 0xff;
6442     python_compat(args.val/256,contextptr);
6443     return string2gen(gettext("Warning: some commands like subs might change arguments order"),false);
6444   }
6445   static const char _xcas_mode_s []="xcas_mode";
6446   static define_unary_function_eval (__xcas_mode,&_xcas_mode,_xcas_mode_s);
6447   define_unary_function_ptr5( at_xcas_mode ,alias_at_xcas_mode,&__xcas_mode,0,true);
6448   static const char _maple_mode_s []="maple_mode";
6449   static define_unary_function_eval (__maple_mode,&_xcas_mode,_maple_mode_s);
6450   define_unary_function_ptr5( at_maple_mode ,alias_at_maple_mode,&__maple_mode,0,true);
_python_compat(const gen & g,GIAC_CONTEXT)6451   gen _python_compat(const gen & g,GIAC_CONTEXT){
6452     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6453     gen args(g);
6454     if (g.type==_DOUBLE_)
6455       args=int(g._DOUBLE_val);
6456     if (args.type!=_INT_)
6457       return python_compat(contextptr);
6458     int p=python_compat(contextptr);
6459     python_compat(args.val,contextptr) ;
6460     return p;
6461   }
6462   static const char _python_compat_s []="python_compat";
6463   static define_unary_function_eval (__python_compat,&_python_compat,_python_compat_s);
6464   define_unary_function_ptr5( at_python_compat ,alias_at_python_compat,&__python_compat,0,true);
6465 
giac_eval_level(const gen & g,GIAC_CONTEXT)6466   gen giac_eval_level(const gen & g,GIAC_CONTEXT){
6467     gen args(g);
6468     if (g.type==_DOUBLE_)
6469       args=int(g._DOUBLE_val);
6470     if (args.type!=_INT_)
6471       return eval_level(contextptr);
6472     eval_level(contextptr)=args.val;
6473     DEFAULT_EVAL_LEVEL=args.val;
6474     return args;
6475   }
6476   static const char _eval_level_s []="eval_level";
6477   static define_unary_function_eval2 (__eval_level,&giac_eval_level,_eval_level_s,&printasDigits);
6478   define_unary_function_ptr5( at_eval_level ,alias_at_eval_level,&__eval_level,0,true);
6479 
_prog_eval_level(const gen & g,GIAC_CONTEXT)6480   gen _prog_eval_level(const gen & g,GIAC_CONTEXT){
6481     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6482     gen args(g);
6483     if (g.type==_DOUBLE_)
6484       args=int(g._DOUBLE_val);
6485     if (args.type!=_INT_)
6486       return prog_eval_level(contextptr);
6487     prog_eval_level_val(contextptr)=args.val;
6488     return args;
6489   }
6490   static const char _prog_eval_level_s []="prog_eval_level";
6491   static define_unary_function_eval2 (__prog_eval_level,&_prog_eval_level,_prog_eval_level_s,&printasDigits);
6492   define_unary_function_ptr5( at_prog_eval_level ,alias_at_prog_eval_level,&__prog_eval_level,0,true);
6493 
_with_sqrt(const gen & g,GIAC_CONTEXT)6494   gen _with_sqrt(const gen & g,GIAC_CONTEXT){
6495     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6496     gen args(g);
6497     if (g.type==_DOUBLE_)
6498       args=int(g._DOUBLE_val);
6499     if (args.type!=_INT_)
6500       return withsqrt(contextptr);
6501     withsqrt(contextptr)=(args.val)!=0;
6502     return args;
6503   }
6504   static const char _with_sqrt_s []="with_sqrt";
6505   static define_unary_function_eval2 (__with_sqrt,&_with_sqrt,_with_sqrt_s,&printasDigits);
6506   define_unary_function_ptr5( at_with_sqrt ,alias_at_with_sqrt,&__with_sqrt,0,true);
6507 
_all_trig_solutions(const gen & g,GIAC_CONTEXT)6508   gen _all_trig_solutions(const gen & g,GIAC_CONTEXT){
6509     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6510     gen args(g);
6511     if (g.type==_DOUBLE_)
6512       args=int(g._DOUBLE_val);
6513     if (args.type!=_INT_)
6514       return all_trig_sol(contextptr);
6515     all_trig_sol((args.val)!=0,contextptr);
6516     parent_cas_setup(contextptr);
6517     return args;
6518   }
6519   static const char _all_trig_solutions_s []="all_trig_solutions";
6520   static define_unary_function_eval2 (__all_trig_solutions,&_all_trig_solutions,_all_trig_solutions_s,&printasDigits);
6521   define_unary_function_ptr( at_all_trig_solutions ,alias_at_all_trig_solutions ,&__all_trig_solutions);
6522 
_increasing_power(const gen & g,GIAC_CONTEXT)6523   gen _increasing_power(const gen & g,GIAC_CONTEXT){
6524     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6525     gen args(g);
6526     if (g.type==_DOUBLE_)
6527       args=int(g._DOUBLE_val);
6528     if (args.type!=_INT_)
6529       return increasing_power(contextptr);
6530     increasing_power((args.val)!=0,contextptr);
6531     parent_cas_setup(contextptr);
6532     return args;
6533   }
6534   static const char _increasing_power_s []="increasing_power";
6535   static define_unary_function_eval2 (__increasing_power,&_increasing_power,_increasing_power_s,&printasDigits);
6536   define_unary_function_ptr( at_increasing_power ,alias_at_increasing_power ,&__increasing_power);
6537 
_ntl_on(const gen & g,GIAC_CONTEXT)6538   gen _ntl_on(const gen & g,GIAC_CONTEXT){
6539     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6540     gen args(g);
6541     if (g.type==_DOUBLE_)
6542       args=int(g._DOUBLE_val);
6543     if (args.type!=_INT_)
6544       return ntl_on(contextptr);
6545     ntl_on((args.val)!=0,contextptr);
6546     ntl_on((args.val)!=0,context0); // Current factorization routines do not have access to the context
6547     return args;
6548   }
6549   static const char _ntl_on_s []="ntl_on";
6550   static define_unary_function_eval2 (__ntl_on,&_ntl_on,_ntl_on_s,&printasDigits);
6551   define_unary_function_ptr( at_ntl_on ,alias_at_ntl_on ,&__ntl_on);
6552 
_complex_mode(const gen & g,GIAC_CONTEXT)6553   gen _complex_mode(const gen & g,GIAC_CONTEXT){
6554     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6555     gen args(g);
6556     if (g.type==_DOUBLE_)
6557       args=int(g._DOUBLE_val);
6558     if (args.type!=_INT_)
6559       return complex_mode(contextptr);
6560     complex_mode((args.val)!=0,contextptr);
6561     parent_cas_setup(contextptr);
6562     return args;
6563   }
6564   static const char _complex_mode_s []="complex_mode";
6565   static define_unary_function_eval2 (__complex_mode,&_complex_mode,_complex_mode_s,&printasDigits);
6566   define_unary_function_ptr( at_complex_mode ,alias_at_complex_mode ,&__complex_mode);
6567 
_keep_algext(const gen & g,GIAC_CONTEXT)6568   gen _keep_algext(const gen & g,GIAC_CONTEXT){
6569     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6570     gen args(g);
6571     if (g.type==_DOUBLE_)
6572       args=int(g._DOUBLE_val);
6573     if (args.type!=_INT_)
6574       return keep_algext(contextptr);
6575     keep_algext((args.val)!=0,contextptr);
6576     parent_cas_setup(contextptr);
6577     return args;
6578   }
6579   static const char _keep_algext_s []="keep_algext";
6580   static define_unary_function_eval2 (__keep_algext,&_keep_algext,_keep_algext_s,&printasDigits);
6581   define_unary_function_ptr( at_keep_algext ,alias_at_keep_algext ,&__keep_algext);
6582 
_angle_radian(const gen & g,GIAC_CONTEXT)6583   gen _angle_radian(const gen & g,GIAC_CONTEXT){
6584     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6585     gen args(g);
6586     if (g.type==_DOUBLE_)
6587       args=int(g._DOUBLE_val);
6588     //grad
6589     //since this is a programming command, not sure what you want done here exactly..., will return 1 for radian, 0 for degree, and 2 for grads to match prior behavior
6590     if (args.type!=_INT_)
6591     {
6592       if(angle_radian(contextptr))
6593         return 1;
6594       else if(angle_degree(contextptr))
6595         return 0;
6596       else
6597         return 2;
6598     }
6599     //anything but 0 or 2 will result in radians...
6600     int val = args.val;
6601     if(val == 0)
6602       angle_mode(1, contextptr); //set to degrees if 0
6603     else if(val==2)
6604       angle_mode(2, contextptr); //set to grads if 2
6605     else
6606       angle_mode(0, contextptr); //set to radians for anything but those two
6607 
6608     parent_cas_setup(contextptr);
6609     return args;
6610   }
6611   static const char _angle_radian_s []="angle_radian";
6612   static define_unary_function_eval2 (__angle_radian,&_angle_radian,_angle_radian_s,&printasDigits);
6613   define_unary_function_ptr( at_angle_radian ,alias_at_angle_radian ,&__angle_radian);
6614 
_epsilon(const gen & arg,GIAC_CONTEXT)6615   gen _epsilon(const gen & arg,GIAC_CONTEXT){
6616     if ( arg.type==_STRNG &&  arg.subtype==-1) return  arg;
6617     gen args=evalf_double(arg,0,contextptr);
6618     if (args.type!=_DOUBLE_)
6619       return epsilon(contextptr);
6620     epsilon(fabs(args._DOUBLE_val),contextptr);
6621     parent_cas_setup(contextptr);
6622     return args;
6623   }
6624   static const char _epsilon_s []="epsilon";
6625   static define_unary_function_eval2 (__epsilon,&_epsilon,_epsilon_s,&printasDigits);
6626   define_unary_function_ptr( at_epsilon ,alias_at_epsilon ,&__epsilon);
6627 
_proba_epsilon(const gen & arg,GIAC_CONTEXT)6628   gen _proba_epsilon(const gen & arg,GIAC_CONTEXT){
6629     if ( arg.type==_STRNG &&  arg.subtype==-1) return  arg;
6630     gen args=evalf_double(arg,0,contextptr);
6631     if (args.type!=_DOUBLE_)
6632       return proba_epsilon(contextptr);
6633     proba_epsilon(contextptr)=fabs(args._DOUBLE_val);
6634     parent_cas_setup(contextptr);
6635     return args;
6636   }
6637   static const char _proba_epsilon_s []="proba_epsilon";
6638   static define_unary_function_eval2 (__proba_epsilon,&_proba_epsilon,_proba_epsilon_s,&printasDigits);
6639   define_unary_function_ptr( at_proba_epsilon ,alias_at_proba_epsilon ,&__proba_epsilon);
6640 
_complex_variables(const gen & g,GIAC_CONTEXT)6641   gen _complex_variables(const gen & g,GIAC_CONTEXT){
6642     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6643     gen args(g);
6644     if (g.type==_DOUBLE_)
6645       args=int(g._DOUBLE_val);
6646     if (args.type!=_INT_)
6647       return complex_variables(contextptr);
6648     complex_variables((args.val)!=0,contextptr);
6649     parent_cas_setup(contextptr);
6650     return args;
6651   }
6652   static const char _complex_variables_s []="complex_variables";
6653   static define_unary_function_eval2 (__complex_variables,&_complex_variables,_complex_variables_s,&printasDigits);
6654   define_unary_function_ptr( at_complex_variables ,alias_at_complex_variables ,&__complex_variables);
6655 
_approx_mode(const gen & g,GIAC_CONTEXT)6656   gen _approx_mode(const gen & g,GIAC_CONTEXT){
6657     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6658     gen args(g);
6659     if (g.type==_DOUBLE_)
6660       args=int(g._DOUBLE_val);
6661     if (args.type!=_INT_)
6662       return approx_mode(contextptr);
6663     approx_mode((args.val)!=0,contextptr);
6664     parent_cas_setup(contextptr);
6665     return args;
6666   }
6667   static const char _approx_mode_s []="approx_mode";
6668   static define_unary_function_eval2 (__approx_mode,&_approx_mode,_approx_mode_s,&printasDigits);
6669   define_unary_function_ptr( at_approx_mode ,alias_at_approx_mode ,&__approx_mode);
6670 
_threads(const gen & g,GIAC_CONTEXT)6671   gen _threads(const gen & g,GIAC_CONTEXT){
6672     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6673     gen args(g);
6674     if (g.type==_DOUBLE_)
6675       args=int(g._DOUBLE_val);
6676     if (args.type!=_INT_)
6677       return threads;
6678     threads=giacmax(absint(args.val),1);
6679     parent_cas_setup(contextptr);
6680     return args;
6681   }
6682   static const char _threads_s []="threads";
6683   static define_unary_function_eval2 (__threads,&_threads,_threads_s,&printasDigits);
6684   define_unary_function_ptr( at_threads ,alias_at_threads ,&__threads);
6685 
digits2bits(int n)6686   int digits2bits(int n){
6687 #ifdef OLDGNUWINCE
6688     return (n*33)/10;
6689 #else
6690     return int(std::floor(std::log(10.0)/std::log(2.0)*n))+1;
6691 #endif
6692   }
6693 
bits2digits(int n)6694   int bits2digits(int n){
6695 #ifdef OLDGNUWINCE
6696     return (n*3)/10;
6697 #else
6698     return int(std::floor(std::log(2.0)/std::log(10.0)*n))+1;
6699 #endif
6700   }
6701 
set_decimal_digits(int n,GIAC_CONTEXT)6702   void set_decimal_digits(int n,GIAC_CONTEXT){
6703 #ifdef GNUWINCE
6704     return ;
6705 #else
6706 #ifdef HAVE_LIBMPFR
6707     decimal_digits(contextptr)=giacmax(absint(n),1);
6708 #else
6709     decimal_digits(contextptr)=giacmin(giacmax(absint(n),1),13);
6710 #endif
6711     // deg2rad_g=evalf(cst_pi,1,0)/180;
6712     // rad2deg_g=inv(deg2rad_g);
6713 #endif
6714   }
6715 
cas_setup(const vecteur & v_orig,GIAC_CONTEXT)6716   bool cas_setup(const vecteur & v_orig,GIAC_CONTEXT){
6717     vecteur v(v_orig);
6718     for (size_t i=0;i<v.size();++i){
6719       gen g=v[i];
6720       if (g.type==_VECT && g._VECTptr->size()==2 && g._VECTptr->front().type==_STRNG)
6721 	v[i]=g._VECTptr->back();
6722     }
6723     if (v.size()<7)
6724       return false;
6725     if (logptr(contextptr) && debug_infolevel)
6726       *logptr(contextptr) << gettext("Cas_setup ") << v << char(10) << char(13) ;
6727     if (v[0].type==_INT_)
6728       approx_mode((v[0].val)!=0,contextptr);
6729     else {
6730       v[0]=evalf_double(v[0],1,contextptr);
6731       if (v[0].type==_DOUBLE_)
6732 	approx_mode(v[0]._DOUBLE_val!=0,contextptr);
6733     }
6734     if (v[1].type==_INT_)
6735       complex_variables((v[1].val)!=0,contextptr);
6736     else {
6737       v[1]=evalf_double(v[1],1,contextptr);
6738       if (v[1].type==_DOUBLE_)
6739 	complex_variables(v[1]._DOUBLE_val!=0,contextptr);
6740     }
6741     if (v[2].type==_INT_)
6742       complex_mode((v[2].val)!=0,contextptr);
6743     else {
6744       v[2]=evalf_double(v[2],1,contextptr);
6745       if (v[2].type==_DOUBLE_)
6746 	complex_mode(v[2]._DOUBLE_val!=0,contextptr);
6747     }
6748     if (v[3].type==_INT_)
6749     {
6750       //grad
6751       //since end user sees val !=0 being radians, I have hijacked so 2 will be grad, 0 is deg, and anything else is radians
6752       int val = v[3].val;
6753       if(val == 0)
6754         angle_mode(1, contextptr); //degrees if ==0
6755       else if(val == 2)
6756         angle_mode(2, contextptr); //grad if ==2
6757       else
6758         angle_mode(0, contextptr); //anything else is radians
6759     }
6760     else {
6761       v[3]=evalf_double(v[3],1,contextptr);
6762       if (v[3].type==_DOUBLE_)
6763       {
6764         //grad
6765         //since end user sees val !=0 being radians, I have hijacked so 2 will be grad, 0 is deg, and anything else is radians
6766         int val = int(v[3]._DOUBLE_val);
6767         if(val == 0)
6768           angle_mode(1, contextptr); //degrees if ==0
6769         else if(val == 2)
6770           angle_mode(2, contextptr); //grad if ==2
6771         else
6772           angle_mode(0, contextptr); //anything else is radians
6773       }
6774     }
6775     v[4]=evalf_double(v[4],1,contextptr);
6776     if (v[4].type==_DOUBLE_){
6777       int format=int(v[4]._DOUBLE_val);
6778       scientific_format(format % 16,contextptr);
6779       integer_format(format/16,contextptr);
6780     }
6781     v[5]=evalf_double(v[5],1,contextptr);
6782     if (v[5].type==_DOUBLE_)
6783       epsilon(fabs(v[5]._DOUBLE_val),contextptr);
6784     if (v[5].type==_VECT && v[5]._VECTptr->size()==2 && v[5]._VECTptr->front().type==_DOUBLE_ && v[5]._VECTptr->back().type==_DOUBLE_){
6785       epsilon(fabs(v[5]._VECTptr->front()._DOUBLE_val),contextptr);
6786       proba_epsilon(contextptr)=fabs(v[5]._VECTptr->back()._DOUBLE_val);
6787     }
6788     if (v[6].type==_INT_)
6789       set_decimal_digits(v[6].val,contextptr);
6790     else {
6791       v[6]=evalf_double(v[6],1,contextptr);
6792       if (v[6].type==_DOUBLE_)
6793 	set_decimal_digits(int(v[6]._DOUBLE_val),contextptr);
6794     }
6795     if (v.size()>=8){
6796       if (v[7].type==_VECT){
6797 	vecteur & vv =*v[7]._VECTptr;
6798 	if (vv.size()>=4){
6799 	  threads=std::max(1,int(evalf_double(vv[0],1,contextptr)._DOUBLE_val));
6800 	  MAX_RECURSION_LEVEL=std::max(int(evalf_double(vv[1],1,contextptr)._DOUBLE_val),1);
6801 	  debug_infolevel=std::max(0,int(evalf_double(vv[2],1,contextptr)._DOUBLE_val));
6802 	  DEFAULT_EVAL_LEVEL=std::max(1,int(evalf_double(vv[3],1,contextptr)._DOUBLE_val));
6803 	}
6804       }
6805     }
6806     if (v.size()>=9){
6807       if (v[8].type==_INT_)
6808 	increasing_power(v[8].val!=0,contextptr);
6809       else {
6810 	v[8]=evalf_double(v[8],1,contextptr);
6811 	if (v[8].type==_DOUBLE_)
6812 	  increasing_power(v[8]._DOUBLE_val!=0,contextptr);
6813       }
6814     }
6815     if (v.size()>=10){
6816       if (v[9].type==_INT_)
6817 	withsqrt(v[9].val!=0,contextptr);
6818       else {
6819 	v[9]=evalf_double(v[9],1,contextptr);
6820 	if (v[9].type==_DOUBLE_)
6821 	  withsqrt(v[9]._DOUBLE_val!=0,contextptr);
6822       }
6823     }
6824     if (v.size()>=11){
6825       if (v[10].type==_INT_)
6826 	all_trig_sol(v[10].val!=0,contextptr);
6827       else {
6828 	v[10]=evalf_double(v[10],1,contextptr);
6829 	if (v[10].type==_DOUBLE_)
6830 	  all_trig_sol(v[10]._DOUBLE_val!=0,contextptr);
6831       }
6832     }
6833     if (v.size()>=12){
6834       if (v[11].type==_INT_)
6835 	integer_mode(v[11].val!=0,contextptr);
6836       else {
6837 	v[11]=evalf_double(v[11],1,contextptr);
6838 	if (v[11].type==_DOUBLE_)
6839 	  integer_mode(v[11]._DOUBLE_val!=0,contextptr);
6840       }
6841     }
6842     return true;
6843   }
cas_setup(GIAC_CONTEXT)6844   vecteur cas_setup(GIAC_CONTEXT){
6845     vecteur v;
6846     v.push_back(approx_mode(contextptr));
6847     v.push_back(complex_variables(contextptr));
6848     v.push_back(complex_mode(contextptr));
6849     int an=angle_mode(contextptr);
6850     v.push_back(an==2?2:1-an); //grad //not sure if this will mess anything up on your side bernard, having int instead of bool
6851     v.push_back(scientific_format(contextptr)+16*integer_format(contextptr));
6852     v.push_back(makevecteur(epsilon(contextptr),proba_epsilon(contextptr)));
6853     v.push_back(decimal_digits(contextptr));
6854     v.push_back(makevecteur(threads,MAX_RECURSION_LEVEL,debug_infolevel,DEFAULT_EVAL_LEVEL));
6855     v.push_back(increasing_power(contextptr));
6856     v.push_back(withsqrt(contextptr));
6857     v.push_back(all_trig_sol(contextptr));
6858     v.push_back(integer_mode(contextptr));
6859     return v;
6860   }
_cas_setup(const gen & args,GIAC_CONTEXT)6861   gen _cas_setup(const gen & args,GIAC_CONTEXT){
6862     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
6863     if (args.type!=_VECT){
6864       vecteur v=cas_setup(contextptr);
6865       v[0]=makevecteur(string2gen("~",false),v[0]);
6866       v[1]=makevecteur(string2gen("var C",false),v[1]);
6867       v[2]=makevecteur(string2gen("C",false),v[2]);
6868       v[3]=makevecteur(string2gen("0:deg/1:rad/2:grad",false),v[3]);
6869       v[4]=makevecteur(string2gen("format",false),v[4]);
6870       v[5]=makevecteur(string2gen("[epsilon,proba_epsilon]",false),v[5]);
6871       v[6]=makevecteur(string2gen("digits",false),v[6]);
6872       v[7]=makevecteur(string2gen("[thread,recursion,debug,eval]",false),v[7]);
6873       v[8]=makevecteur(string2gen("increasing power",false),v[8]);
6874       v[9]=makevecteur(string2gen("sqrt",false),v[9]);
6875       v[10]=makevecteur(string2gen("trig. solutions",false),v[10]);
6876       v[11]=makevecteur(string2gen("integer",false),v[11]);
6877       return v;
6878     }
6879     vecteur & w=*args._VECTptr;
6880     if (w.empty())
6881       return cas_setup(contextptr);
6882     if (!cas_setup(w,contextptr))
6883       return gendimerr(contextptr);
6884 #ifdef HAVE_SIGNAL_H_OLD
6885     if (!child_id){
6886       _signal(symbolic(at_quote,symbolic(at_cas_setup,w)),contextptr);
6887     }
6888 #endif
6889     return args;
6890   }
6891   static const char _cas_setup_s []="cas_setup";
6892   static define_unary_function_eval (__cas_setup,&_cas_setup,_cas_setup_s);
6893   define_unary_function_ptr5( at_cas_setup ,alias_at_cas_setup,&__cas_setup,0,true);
6894 
parent_cas_setup(GIAC_CONTEXT)6895   void parent_cas_setup(GIAC_CONTEXT){
6896 #ifdef HAVE_SIGNAL_H_OLD
6897     if (!child_id){
6898       _signal(symbolic(at_quote,symbolic(at_cas_setup,cas_setup(contextptr))),contextptr);
6899     }
6900 #endif
6901   }
6902 
printasDigits(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)6903   string printasDigits(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
6904     if (feuille.type==_VECT && feuille._VECTptr->empty())
6905       return sommetstr;
6906     return sommetstr+(" := "+feuille.print(contextptr));
6907   }
_Digits(const gen & g,GIAC_CONTEXT)6908   gen _Digits(const gen & g,GIAC_CONTEXT){
6909     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
6910     gen args(g);
6911     if (g.type==_DOUBLE_)
6912       args=int(g._DOUBLE_val);
6913     if (args.type!=_INT_)
6914       return decimal_digits(contextptr);
6915     set_decimal_digits(args.val,contextptr);
6916     _cas_setup(cas_setup(contextptr),contextptr);
6917     return decimal_digits(contextptr);
6918   }
6919   static const char _Digits_s []="Digits";
6920   static define_unary_function_eval2 (__Digits,&_Digits,_Digits_s,&printasDigits);
6921   define_unary_function_ptr( at_Digits ,alias_at_Digits ,&__Digits);
6922 
_xport(const gen & args,GIAC_CONTEXT)6923   gen _xport(const gen & args,GIAC_CONTEXT){
6924     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
6925     string libname(gen2string(args));
6926     if (libname.size()>5 && libname.substr(0,5)=="giac_")
6927       libname=libname.substr(5,libname.size()-5);
6928 #ifdef USTL
6929     ustl::map<std::string,std::vector<std::string> >::iterator it=library_functions().find(libname);
6930     if (it==library_functions().end())
6931       return zero;
6932     ustl::sort(it->second.begin(),it->second.end());
6933 #else
6934     std::map<std::string,std::vector<std::string> >::iterator it=library_functions().find(libname);
6935     if (it==library_functions().end())
6936       return zero;
6937     sort(it->second.begin(),it->second.end());
6938 #endif
6939     // Add library function names to the translator
6940     std::vector<std::string>::iterator jt=it->second.begin(),jtend=it->second.end(),kt,ktend;
6941     for (;jt!=jtend;++jt){
6942       string tname=libname+"::"+*jt;
6943       // Find if the name exists in the translator base
6944       it=lexer_translator().find(*jt);
6945       if (it==lexer_translator().end())
6946 	lexer_translator()[*jt]=vector<string>(1,tname);
6947       else { // Name exists, check if tname is in the vector, else push it
6948 	kt=it->second.begin(); ktend=it->second.end();
6949 	for (;kt!=ktend;++kt){
6950 	  if (*kt==tname)
6951 	    break;
6952 	}
6953 	if (kt!=ktend)
6954 	  it->second.erase(kt);
6955 	it->second.push_back(tname);
6956       }
6957     }
6958     return plus_one;
6959   }
_insmod(const gen & args,GIAC_CONTEXT)6960   gen _insmod(const gen & args,GIAC_CONTEXT){
6961     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
6962     if (args.type==_IDNT)
6963       return _insmod(string2gen(args.print(contextptr),false),contextptr);
6964     if (args.type!=_STRNG)
6965       return _xport(args,contextptr);
6966 #ifdef __APPLE__
6967     string suffix=".dylib";
6968 #else
6969     string suffix=".so";
6970 #endif
6971     size_t sl=suffix.size();
6972 #ifdef HAVE_LIBDL
6973     string libname=*args._STRNGptr;
6974     if (libname.empty())
6975       return 0;
6976     // a way to add the current path to the search
6977     if (libname[0]!='/'){
6978       if (libname.size()<3 || libname.substr(0,3)!="lib")
6979 	libname = "libgiac_"+libname;
6980       gen pwd=_pwd(0,contextptr);
6981       if (pwd.type==_STRNG){
6982 	string libname1 = *pwd._STRNGptr+'/'+libname;
6983 	if (libname1.size()<sl || libname1.substr(libname1.size()-sl,sl)!=suffix)
6984 	  libname1 += suffix;
6985 	if (is_file_available(libname1.c_str()))
6986 	  libname=libname1;
6987       }
6988     }
6989 #ifndef WIN32
6990     if (libname.size()<sl || libname.substr(libname.size()-sl,sl)!=suffix)
6991       libname += suffix;
6992 #endif
6993     modules_tab::const_iterator i = giac_modules_tab.find(libname);
6994     if (i!=giac_modules_tab.end())
6995       return 3; // still registered
6996     registered_lexer_functions().clear();
6997     doing_insmod=true;
6998     void * handle = dlopen (libname.c_str(), RTLD_LAZY);
6999     if (!handle) {
7000       setsizeerr (string(dlerror()));
7001     }
7002     // if (debug_infolevel)
7003     //  *logptr(contextptr) << registered_lexer_functions << '\n';
7004     giac_modules_tab[libname]=module_info(registered_lexer_functions(),handle);
7005 #ifdef HAVE_SIGNAL_H_OLD
7006     if (!child_id)
7007       _signal(symb_quote(symbolic(at_insmod,args)),contextptr);
7008     else
7009 #endif
7010       if (debug_infolevel) *logptr(contextptr) << gettext("Parent insmod") <<'\n';
7011     return 1+_xport(args,contextptr);
7012 #else // HAVE_LIBDL
7013     return zero;
7014 #endif // HAVE_LIBDL
7015   }
7016   static const char _insmod_s []="insmod";
7017   static define_unary_function_eval (__insmod,&_insmod,_insmod_s);
7018   define_unary_function_ptr5( at_insmod ,alias_at_insmod,&__insmod,0,true);
7019   // QUOTE_ARGUMENTS ??
7020 
_rmmod(const gen & args,GIAC_CONTEXT)7021   gen _rmmod(const gen & args,GIAC_CONTEXT){
7022     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
7023     if (args.type!=_STRNG)
7024       return gentypeerr(contextptr);
7025 #ifdef HAVE_LIBDL
7026     string libname=*args._STRNGptr;
7027     modules_tab::const_iterator i = giac_modules_tab.find(libname);
7028     if (i==giac_modules_tab.end())
7029       return plus_two; // not registered
7030     dlclose(i->second.handle);
7031     bool res= lexer_function_remove(i->second.registered_names);
7032     giac_modules_tab.erase(libname);
7033 #ifdef HAVE_SIGNAL_H_OLD
7034     if (!child_id)
7035       _signal(symb_quote(symbolic(at_rmmod,args)),contextptr);
7036 #endif
7037     return(res);
7038 #else // HAVE_LIBDL
7039     return zero;
7040 #endif // HAVE_LIBDL
7041   }
7042 
7043   /*
7044   gen _rmmod(const gen & args){
7045   if ( args){
7046     if (args.type==_VECT)
7047       apply(args.type==_STRNG &&  args.subtype==-1{
7048     if (args.type==_VECT)
7049       apply(args)) return  args){
7050     if (args.type==_VECT)
7051       apply(args;
7052     if (args.type==_VECT)
7053       apply(args,rmmod);
7054     rmmod(args);
7055   }
7056   */
7057   static const char _rmmod_s []="rmmod";
7058   static define_unary_function_eval (__rmmod,&_rmmod,_rmmod_s);
7059   define_unary_function_ptr5( at_rmmod ,alias_at_rmmod,&__rmmod,0,true);
7060 
_lsmod(const gen & args,GIAC_CONTEXT)7061   gen _lsmod(const gen & args,GIAC_CONTEXT){
7062     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
7063     vecteur v;
7064 #ifdef HAVE_LIBDL
7065     modules_tab::const_iterator i = giac_modules_tab.begin(),iend=giac_modules_tab.end();
7066     for (;i!=iend;++i)
7067       v.push_back(string2gen(i->first,false));
7068 #endif
7069     return v;
7070   }
7071   static const char _lsmod_s []="lsmod";
7072   static define_unary_function_eval (__lsmod,&_lsmod,_lsmod_s);
7073   define_unary_function_ptr5( at_lsmod ,alias_at_lsmod,&__lsmod,0,true);
7074 
7075   class gen_sort {
7076     gen sorting_function;
7077     const context * contextptr;
7078   public:
operator ()(const gen & a,const gen & b)7079     bool operator () (const gen & a,const gen & b){
7080       gen c=sorting_function(gen(makevecteur(a,b),_SEQ__VECT),contextptr);
7081       if (c.type!=_INT_){
7082 #ifndef NO_STDEXCEPT
7083 	setsizeerr(gettext("Unable to sort ")+c.print(contextptr));
7084 #else
7085 	*logptr(contextptr) << gettext("Unable to sort ") << c << '\n';
7086 #endif
7087 	return true;
7088       }
7089       return !is_zero(c);
7090     }
gen_sort(const gen & f,const context * ptr)7091     gen_sort(const gen & f,const context * ptr): sorting_function(f),contextptr(ptr) {};
gen_sort()7092     gen_sort(): sorting_function(at_inferieur_strict),contextptr(0) {};
7093   };
7094 
7095   /*
7096   gen sorting_function;
7097   bool sort_sort(const gen & a,const gen & b){
7098     gen c=sorting_function(gen(makevecteur(a,b),_SEQ__VECT),0);
7099     if (c.type!=_INT_)
7100       setsizeerr(gettext("Unable to sort ")+c.print(contextptr));
7101     return !is_zero(c);
7102   }
7103   */
7104 
7105   /*
7106   gen negdistrib(const gen & g,GIAC_CONTEXT){
7107     if (!g.is_symb_of_sommet(at_plus))
7108       return -g;
7109     return _plus(-g._SYMBptr->feuille,contextptr);
7110   }
7111   */
7112 
simplifier(const gen & g,GIAC_CONTEXT)7113   gen simplifier(const gen & g,GIAC_CONTEXT){
7114 #if 0 // def NSPIRE
7115     return g;
7116 #endif
7117     if (g.type!=_SYMB || g._SYMBptr->sommet==at_program || g._SYMBptr->sommet==at_pnt || g._SYMBptr->sommet==at_animation || g._SYMBptr->sommet==at_unit || g._SYMBptr->sommet==at_integrate || g._SYMBptr->sommet==at_superieur_strict || g._SYMBptr->sommet==at_superieur_egal || g._SYMBptr->sommet==at_inferieur_strict || g._SYMBptr->sommet==at_inferieur_egal || g._SYMBptr->sommet==at_and || g._SYMBptr->sommet==at_ou || g._SYMBptr->sommet==at_et || g._SYMBptr->sommet==at_not || g._SYMBptr->sommet==at_xor || g._SYMBptr->sommet==at_piecewise
7118 #ifndef FXCG
7119 	|| g._SYMBptr->sommet==at_archive
7120 #endif
7121 	)
7122       return g;
7123     if (is_equal(g))
7124       return apply_to_equal(g,simplifier,contextptr);
7125     if (is_inf(g))
7126       return g;
7127     vecteur v(lvar(g)),w(v);
7128     for (unsigned i=0;i<w.size();++i){
7129       gen & wi=w[i];
7130       if (wi.type==_SYMB){
7131 	gen f =wi._SYMBptr->feuille;
7132 	if (wi.is_symb_of_sommet(at_pow) && f.type==_VECT && f._VECTptr->size()==2 && f._VECTptr->back().type==_FRAC){
7133 	  gen base=f._VECTptr->front();
7134 	  gen d= f._VECTptr->back()._FRACptr->den;
7135 	  if ( (base.type==_INT_ && absint(base.val)>3) || base.type==_ZINT){
7136 	    gen b=evalf_double(base,1,contextptr);
7137 	    if (b.type==_DOUBLE_){
7138 	      double bd=b._DOUBLE_val;
7139 	      bd=std::log(bd);
7140 	      int N=int(bd/std::log(2.0));
7141 	      int ii;
7142 	      for (ii=3;ii<=N;++ii){
7143 		double di=std::exp(bd/ii);
7144 		gen g=exact_double(di,1e-15);
7145 		if (is_integer(g) && pow(g,ii,contextptr)==base){
7146 		  wi=pow(g,ii*f._VECTptr->back(),contextptr);
7147 		  break;
7148 		}
7149 	      }
7150 	      if (ii!=N+1)
7151 		continue;
7152 	    }
7153 	  }
7154 	  if (d.type==_INT_){
7155 	    gen f0=simplifier(f._VECTptr->front(),contextptr);
7156 	    gen z=fast_icontent(f0);
7157 	    gen n= f._VECTptr->back()._FRACptr->num;
7158 	    if (d.val<0){ n=-n; d=-d;}
7159 	    gen zn=pow(z,n,contextptr),a,b,fapprox;
7160 	    bool pos; // pos should be true after next call since zn is > 0
7161 	    zint2simpldoublpos(zn,a,b,pos,d.val,contextptr);
7162 	    if (pos){
7163 	      if (0 && n==1)
7164 		wi=b*pow(fast_divide_by_icontent(f0,z/a),f._VECTptr->back(),contextptr);
7165 	      else { // avoid extracting sqrt(2) out for simplify(exp(i*pi/5));
7166 		if (d*f._VECTptr->back()==1 && has_evalf(f0,fapprox,1,contextptr))
7167 		  wi=b*pow(a*fast_divide_by_icontent(f0,z),inv(d,contextptr),contextptr);
7168 		else
7169 		  wi=b*pow(a,inv(d,contextptr),contextptr)*pow(fast_divide_by_icontent(f0,z),f._VECTptr->back(),contextptr);
7170 	      }
7171 	      continue;
7172 	    }
7173 	  }
7174 	}
7175 	// check added for [] and () otherwise xcas_mode index shift is not taken in account
7176 	if (wi._SYMBptr->sommet==at_at || wi._SYMBptr->sommet==at_of || wi._SYMBptr->sommet==at_Ans)
7177 	  wi=symbolic(wi._SYMBptr->sommet,simplifier(f,contextptr));
7178 	else
7179 	  wi=wi._SYMBptr->sommet(simplifier(f,contextptr),contextptr);
7180       }
7181     }
7182     gen g_(g);
7183     if (v!=w)
7184       g_=subst(g,v,w,false,contextptr);
7185     g_=aplatir_fois_plus(g_);
7186     // distribute neg over +
7187     //vector< gen_op_context > negdistrib_v(1,negdistrib);
7188     //vector<const unary_function_ptr *> neg_v(1,at_neg);
7189     //g_=subst(g_,neg_v,negdistrib_v,false,contextptr);
7190     return liste2symbolique(symbolique2liste(g_,contextptr));
7191   }
_simplifier(const gen & g,GIAC_CONTEXT)7192   gen _simplifier(const gen & g,GIAC_CONTEXT){
7193     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
7194     if (is_equal(g))
7195       return apply_to_equal(g,_simplifier,contextptr);
7196     if (g.type!=_VECT)
7197       return simplifier(g,contextptr);
7198     return apply(g,_simplifier,contextptr);
7199   }
7200 
_inferieur_strict_sort(const gen & args,GIAC_CONTEXT)7201   gen _inferieur_strict_sort(const gen & args,GIAC_CONTEXT){
7202     if ( args.type==_STRNG && args.subtype==-1) return  args;
7203     if (args.type!=_VECT)
7204       return gensizeerr(contextptr);
7205     gen a=args._VECTptr->front(),b=args._VECTptr->back();
7206     if (a.type==_VECT && b.type==_VECT){
7207       unsigned as=unsigned(a._VECTptr->size()),bs=unsigned(b._VECTptr->size());
7208       for (unsigned i=0;i<as && i<bs;++i){
7209 	if ((*a._VECTptr)[i]!=(*b._VECTptr)[i]){
7210 	  a=(*a._VECTptr)[i]; b=(*b._VECTptr)[i];
7211 	  break;
7212 	}
7213       }
7214     }
7215     if (a.is_symb_of_sommet(at_equal) && b.is_symb_of_sommet(at_equal)){
7216       if (a._SYMBptr->feuille[0]!=b._SYMBptr->feuille[0]){
7217 	a=a._SYMBptr->feuille[0]; b=b._SYMBptr->feuille[0];
7218       }
7219       else {
7220 	a=a._SYMBptr->feuille[1]; b=b._SYMBptr->feuille[1];
7221       }
7222     }
7223     if (a.type==_STRNG){
7224       if (b.type!=_STRNG) return true;
7225       return *a._STRNGptr<*b._STRNGptr;
7226     }
7227     if (b.type==_STRNG)
7228       return false;
7229     gen res=inferieur_strict(a,b,contextptr);
7230     if (res.type==_INT_)
7231       return res;
7232     return islesscomplexthanf(a,b);
7233   }
7234   static const char _inferieur_strict_sort_s []="inferieur_strict_sort";
7235   static define_unary_function_eval (__inferieur_strict_sort,&_inferieur_strict_sort,_inferieur_strict_sort_s);
7236   define_unary_function_ptr5( at_inferieur_strict_sort ,alias_at_inferieur_strict_sort,&__inferieur_strict_sort,0,true);
7237 
_sort(const gen & args,GIAC_CONTEXT)7238   gen _sort(const gen & args,GIAC_CONTEXT){
7239     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
7240     if (args.type==_SYMB)
7241       return simplifier(args,contextptr);
7242     if (args.type!=_VECT)
7243       return args; // FIXME sort in additions, symbolic(at_sort,args);
7244     vecteur v=*args._VECTptr;
7245     int subtype;
7246     gen f;
7247     bool usersort=v.size()==2 && v[0].type==_VECT && v[1].type!=_VECT
7248       // && args.subtype==_SEQ__VECT
7249       ;
7250     bool rev=false;
7251     if (usersort){
7252       f=v[1];
7253       subtype=v[0].subtype;
7254       v=*v[0]._VECTptr;
7255       if (is_equal(f) && f._SYMBptr->feuille[0]==at_reverse && !is_zero(f._SYMBptr->feuille[1])){
7256 	f=at_inferieur_strict;
7257 	rev=true;
7258       }
7259     }
7260     else {
7261       f=at_inferieur_strict_sort;
7262       subtype=args.subtype;
7263     }
7264     if (!v.empty() && (f==at_inferieur_strict || f==at_inferieur_strict_sort)){
7265       // check integer or double vector
7266       if (v.front().type==_INT_ && is_integer_vecteur(v,true)){
7267 	// find min/max
7268 	vector<int> w(vecteur_2_vector_int(v));
7269 	int m=giacmin(w),M=giacmax(w);
7270 	if (M-m<=int(w.size())/3){
7271 	  vector<int> eff(M-m+1);
7272 	  effectif(w,eff,m);
7273 	  vecteur res(w.size());
7274 	  iterateur it=res.begin();
7275 	  int val=m;
7276 	  for (unsigned i=0;i<eff.size();++val,++i){
7277 	    unsigned I=eff[i];
7278 	    for (unsigned j=0;j<I;++it,++j){
7279 	      *it=val;
7280 	    }
7281 	  }
7282 	  if (rev)
7283 	    reverse(res.begin(),res.end());
7284 	  return gen(res,subtype);
7285 	}
7286 	sort(w.begin(),w.end());
7287 	vector_int2vecteur(w,v);
7288 	if (rev)
7289 	  reverse(v.begin(),v.end());
7290 	return gen(v,subtype);
7291       }
7292       vector<giac_double> V;
7293       if (v.front().type==_DOUBLE_ && is_fully_numeric(v) && convert(v,V,true)){
7294 	sort(V.begin(),V.end());
7295 	v=vector_giac_double_2_vecteur(V);
7296 	if (rev)
7297 	  reverse(v.begin(),v.end());
7298 	return gen(v,subtype);
7299       }
7300     }
7301     sort(v.begin(),v.end(),gen_sort(f,contextptr));
7302     if (rev)
7303       reverse(v.begin(),v.end());
7304     return gen(v,subtype);
7305   }
7306   static const char _sort_s []="sort";
7307   static define_unary_function_eval (__sort,&_sort,_sort_s);
7308   define_unary_function_ptr5( at_sort ,alias_at_sort,&__sort,0,true);
7309 
7310   static const char _sorted_s []="sorted";
7311   static define_unary_function_eval (__sorted,&_sort,_sorted_s);
7312   define_unary_function_ptr5( at_sorted ,alias_at_sorted,&__sorted,0,true);
7313 
remove_nodisp(const gen & g)7314   static gen remove_nodisp(const gen & g){
7315     if (g.is_symb_of_sommet(at_nodisp))
7316       return g._SYMBptr->feuille;
7317     return g;
7318   }
_ans(const gen & args,GIAC_CONTEXT)7319   gen _ans(const gen & args,GIAC_CONTEXT){
7320     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
7321     if (args.type==_VECT && args._VECTptr->size()>1){
7322       vecteur v=*args._VECTptr;
7323       gen tmp=_ans(v.front(),contextptr);
7324       v.erase(v.begin());
7325       return _at(makesequence(tmp,gen(v,args.subtype)),contextptr);
7326     }
7327     int s=int(history_out(contextptr).size());
7328     if (!s)
7329       return undef;
7330     int i;
7331     if (args.type!=_INT_)
7332       i=-1;
7333     else {
7334       i=args.val;
7335       if (xcas_mode(contextptr)==3)
7336 	i=-i;
7337     }
7338     if (i>=0){
7339       if (i>=s)
7340 	return gentoofewargs(print_INT_(i));
7341       return remove_nodisp(history_out(contextptr)[i]);
7342     }
7343     if (s+i<0)
7344       return gentoofewargs(print_INT_(-i));
7345     return remove_nodisp(history_out(contextptr)[s+i]);
7346   }
7347   static const char _ans_s []="ans";
7348   static define_unary_function_eval (__ans,&_ans,_ans_s);
7349   define_unary_function_ptr5( at_ans ,alias_at_ans,&__ans,0,true);
7350 
_quest(const gen & args,GIAC_CONTEXT)7351   gen _quest(const gen & args,GIAC_CONTEXT){
7352     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
7353     if (rpn_mode(contextptr))
7354       return gensizeerr(contextptr);
7355     int s=int(history_in(contextptr).size());
7356     if (!s)
7357       return undef;
7358     int i;
7359     if (args.type!=_INT_)
7360       i=-2;
7361     else
7362       i=args.val;
7363     if (i>=0){
7364       if (i>=s)
7365 	return gentoofewargs(print_INT_(i));
7366       return remove_nodisp(history_in(contextptr)[i]);
7367     }
7368     if (s+i<0)
7369       return gentoofewargs(print_INT_(-i));
7370     return remove_nodisp(history_in(contextptr)[s+i]);
7371   }
7372   static const char _quest_s []="quest";
7373   static define_unary_function_eval (__quest,&_quest,_quest_s);
7374   define_unary_function_ptr5( at_quest ,alias_at_quest,&__quest,0,true);
7375 
float2continued_frac(double d_orig,double eps)7376   vector<int> float2continued_frac(double d_orig,double eps){
7377     if (eps<1e-11)
7378       eps=1e-11;
7379     double d=fabs(d_orig);
7380     vector<int> v;
7381     if (d>rand_max2){
7382 #ifndef NO_STDEXCEPT
7383       setsizeerr(gettext("Float too large"));
7384 #endif
7385       v.push_back(rand_max2);
7386       return v;
7387     }
7388     double i;
7389     for (;;){
7390       i=std::floor(d);
7391       v.push_back(int(i));
7392       d=d-i;
7393       if (d<eps)
7394 	return v;
7395       d=1/d;
7396       eps=eps*d*d;
7397     }
7398   }
7399 
continued_frac2gen(vector<int> v,double d_orig,double eps,GIAC_CONTEXT)7400   gen continued_frac2gen(vector<int> v,double d_orig,double eps,GIAC_CONTEXT){
7401     gen res(v.back());
7402     for (;;){
7403       v.pop_back();
7404       if (v.empty()){
7405 	if (
7406 	    !my_isnan(d_orig) &&
7407 	    fabs(evalf_double(res-d_orig,1,contextptr)._DOUBLE_val)>eps)
7408 	  return d_orig;
7409 	return res;
7410       }
7411       res=inv(res,contextptr);
7412       res=res+v.back();
7413     }
7414     return res;
7415   }
7416 
chk_not_unit(const gen & g)7417   gen chk_not_unit(const gen & g){
7418     if (g.is_symb_of_sommet(at_unit))
7419       return gensizeerr(gettext("Incompatible units"));
7420     return g;
7421   }
7422 
convert_interval(const gen & g,int nbits,GIAC_CONTEXT)7423   gen convert_interval(const gen & g,int nbits,GIAC_CONTEXT){
7424 #if defined HAVE_LIBMPFI && !defined NO_RTTI
7425     if (g.type==_VECT){
7426       vecteur res(*g._VECTptr);
7427       for (unsigned i=0;i<res.size();++i)
7428 	res[i]=convert_interval(res[i],nbits,contextptr);
7429       return gen(res,g.subtype);
7430     }
7431     if (g.is_symb_of_sommet(at_rootof) && g._SYMBptr->feuille.type==_VECT && g._SYMBptr->feuille._VECTptr->size()==2){
7432       gen p=g._SYMBptr->feuille._VECTptr->front();
7433       gen x=g._SYMBptr->feuille._VECTptr->back();
7434       if (p.type==_VECT && x.type==_VECT){
7435 	bool reel=is_real(*x._VECTptr,contextptr);
7436 	// adjust (guess?) nbits
7437 	gen g_=accurate_evalf(evalf_double(g,1,contextptr),60); // low prec multiprec evalf
7438 	vecteur P=*p._VECTptr;
7439 	gen val=0;
7440 	gen err=0; // absolute error
7441 	gen absg=abs(g_,contextptr);
7442 	gen rnd=accurate_evalf(gen(4e-15),60);
7443 	for (int i=0;i<P.size();++i){
7444 	  val = accurate_evalf(val*g_+P[i],60);
7445 	  // 2* because we multiply complex numbers
7446 	  err = 2*(err*absg+rnd*abs(val,contextptr));
7447 	}
7448 	err=err/abs(val,contextptr)/rnd; // relative error/rounding error
7449 	if (is_strictly_greater(err,1,contextptr))
7450 	  err=log(err,contextptr);
7451 	else
7452 	  err=0;
7453 	double errd=evalf_double(err,1,contextptr)._DOUBLE_val;
7454 	int nbitsmore=std::ceil(errd/std::log(2));
7455 	if (nbits<56)
7456 	  nbits=56; // otherwise we should adjust precision 1e-14 in in_select_root call below
7457 	gen r=complexroot(makesequence(symb_horner(*x._VECTptr,vx_var),pow(plus_two,-nbits-nbitsmore-4,contextptr)),true,contextptr);
7458 	if (r.type==_VECT){
7459 	  vecteur R=*r._VECTptr;
7460 	  for (unsigned i=0;i<R.size();++i){
7461 	    R[i]=R[i][0];
7462 	  }
7463 	  x=in_select_root(R,reel,contextptr,1e-14);
7464 	  return horner(*p._VECTptr,x,contextptr);
7465 	}
7466       }
7467     }
7468     if (g.type==_SYMB)
7469       return g._SYMBptr->sommet(convert_interval(g._SYMBptr->feuille,nbits,contextptr),contextptr);
7470     if (g.type==_REAL){
7471       if (dynamic_cast<real_interval *>(g._REALptr))
7472 	return g;
7473     }
7474     if (g.type==_CPLX)
7475       return convert_interval(*g._CPLXptr,nbits,contextptr)+cst_i*convert_interval(*(g._CPLXptr+1),nbits,contextptr);
7476     if (is_integer(g) || g.type==_REAL){
7477       gen f=accurate_evalf(g,nbits);
7478       return eval(gen(makevecteur(f,f),_INTERVAL__VECT),1,contextptr);
7479     }
7480     if (g.type==_FRAC){
7481       return convert_interval(g._FRACptr->num,nbits,contextptr)/convert_interval(g._FRACptr->den,nbits,contextptr);
7482     }
7483     if (g.type==_IDNT){
7484       if (g==cst_pi || g==cst_euler_gamma){
7485 	mpfi_t tmp;
7486 	mpfi_init2(tmp,nbits);
7487 	if (g==cst_pi)
7488 	  mpfi_const_pi(tmp);
7489 	else
7490 	  mpfi_const_euler(tmp);
7491 	gen res=real_interval(tmp);
7492 	mpfi_clear(tmp);
7493 	return res;
7494       }
7495     }
7496     return g;
7497 #endif
7498     return gensizeerr("Interval arithmetic support not compiled. Please install MPFI and recompile");
7499   }
7500 
convert_real(const gen & g,GIAC_CONTEXT)7501   gen convert_real(const gen & g,GIAC_CONTEXT){
7502 #if defined HAVE_LIBMPFI && !defined NO_RTTI
7503     if (g.type==_STRNG)
7504       return convert_real(gen(*g._STRNGptr,contextptr),contextptr);
7505     if (g.type==_VECT){
7506       vecteur res(*g._VECTptr);
7507       for (unsigned i=0;i<res.size();++i)
7508 	res[i]=convert_real(res[i],contextptr);
7509       return gen(res,g.subtype);
7510     }
7511     if (g.type==_SYMB)
7512       return g._SYMBptr->sommet(convert_real(g._SYMBptr->feuille,contextptr),contextptr);
7513     if (g.type==_REAL){
7514       if (dynamic_cast<real_interval *>(g._REALptr))
7515 	return _milieu(g,contextptr);
7516     }
7517     if (g.type==_CPLX)
7518       return convert_real(*g._CPLXptr,contextptr)+cst_i*convert_real(*(g._CPLXptr+1),contextptr);
7519     return g;
7520 #endif
7521     return gensizeerr("Interval arithmetic support not compiled. Please install MPFI and recompile");
7522   }
7523 
os_nary_workaround(const gen & g)7524   gen os_nary_workaround(const gen & g){
7525 #ifdef KHICAS
7526     if (g.type==_VECT && g._VECTptr->size()==1 && g._VECTptr->front().type==_VECT)
7527       return change_subtype(g._VECTptr->front(),_SEQ__VECT);
7528 #endif
7529     return g;
7530   }
7531 
denest_sto(const gen & g)7532   gen denest_sto(const gen & g){
7533     if (g.type==_VECT){
7534       vecteur v(*g._VECTptr);
7535       iterateur it=v.begin(),itend=v.end();
7536       for (;it!=itend;++it)
7537 	*it=denest_sto(*it);
7538       return gen(v,g.subtype);
7539     }
7540     if (g.is_symb_of_sommet(at_sto) && g._SYMBptr->feuille.type==_VECT && g._SYMBptr->feuille._VECTptr->size()==2){
7541       gen b=g._SYMBptr->feuille._VECTptr->front();
7542       gen a=g._SYMBptr->feuille._VECTptr->back();
7543       // a:=b, should be a0,..,an-2,an-1=b
7544       if (b.is_symb_of_sommet(at_sto)){
7545 	// if b is a sto a0,...an-2,a1=c[0],c1,..,cn-1
7546 	gen c=denest_sto(b);
7547 	if (a.type==_VECT && c.type==_VECT){
7548 	  vecteur av=*a._VECTptr;
7549 	  vecteur cv=*c._VECTptr;
7550 	  av.back()=symbolic(at_equal,makesequence(av.back(),cv.front()));
7551 	  cv.erase(cv.begin());
7552 	  return gen(mergevecteur(av,cv),_SEQ__VECT);
7553 	}
7554       }
7555       if (a.type==_VECT){
7556 	vecteur av=*a._VECTptr;
7557 	av.back()=symbolic(at_equal,makesequence(av.back(),b));
7558 	return gen(av,_SEQ__VECT);
7559       }
7560     }
7561     if (g.type==_SYMB){
7562       gen f=denest_sto(g._SYMBptr->feuille);
7563       return symbolic(g._SYMBptr->sommet,f);
7564     }
7565     return g;
7566   }
7567 
re2zconj(const gen & g,GIAC_CONTEXT)7568   gen re2zconj(const gen &g,GIAC_CONTEXT){
7569     return (g+symb_conj(g))/2;
7570   }
7571 
im2zconj(const gen & g,GIAC_CONTEXT)7572   gen im2zconj(const gen &g,GIAC_CONTEXT){
7573     return (g-symb_conj(g))/(2*cst_i);
7574   }
7575 
abs2zconj(const gen & g,GIAC_CONTEXT)7576   gen abs2zconj(const gen &g,GIAC_CONTEXT){
7577     return symbolic(at_sqrt,g*symb_conj(g));
7578   }
7579 
re2abs(const gen & g,GIAC_CONTEXT)7580   gen re2abs(const gen & g,GIAC_CONTEXT){
7581     return (g+pow(symb_abs(g),2,contextptr)/g)/2;
7582   }
7583 
im2abs(const gen & g,GIAC_CONTEXT)7584   gen im2abs(const gen & g,GIAC_CONTEXT){
7585     return (g-pow(symb_abs(g),2,contextptr)/g)/(2*cst_i);
7586   }
7587 
conj2abs(const gen & g,GIAC_CONTEXT)7588   gen conj2abs(const gen &g,GIAC_CONTEXT){
7589     return pow(symb_abs(g),2,contextptr)/g;
7590   }
7591 
_convert(const gen & args,const context * contextptr)7592   gen _convert(const gen & args,const context * contextptr){
7593     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
7594     if (args.type!=_VECT){
7595       if (args.type==_POLY)
7596 	return _convert(vecteur(1,args),contextptr);
7597       return gensizeerr(contextptr);
7598     }
7599     vecteur v=*args._VECTptr;
7600     int s=int(v.size());
7601     if (s==3 && v[0].type==_INT_ && v[0].subtype==_INT_PLOT && v[0].val==_AXES && v[2].type==_INT_ && v[2].subtype==_INT_PLOT && v[2].val==_SET__VECT){
7602       // axes.set(xlabel="",ylabel="")
7603       return v[1].type==_VECT?change_subtype(v[1],_SEQ__VECT):v[1];
7604     }
7605     if (s>=1 && v.front().type==_POLY){
7606       int dim=v.front()._POLYptr->dim;
7607       vecteur idx(dim);
7608       vector< monomial<gen> >::const_iterator it=v.front()._POLYptr->coord.begin(),itend=v.front()._POLYptr->coord.end();
7609       vecteur res;
7610       res.reserve(itend-it);
7611       for (;it!=itend;++it){
7612 	index_t::const_iterator j=it->index.begin();
7613 	for (int k=0;k<dim;k++,++j)
7614 	  idx[k]=*j;
7615 	res.push_back(makevecteur(it->value,idx));
7616       }
7617       return res;
7618     }
7619     if (s<2)
7620       return gensizeerr(contextptr);
7621     gen f=v[1];
7622     gen g=v.front();
7623     if (g.type==_VECT && v[1].type==_VECT)
7624       return gen(*g._VECTptr,v[1].subtype);
7625     if (f==at_cell && ckmatrix(g,true)){
7626       matrice m=makefreematrice(*g._VECTptr);
7627       int lignes,colonnes; mdims(m,lignes,colonnes);
7628       makespreadsheetmatrice(m,contextptr);
7629       if (s>=5){ // convert(matrix,command,row,col)
7630 	// command==copy down, copy right, insert/delete row, insert/delete col
7631 	gen CMD=v[2],cmd,R=v[3],C=v[4];
7632 	if (!is_integer(R) || !is_integer(C))
7633 	  return gensizeerr(contextptr);
7634 	string scmd;
7635 	if (CMD.type==_STRNG)
7636 	  scmd=*CMD._STRNGptr;
7637 	else {
7638 	  if (!is_integral(CMD)) return gensizeerr(contextptr);
7639 	  cmd=CMD.val;
7640 	}
7641 	if (scmd=="copy down")
7642 	  cmd=0;
7643 	if (scmd=="copy right")
7644 	  cmd=1;
7645 	if (scmd=="row+")
7646 	  cmd=2;
7647 	if (scmd=="row-")
7648 	  cmd=3;
7649 	if (scmd=="col+")
7650 	  cmd=4;
7651 	if (scmd=="col-")
7652 	  cmd=5;
7653 	int r=R.val,c=C.val;
7654 	if (r<0 || r>=lignes || c<0 || c>=colonnes)
7655 	  return gendimerr(contextptr);
7656 	gen cellule=m[r][c];
7657 	if (cmd==0){
7658 	  for (int i=r+1;i<lignes;++i){
7659 	    vecteur & v=*m[i]._VECTptr;
7660 	    v[c]=freecopy(cellule);
7661 	  }
7662 	}
7663 	if (cmd==1){
7664 	  vecteur & v=*m[r]._VECTptr;
7665 	  for (int j=c+1;j<colonnes;++j){
7666 	    v[j]=freecopy(cellule);
7667 	  }
7668 	}
7669 	if (cmd==2)
7670 	  m=matrice_insert(m,r,c,1,0,undef,contextptr);
7671 	if (cmd==3)
7672 	  m=matrice_erase(m,r,c,1,0,contextptr);
7673 	if (cmd==4)
7674 	  m=matrice_insert(m,r,c,0,1,undef,contextptr);
7675 	if (cmd==5)
7676 	  m=matrice_erase(m,r,c,0,1,contextptr);
7677 	spread_eval(m,contextptr);
7678       }
7679       return gen(m,_SPREAD__VECT);
7680     }
7681     if (f.is_symb_of_sommet(at_unit)){
7682       if (f._SYMBptr->feuille.type==_VECT && f._SYMBptr->feuille._VECTptr->size()==2)
7683 	f=symbolic(at_unit,makesequence(1,f._SYMBptr->feuille._VECTptr->back()));
7684       g=chk_not_unit(mksa_reduce(evalf(g/f,1,contextptr),contextptr));
7685       g=evalf_double(g,1,contextptr);
7686       if (g.type!=_DOUBLE_ && g.type!=_CPLX && g.type!=_FLOAT_)
7687 	return gensizeerr(gettext("Some units could not be converted to MKSA"));
7688       return g*f;
7689     }
7690     if (s==2 && f==at_conj){
7691       // convert re/im to conj
7692       vector<const unary_function_ptr *> vu;
7693       vu.push_back(at_re);
7694       vu.push_back(at_im);
7695       vu.push_back(at_abs);
7696       vector <gen_op_context> vv;
7697       vv.push_back(re2zconj);
7698       vv.push_back(im2zconj);
7699       vv.push_back(abs2zconj);
7700       return subst(g,vu,vv,false,contextptr);
7701     }
7702     if (s==2 && f==at_abs){
7703       vector<const unary_function_ptr *> vu;
7704       vu.push_back(at_re);
7705       vu.push_back(at_im);
7706       vu.push_back(at_conj);
7707       vector <gen_op_context> vv;
7708       vv.push_back(re2abs);
7709       vv.push_back(im2abs);
7710       vv.push_back(conj2abs);
7711       return subst(g,vu,vv,false,contextptr);
7712     }
7713     if (s==2 && f==at_interval)
7714       return convert_interval(g,int(decimal_digits(contextptr)*3.2),contextptr);
7715     if (s==2 && f==at_real && f.type==_FUNC)
7716       return convert_real(g,contextptr);
7717     if (s>=2 && f==at_series){
7718       if (g.type==_VECT){
7719 	sparse_poly1 res=vecteur2sparse_poly1(*g._VECTptr);
7720 	if (s>=3 && v[2].type==_INT_ && v[2].val>=0)
7721 	  res.push_back(monome(undef,v[2].val));
7722 	return res;
7723       }
7724       int s=series_flags(contextptr);
7725       series_flags(contextptr) = s | (1<<4);
7726       v.erase(v.begin()+1);
7727       gen res=_series(gen(v,args.subtype),contextptr);
7728       series_flags(contextptr) = s ;
7729       return res;
7730     }
7731     if (s==3 && f==at_interval && v[2].type==_INT_)
7732       return convert_interval(g,int(v[2].val*3.2),contextptr);
7733     if (s==3 && f.type==_INT_ ){
7734       if (f.val==_BASE && is_integer(v.back()) ){
7735 	if (is_greater(1,v.back(),contextptr))
7736 	  return gensizeerr(gettext("Bad conversion basis"));
7737 	if (is_integer(g)){
7738 	  if (is_zero(g))
7739 	    return makevecteur(g);
7740 	  // convert(integer,base,integer)
7741 	  bool positif=is_positive(g,contextptr);
7742 	  g=abs(g,contextptr);
7743 	  vecteur res;
7744 	  gen q;
7745 	  for (;!is_zero(g);){
7746 	    res.push_back(irem(g,v.back(),q));
7747 	    g=q;
7748 	  }
7749 	  // reverse(res.begin(),res.end());
7750 	  if (positif)
7751 	    return res;
7752 	  return -res;
7753 	}
7754 	if (g.type==_VECT){
7755 	  vecteur w(*g._VECTptr);
7756 	  reverse(w.begin(),w.end());
7757 	  return horner(w,v.back());
7758 	}
7759       }
7760       if (f.val==_CONFRAC && v.back().type==_IDNT){
7761 	g=evalf_double(g,1,contextptr);
7762 	if (g.type==_DOUBLE_)
7763 	  return sto(vector_int_2_vecteur(float2continued_frac(g._DOUBLE_val,epsilon(contextptr))),v.back(),contextptr);
7764       }
7765     }
7766     if (s>2)
7767       g=gen(mergevecteur(vecteur(1,g),vecteur(v.begin()+2,v.begin()+s)),args.subtype);
7768     if (g.type==_STRNG){
7769       string s=*g._STRNGptr;
7770       int i=f.type==_INT_?f.val:-1;
7771       if (i==_IDNT)
7772 	return identificateur(s);
7773       if (i==_INT_ || i==_ZINT || f==at_int){
7774 	f=gen(s,contextptr);
7775 	if (!is_integral(f))
7776 	  return gensizeerr(contextptr);
7777 	return f;
7778       }
7779       if (i==_SYMB || i==_FRAC)
7780 	return gen(s,contextptr);
7781       if (i==_FRAC || f==at_frac){
7782 	f=exact(gen(s,contextptr),contextptr);
7783 	return f;
7784       }
7785       if (i==_REAL)
7786 	return evalf(gen(s,contextptr),1,contextptr);
7787       if (i==_DOUBLE_ || f==at_real || f==at_float)
7788 	return evalf_double(gen(s,contextptr),1,contextptr);
7789     }
7790 #ifndef CAS38_DISABLED
7791     if (v[1].type==_FUNC){
7792       if (f==at_sincos)
7793 	return sincos(g,contextptr);
7794       if (f==at_sin || f==at_SIN)
7795 	return trigsin(g,contextptr);
7796       if (f==at_cos || f==at_COS)
7797 	return trigcos(g,contextptr);
7798       if (f==at_tan || f==at_TAN)
7799 	return halftan(g,contextptr);
7800       if (f==at_plus)
7801 	return partfrac(tcollect(g,contextptr),true,contextptr);
7802       if (f==at_prod){
7803 	if (is_integer(g)) return _ifactor(g,contextptr);
7804 	return _factor(_texpand(g,contextptr),contextptr);
7805       }
7806       if (f==at_division)
7807 	return _simplify(g,contextptr);
7808       if (f==at_exp || f==at_ln || f==at_EXP)
7809 	return trig2exp(g,contextptr);
7810       if (f==at_string){
7811 	int maxp=MAX_PRINTABLE_ZINT;
7812 	MAX_PRINTABLE_ZINT= 1000000;
7813 	gen res=string2gen(g.print(contextptr),false);
7814 	MAX_PRINTABLE_ZINT=maxp;
7815 	return res;
7816       }
7817       if (g.type==_MAP){
7818 	if (f==at_matrix || f==at_vector){
7819 	  if (g.subtype==_SPARSE_MATRIX)
7820 	    *logptr(contextptr) << gettext("Run convert(matrix,array) for dense conversion") << '\n';
7821 	  g.subtype=_SPARSE_MATRIX;
7822 	  return g;
7823 	}
7824 	if (f==at_array){
7825 	  vecteur res;
7826 	  if (!convert(*g._MAPptr,res))
7827 	    return gensizeerr(gettext("Invalid map"));
7828 	  return res;
7829 	}
7830 	if (f==at_table){
7831 	  g.subtype=0;
7832 	  return g;
7833 	}
7834       }
7835       if (g.type==_VECT){
7836 	if (f==at_matrix){
7837 	  if (!ckmatrix(g))
7838 	    return gentypeerr(contextptr);
7839 	  g.subtype=_MATRIX__VECT;
7840 	  return g;
7841 	}
7842 	if ( f==at_vector || f==at_array){
7843 	  g.subtype=_MATRIX__VECT;
7844 	  return g;
7845 	}
7846 	if (f==at_seq){
7847 	  g.subtype=_SEQ__VECT;
7848 	  return g;
7849 	}
7850 	if (f==at_table){
7851 	  const vecteur & m = *g._VECTptr;
7852 	  // conversion to sparse matrix
7853 	  gen_map M;
7854 	  gen resg(M);
7855 	  resg.subtype=_SPARSE_MATRIX;
7856 	  gen_map & res=*resg._MAPptr;
7857 	  convert(m,res);
7858 	  return resg;
7859 	}
7860       }
7861       return f(g,contextptr);
7862       // setsizeerr();
7863     }
7864 #endif
7865     if (f.type==_INT_ && f.val>=0) {
7866       if (f.val==_CONFRAC){
7867 	if (g.type==_VECT)
7868 	  return _dfc2f(g,contextptr);
7869 	g=evalf_double(g,1,contextptr);
7870 	if (g.type==_DOUBLE_)
7871 	  return vector_int_2_vecteur(float2continued_frac(g._DOUBLE_val,epsilon(contextptr)));
7872       }
7873       int i=f.val;
7874       if (f.val==_FRAC && f.subtype==_INT_TYPE)
7875 	return exact(g,contextptr);
7876       if (f.val==_POLY1__VECT && f.subtype==_INT_MAPLECONVERSION){ // remove order_size
7877 	if (g.type==_SPOL1){
7878 	  vecteur v; int shift;
7879 	  if (sparse_poly12vecteur(*g._SPOL1ptr,v,shift)){
7880 	    if (is_undef(v.front()))
7881 	      v.erase(v.begin());
7882 	    v=trim(v,0);
7883 	    if (shift)
7884 	      return makesequence(gen(v,_POLY1__VECT),shift);
7885 	    return gen(v,_POLY1__VECT);
7886 	  }
7887 	  return gensizeerr(contextptr);
7888 	}
7889 	if (g.type==_VECT && !g._VECTptr->empty()){
7890 	  // check if g is a list of [coeff,[index]]
7891 	  vecteur & w=*g._VECTptr;
7892 	  if (w.front().type!=_VECT)
7893 	    return change_subtype(g,_POLY1__VECT);
7894 	  if (w.front().type==_VECT && w.front()._VECTptr->size()==2 && w.front()._VECTptr->back().type==_VECT){
7895 	    unsigned dim=unsigned(w.front()._VECTptr->back()._VECTptr->size());
7896 	    iterateur it=w.begin(),itend=w.end();
7897 	    polynome res(dim);
7898 	    vector< monomial<gen> > & coord =res.coord;
7899 	    coord.reserve(itend-it);
7900 	    index_t i(dim);
7901 	    for (;it!=itend;++it){
7902 	      if (it->type!=_VECT || it->_VECTptr->size()!=2 || it->_VECTptr->back().type!=_VECT)
7903 		break;
7904 	      vecteur & idx = *it->_VECTptr->back()._VECTptr;
7905 	      if (idx.size()!=dim)
7906 		break;
7907 	      const_iterateur jt=idx.begin(),jtend=idx.end();
7908 	      for (int k=0;jt!=jtend;++jt,++k){
7909 		if (jt->type!=_INT_)
7910 		  break;
7911 		i[k]=jt->val;
7912 	      }
7913 	      if (jt!=jtend)
7914 		break;
7915 	      coord.push_back(monomial<gen>(it->_VECTptr->front(),i));
7916 	    }
7917 	    if (it==itend)
7918 	      return res;
7919 	  }
7920 	}
7921 	vecteur l(lop(g,at_order_size));
7922 	vecteur lp(l.size(),zero);
7923 	g=subst(g,l,lp,false,contextptr);
7924 	return g;
7925       }
7926 #ifndef CAS38_DISABLED
7927       if (f.subtype==_INT_MAPLECONVERSION){
7928 	switch (i){
7929 	case _TRIG:
7930 	  return sincos(g,contextptr);
7931 	case _EXPLN:
7932 	  return trig2exp(g,contextptr);
7933 	case _PARFRAC: case _FULLPARFRAC:
7934 	  return _partfrac(g,contextptr);
7935 	case _MAPLE_LIST:
7936 	  if (g.subtype==0 && ckmatrix(g)){
7937 	    vecteur v;
7938 	    aplatir(*g._VECTptr,v);
7939 	    return v;
7940 	  }
7941 	  g.subtype=0;
7942 	  return g;
7943 	case _SET__VECT:
7944 	  if (g.type==_VECT){
7945 	    vecteur v(*g._VECTptr);
7946 	    comprim(v);
7947 	    g=gen(v,_SET__VECT);
7948 	    return g;
7949 	  }
7950 	default:
7951 	  return gensizeerr(contextptr);
7952 	}
7953       }
7954 #endif
7955       g.subtype=v.back().val;
7956       return g;
7957     }
7958     return gensizeerr(contextptr);
7959   }
7960   static const char _convert_s []="convert";
7961   static define_unary_function_eval (__convert,&_convert,_convert_s);
7962   define_unary_function_ptr5( at_convert ,alias_at_convert,&__convert,0,true);
7963 
7964   static const char _convertir_s []="convertir";
7965   static define_unary_function_eval (__convertir,&_convert,_convertir_s);
7966   define_unary_function_ptr5( at_convertir ,alias_at_convertir,&__convertir,0,true);
7967 
_deuxpoints(const gen & args,GIAC_CONTEXT)7968   gen _deuxpoints(const gen & args,GIAC_CONTEXT){
7969     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
7970     return symbolic(at_deuxpoints,args);
7971   }
7972   static const char _deuxpoints_s []=":";
7973   static define_unary_function_eval4 (__deuxpoints,&_deuxpoints,_deuxpoints_s,&printsommetasoperator,&texprintsommetasoperator);
7974   define_unary_function_ptr( at_deuxpoints ,alias_at_deuxpoints ,&__deuxpoints);
7975 
7976 #if defined FXCG || defined GIAC_HAS_STO_38
_read(const gen & args,GIAC_CONTEXT)7977   gen _read(const gen & args,GIAC_CONTEXT){ return 0;}
_write(const gen & args,GIAC_CONTEXT)7978   gen _write(const gen & args,GIAC_CONTEXT){ return 0;}
7979   static const char _read_s []="read";
7980   static define_unary_function_eval (__read,&_read,_read_s);
7981   define_unary_function_ptr5( at_read ,alias_at_read ,&__read,0,T_RETURN);
7982 
7983   static const char _write_s []="write";
7984   static define_unary_function_eval_quoted (__write,&_write,_write_s);
7985   define_unary_function_ptr5( at_write ,alias_at_write,&__write,_QUOTE_ARGUMENTS,true);
7986 
7987 #else
7988 
7989 #ifdef NSPIRE
in_mws_translate(ios_base<T> & inf,ios_base<T> & of)7990   template<class T> void in_mws_translate(ios_base<T> &  inf,ios_base<T> &  of)
7991 #else
7992   void in_mws_translate(istream & inf,ostream & of)
7993 #endif
7994   {
7995     char c,oldc=0;
7996     // now read char by char,
7997     for (;;){
7998       inf.get(c);
7999       if (c=='"')
8000 	break;
8001     }
8002     for (;;){
8003       inf.get(c);
8004       if (c=='_'){
8005 	of << '~';
8006 	continue;
8007       }
8008       if (c==')' && oldc=='%') // %) -> % )
8009 	of << " ";
8010       if (c=='"'){
8011 	break;
8012       }
8013       if (c=='\n' || c==13)
8014 	continue;
8015       if (c=='\\'){
8016 	inf.get(c);
8017 	if (c>'0' && c<='3'){ // read three chars -> octal code
8018 	  unsigned char res=c-'0';
8019 	  inf.get(c);
8020 	  res <<= 3;
8021 	  res += (c-'0');
8022 	  inf.get(c);
8023 	  res <<= 3;
8024 	  res += (c-'0');
8025 	  of << res;
8026 	}
8027 	else {
8028 	  switch (c) {
8029 	  case 'n':
8030 	    of << '\n';
8031 	    break;
8032 	  case '+':
8033 	    break;
8034 	  case '"':
8035 	    of << "\""; // Seems one " is needed, not two
8036 	    // of << "\"\"";
8037 	    break;
8038 	  default:
8039 	    of << c;
8040 	  } // end switch
8041 	} // end else octal code
8042 	continue;
8043       } // end c==backslash
8044       else
8045 	of << c;
8046       oldc=c;
8047     }
8048   }
8049 
8050   // Maple worksheet translate
8051 #ifdef NSPIRE
mws_translate(ios_base<T> & inf,ios_base<T> & of)8052   template<class T> void mws_translate(ios_base<T> &  inf,ios_base<T> &  of)
8053 #else
8054   void mws_translate(istream & inf,ostream & of)
8055 #endif
8056   {
8057     string thet;
8058     while (!inf.eof()){
8059       inf >> thet;
8060       int n1,n2,n3;
8061       n1=int(thet.size());
8062       if (n1>7 && thet.substr(n1-7,7)=="MPLTEXT"){
8063         inf >> n1 >> n2 >> n3;
8064 	in_mws_translate(inf,of);
8065 	of << "\n";
8066       }
8067       else {
8068 	if ( (n1>4 && thet.substr(n1-4,4)=="TEXT") || (n1>7 && thet.substr(n1-7,7)=="XPPEDIT") ){
8069 	  inf >> n1 >> n2;
8070 	  of << '"';
8071 	  in_mws_translate(inf,of);
8072 	  of << '"' << ";\n";
8073 	}
8074       }
8075     }
8076   }
8077 
8078   // TI89/92 function/program translate
8079 #if defined(WIN32) || defined(BESTA_OS) || defined(MS_SMART)
8080 #define BUFFER_SIZE 16384
8081 #endif
8082 
8083 #ifdef NSPIRE
ti_translate(ios_base<T> & inf,ios_base<T> & of)8084   template<class T> void ti_translate(ios_base<T> &  inf,ios_base<T> &  of)
8085 #else
8086   void ti_translate(istream & inf,ostream & of)
8087 #endif
8088   {
8089     char thebuf[BUFFER_SIZE];
8090     inf.getline(thebuf,BUFFER_SIZE,'\n');
8091     inf.getline(thebuf,BUFFER_SIZE,'\n');
8092     string lu=thebuf;
8093     lu=lu.substr(6,lu.size()-7);
8094     CERR << "Function name: " << lu << '\n';
8095     of << ":" << lu;
8096     inf.getline(thebuf,BUFFER_SIZE,'\n');
8097     inf.getline(thebuf,BUFFER_SIZE,'\n');
8098     of << thebuf << '\n';
8099     for (;inf.good();){
8100       inf.getline(thebuf,BUFFER_SIZE,'\n');
8101       lu=thebuf;
8102       if (lu=="\r")
8103         continue;
8104       if (lu=="\\STOP92\\\r"){
8105         break;
8106       }
8107       lu = tiasc_translate(lu);
8108       if (lu.size())
8109         of << ":" << lu << '\n';
8110     }
8111   }
8112 
8113   // FIXME SECURITY
quote_read(const gen & args,GIAC_CONTEXT)8114   gen quote_read(const gen & args,GIAC_CONTEXT){
8115     if (args.type!=_STRNG)
8116       return symbolic(at_read,args);
8117     string fichier=*args._STRNGptr;
8118 #ifdef KHICAS
8119     const char * s=read_file(fichier.c_str());
8120     if (!s)
8121       return undef;
8122     gen g(s,contextptr);
8123     return g;
8124 #else // KHICAS
8125 #ifdef EMCC
8126     string s=fetch(fichier);
8127     return gen(s,contextptr);
8128 #endif
8129     if (fichier.size()>4 && fichier.substr(0,4)=="http"){
8130       string s=fetch(fichier);
8131       return gen(s,contextptr);
8132     }
8133 #ifdef NSPIRE
8134     file inf(fichier.c_str(),"r");
8135 #else
8136     ifstream inf(fichier.c_str());
8137 #endif
8138     if (!inf)
8139       return undef;
8140 #if defined( VISUALC ) || defined( BESTA_OS )
8141     ALLOCA(char, thebuf, BUFFER_SIZE );// char * thebuf = ( char * )alloca( BUFFER_SIZE );
8142 #else
8143     char thebuf[BUFFER_SIZE];
8144 #endif
8145     inf.getline(thebuf,BUFFER_SIZE
8146 #ifndef NSPIRE
8147 		,'\n'
8148 #endif
8149 		);
8150     string lu(thebuf),thet;
8151     if (lu.size()>9 && lu.substr(0,9)=="{VERSION "){ // Maple Worksheet
8152 #ifdef NSPIRE
8153       file of("__.map","w");
8154 #else
8155       ofstream of("__.map");
8156 #endif
8157       mws_translate(inf,of);
8158       of.close();
8159       xcas_mode(contextptr)=1;
8160       *logptr(contextptr) << gettext("Running maple text translation __.map") << '\n';
8161       fichier="__.map";
8162     }
8163     if (lu.size()>6 && lu.substr(0,6)=="**TI92"){ // TI archive
8164       inf.close();
8165       xcas_mode(contextptr)=3;
8166       eval(_unarchive_ti(args,contextptr),1,contextptr);
8167       return symbolic(at_xcas_mode,3);
8168     }
8169     if (lu=="\\START92\\\r"){ // TI text
8170 #ifdef NSPIRE
8171       file of("__.ti","w");
8172 #else
8173       ofstream of("__.ti");
8174 #endif
8175       ti_translate(inf,of);
8176 #ifndef NSPIRE
8177       of.close();
8178 #endif
8179       xcas_mode(contextptr)=3;
8180       *logptr(contextptr) << gettext("Running TI89 text translation __.ti") << '\n';
8181       fichier="__.ti";
8182     } // end file of type TI
8183 #ifdef NSPIRE
8184     file inf2(fichier.c_str(),"r");
8185 #else
8186     inf.close();
8187     ifstream inf2(fichier.c_str());
8188 #endif // NSPIRE
8189     vecteur v;
8190     readargs_from_stream(inf2,v,contextptr);
8191     return v.size()==1?v.front():gen(v,_SEQ__VECT);
8192 #endif // KHICAS
8193   }
is_address(const gen & g,size_t & addr)8194   bool is_address(const gen & g,size_t & addr){
8195     if (g.type==_INT_){
8196       addr=g.val;
8197       return true;
8198     }
8199     if (g.type!=_ZINT)
8200       return false;
8201     addr = modulo(*g._ZINTptr,(unsigned)0x80000000);
8202     addr += 0x80000000;
8203     return true;
8204   }
_read(const gen & args,GIAC_CONTEXT)8205   gen _read(const gen & args,GIAC_CONTEXT){
8206     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8207     size_t addr;
8208     if (is_address(args,addr))
8209       return (int) *(unsigned char *) addr;
8210     if (args.type==_VECT && !args._VECTptr->empty() && args._VECTptr->front().type==_STRNG){
8211       string file=*args._VECTptr->front()._STRNGptr;
8212       if (file.size()>4 && file.substr(0,4)=="http"){
8213 	string s=fetch(file);
8214 	return string2gen(s,false);
8215       }
8216       FILE * f=fopen(file.c_str(),"r");
8217       if (!f)
8218 	return undef;
8219       string s;
8220       while (!feof(f))
8221 	s += char(fgetc(f));
8222       fclose(f);
8223       return string2gen(s,false);
8224     }
8225     if (args.type!=_STRNG)
8226       return symbolic(at_read,args);
8227     return eval(quote_read(args,contextptr),eval_level(contextptr),contextptr);
8228   }
8229   static const char _read_s []="read";
8230   static define_unary_function_eval (__read,&_read,_read_s);
8231   define_unary_function_ptr5( at_read ,alias_at_read ,&__read,0,T_RETURN);
8232 
_read16(const gen & args,GIAC_CONTEXT)8233   gen _read16(const gen & args,GIAC_CONTEXT){
8234     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8235     size_t addr;
8236     if (is_address(args,addr))
8237       return (int) *(unsigned short *) addr;
8238     return gensizeerr(contextptr);
8239   }
8240   static const char _read16_s []="read16";
8241   static define_unary_function_eval (__read16,&_read16,_read16_s);
8242   define_unary_function_ptr5( at_read16 ,alias_at_read16 ,&__read16,0,true);
8243 
_read32(const gen & args,GIAC_CONTEXT)8244   gen _read32(const gen & args,GIAC_CONTEXT){
8245     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8246     size_t addr;
8247     if (is_address(args,addr))
8248       return (longlong) *(unsigned *) addr;
8249     return gensizeerr(contextptr);
8250   }
8251   static const char _read32_s []="read32";
8252   static define_unary_function_eval (__read32,&_read32,_read32_s);
8253   define_unary_function_ptr5( at_read32 ,alias_at_read32 ,&__read32,0,true);
8254 
_write(const gen & args,GIAC_CONTEXT)8255   gen _write(const gen & args,GIAC_CONTEXT){
8256     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8257 #ifdef KHICAS
8258     return _ecris(args,contextptr);
8259 #endif
8260     gen tmp=check_secure();
8261     if (is_undef(tmp)) return tmp;
8262     if (args.type==_VECT){
8263       vecteur v=*args._VECTptr;
8264       v.front()=eval(v.front(),eval_level(contextptr),contextptr);
8265       size_t addr;
8266       if (v.size()==2 && is_address(v.front(),addr)){
8267 	gen vb=eval(v.back(),1,contextptr);
8268 	if (vb.type==_INT_){
8269 #ifdef KHICAS
8270 	  if (exam_mode)
8271 	    return gensizeerr("Exam mode");
8272 #endif
8273 	  unsigned char * ptr =(unsigned char *) addr;
8274 	  // int res=*ptr;
8275 	  *ptr=vb.val;
8276 	  return *ptr;//return res;
8277 	}
8278       }
8279       if (v.size()<2 || v.front().type!=_STRNG)
8280 	return gensizeerr(contextptr);
8281       if (v.size()==2 && is_zero(v[1])){
8282 	v[1]=_VARS(0,contextptr);
8283 	if (v[1].type==_VECT)
8284 	  v=mergevecteur(vecteur(1,v[0]),*v[1]._VECTptr);
8285       }
8286 #ifdef NSPIRE
8287       file inf(v[0]._STRNGptr->c_str(),"w");
8288 #else
8289       ofstream inf(v[0]._STRNGptr->c_str());
8290 #endif
8291       const_iterateur it=v.begin()+1,itend=v.end();
8292       for (;it!=itend;++it){
8293 	gen tmp=eval(*it,1,contextptr);
8294 	if (it->type==_IDNT){
8295 	  gen tmp2=*it;
8296 	  inf << symb_sto(tmp,tmp2) << ";" << '\n';
8297 	}
8298 	else
8299 	  inf << tmp << ";" << '\n';
8300       }
8301       return plus_one;
8302     }
8303     if (args.type!=_STRNG)
8304       return symbolic(at_write,args);
8305 #ifndef KHICAS
8306     if (turtle_stack(contextptr).size()>1)
8307       return _ecris(args,contextptr);
8308 #endif
8309 #ifdef NSPIRE
8310     file inf(args._STRNGptr->c_str(),"w");
8311 #else
8312     ofstream inf(args._STRNGptr->c_str());
8313 #endif
8314     const_iterateur it=history_in(contextptr).begin(),itend=history_in(contextptr).end();
8315     if (it==itend)
8316       return zero;
8317     for (;it!=itend;++it){
8318       if (!it->is_symb_of_sommet(at_write))
8319 	inf << *it << ";" << '\n';
8320     }
8321     return plus_one;
8322   }
8323   static const char _write_s []="write";
8324   static define_unary_function_eval_quoted (__write,&_write,_write_s);
8325   define_unary_function_ptr5( at_write ,alias_at_write,&__write,_QUOTE_ARGUMENTS,true);
8326 
_write32(const gen & args,GIAC_CONTEXT)8327   gen _write32(const gen & args,GIAC_CONTEXT){
8328     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8329 #ifdef KHICAS
8330     if (exam_mode)
8331       return gensizeerr("Exam mode");
8332 #endif
8333     if (args.type==_VECT){
8334       vecteur v=*args._VECTptr;
8335       size_t addr;
8336       if (v.size()==2 && is_address(v.front(),addr)){
8337 	gen vb=v.back();
8338 	unsigned * ptr =(unsigned *) addr;
8339 	if (vb.type==_INT_){
8340 	  *ptr=vb.val;
8341 	  return makevecteur(longlong(addr),longlong(*ptr));
8342 	}
8343 	if (vb.type==_ZINT){
8344 	  unsigned l =mpz_get_si(*vb._ZINTptr);
8345 	  *ptr=l;
8346 	  return makevecteur(longlong(addr),longlong(*ptr));
8347 	}
8348       }
8349     }
8350     return gensizeerr(contextptr);
8351   }
8352   static const char _write32_s []="write32";
8353   static define_unary_function_eval (__write32,&_write32,_write32_s);
8354   define_unary_function_ptr5( at_write32 ,alias_at_write32,&__write32,0,true);
8355 
_write16(const gen & args,GIAC_CONTEXT)8356   gen _write16(const gen & args,GIAC_CONTEXT){
8357     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8358 #ifdef KHICAS
8359     if (exam_mode)
8360       return gensizeerr("Exam mode");
8361 #endif
8362     if (args.type==_VECT){
8363       vecteur v=*args._VECTptr;
8364       size_t addr;
8365       if (v.size()==2 && is_address(v.front(),addr)){
8366 	gen vb=v.back();
8367 	unsigned short * ptr =(unsigned short *) addr;
8368 	if (vb.type==_INT_){
8369 	  *ptr=vb.val;
8370 	  return int( (unsigned short) vb.val);
8371 	}
8372       }
8373     }
8374     return gensizeerr(contextptr);
8375   }
8376   static const char _write16_s []="write16";
8377   static define_unary_function_eval (__write16,&_write16,_write16_s);
8378   define_unary_function_ptr5( at_write16 ,alias_at_write16,&__write16,0,true);
8379 
_save_history(const gen & args,GIAC_CONTEXT)8380   gen _save_history(const gen & args,GIAC_CONTEXT){
8381 #ifdef NSPIRE
8382     return 0;
8383 #else
8384     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8385     gen tmp=check_secure();
8386     if (is_undef(tmp)) return tmp;
8387     if (args.type!=_STRNG)
8388       return symbolic(at_save_history,args);
8389     ofstream of(args._STRNGptr->c_str());
8390     vecteur v(history_in(contextptr));
8391     if (!v.empty() && v.back().is_symb_of_sommet(at_save_history))
8392       v.pop_back();
8393     of << gen(history_in(contextptr),_SEQ__VECT) << '\n';
8394     return plus_one;
8395 #endif
8396   }
8397   static const char _save_history_s []="save_history";
8398   static define_unary_function_eval (__save_history,&_save_history,_save_history_s);
8399   define_unary_function_ptr5( at_save_history ,alias_at_save_history,&__save_history,0,true);
8400 
8401 #endif // FXCG
8402   /*
8403   gen _matrix(const gen & args){
8404   if ( args){
8405     if (!ckmatrix(args))
8406       return symbolic(at_matrix.type==_STRNG &&  args.subtype==-1{
8407     if (!ckmatrix(args))
8408       return symbolic(at_matrix)) return  args){
8409     if (!ckmatrix(args))
8410       return symbolic(at_matrix;
8411     if (!ckmatrix(args))
8412       return symbolic(at_matrix,args);
8413     gen res=args;
8414     res.subtype=_MATRIX__VECT;
8415     return res;
8416   }
8417   static const char _matrix_s []="matrix";
8418   static define_unary_function_eval (__matrix,&_matrix,_matrix_s);
8419   define_unary_function_ptr5( at_matrix ,alias_at_matrix,&__matrix);
8420   */
8421 
symb_findhelp(const gen & args)8422   gen symb_findhelp(const gen & args){
8423     return symbolic(at_findhelp,args);
8424   }
_findhelp(const gen & g,GIAC_CONTEXT)8425   gen _findhelp(const gen & g,GIAC_CONTEXT){
8426     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
8427     gen args(g);
8428     int lang=language(contextptr);
8429     int helpitems = 0;
8430     if (g.type==_VECT && g.subtype==_SEQ__VECT && g._VECTptr->size()==2 && g._VECTptr->back().type==_INT_){
8431       args=g._VECTptr->front();
8432       lang=absint(g._VECTptr->back().val);
8433     }
8434 #ifdef HAVE_LIBPARI
8435     if (args.type==_FUNC && string(args._FUNCptr->ptr()->s)=="pari")
8436       return string2gen(pari_help(0),false);
8437     if (args.type==_SYMB && string(args._SYMBptr->sommet.ptr()->s)=="pari")
8438       return string2gen(pari_help(args._SYMBptr->feuille),false);
8439 #endif
8440     if (args.type==_IDNT)
8441       args=eval(args,1,contextptr);
8442     if (args.type==_SYMB && args._SYMBptr->sommet==at_of && args._SYMBptr->feuille.type==_VECT && args._SYMBptr->feuille._VECTptr->size()==2){
8443       args=args._SYMBptr->feuille._VECTptr->front();
8444       args=eval(args,1,contextptr);
8445     }
8446     if (args.type==_SYMB && args._SYMBptr->sommet!=at_of){
8447       if (args._SYMBptr->sommet==at_program && args._SYMBptr->feuille.type==_VECT){
8448 	vecteur v=*args._SYMBptr->feuille._VECTptr;
8449 	if (v.size()==3){
8450 	  string argss="Help on user function "+g.print(contextptr)+"(";
8451 	  if (v[0].type==_VECT && v[0].subtype==_SEQ__VECT && v[0]._VECTptr->size()==1)
8452 	    argss += v[0]._VECTptr->front().print(contextptr);
8453 	  else
8454 	    argss += v[0].print(contextptr);
8455 	  gen g=v[2];
8456 	  while (g.is_symb_of_sommet(at_bloc))
8457 	    g=g._SYMBptr->feuille;
8458 	  while (g.is_symb_of_sommet(at_local))
8459 	    g=g._SYMBptr->feuille[1];
8460 	  while (g.type==_VECT && !g._VECTptr->empty())
8461 	    g=g._VECTptr->front();
8462 	  argss += ")\n";
8463 	  if (g.type==_STRNG)
8464 	    argss += *g._STRNGptr;
8465 	  else {
8466 	    argss += "Begins by: ";
8467 	    argss +=g.print(contextptr);
8468 	  }
8469 	  return string2gen(argss,false);
8470 	}
8471       }
8472       args=args._SYMBptr->sommet;
8473     }
8474     string argss=args.print(contextptr);
8475     // remove space at the end if required
8476     while (!argss.empty() && argss[argss.size()-1]==' ')
8477       argss=argss.substr(0,argss.size()-1);
8478 #ifdef HAVE_LIBPARI
8479     if (argss.size()>5 && argss.substr(0,5)=="pari_")
8480       return string2gen(pari_help(string2gen(argss.substr(5,argss.size()-5),false)),false);
8481 #endif
8482     const char *cmdname=argss.c_str(),* howto=0, * syntax=0, * related=0, *examples=0;
8483     if (has_static_help(cmdname,lang,howto,syntax,examples,related)){
8484 #ifdef EMCC
8485       if (argss.size()>2 && argss[0]=='\'' && argss[argss.size()-1]=='\'')
8486 	argss=argss.substr(1,argss.size()-2);
8487       // should split related at commas, and display buttons
8488       // should split examples at semis, and display buttons
8489       string res="<b>"+argss+"</b> : "+string(howto)+"<br>";
8490       if (strlen(syntax))
8491 	res = res+argss+'('+string(syntax)+")<br>";
8492       else
8493 	res = res+"<br>";
8494       res = res+string(related)+"<br>";
8495       if (strlen(examples))
8496 	res = res +string(examples);
8497       return string2gen(res,false);
8498 #endif
8499 #ifdef NSPIRE
8500       if (argss.size()>2 && argss[0]=='\'' && argss[argss.size()-1]=='\'')
8501 	argss=argss.substr(1,argss.size()-2);
8502       COUT << howto << '\n' << "Syntax: " << argss << "(" << syntax << ")" << '\n' << "See also: " << related << '\n' ;
8503       COUT << "Examples: " << examples << '\n';
8504       return 1;
8505 #else
8506       return string2gen(string(howto?howto:"")+'\n'+string(syntax)+'\n'+string(related)+'\n'+string(examples),false);
8507 #endif
8508     }
8509 #ifndef GIAC_HAS_STO_38
8510     if (!vector_aide_ptr() || vector_aide_ptr()->empty()){
8511       if (!vector_aide_ptr())
8512 	vector_aide_ptr() = new vector<aide>;
8513       * vector_aide_ptr()=readhelp("aide_cas",helpitems,false);
8514       if (!helpitems){
8515 	* vector_aide_ptr()=readhelp(default_helpfile,helpitems);
8516       }
8517       if (!helpitems){
8518 	* vector_aide_ptr()=readhelp((giac_aide_dir()+"aide_cas").c_str(),helpitems);
8519       }
8520     }
8521 #endif
8522     if (vector_aide_ptr()){
8523       string s=argss; // args.print(contextptr);
8524       int l=int(s.size());
8525       if ( (l>2) && (s[0]=='\'') && (s[l-1]=='\'') )
8526 	s=s.substr(1,l-2);
8527       l=int(s.size());
8528       if (l && s[l-1]==')'){
8529 	int i=l-1;
8530 	for (;i;--i){
8531 	  if (s[i]=='(')
8532 	    break;
8533 	}
8534 	if (i)
8535 	  s=s.substr(0,i);
8536       }
8537       s=writehelp(helpon(s,*vector_aide_ptr(),lang,int(vector_aide_ptr()->size())),lang);
8538       return string2gen(s,false);
8539     }
8540     else
8541       return gensizeerr(gettext("No help file found"));
8542     // return 0;
8543   }
8544   static const char _findhelp_s []="findhelp";
8545   static define_unary_function_eval_quoted (__findhelp,&_findhelp,_findhelp_s);
8546   define_unary_function_ptr5( at_findhelp ,alias_at_findhelp,&__findhelp,_QUOTE_ARGUMENTS,true);
8547 
8548   static const char _help_s []="help";
8549   static define_unary_function_eval_quoted (__help,&_findhelp,_help_s);
8550   define_unary_function_ptr5( at_help ,alias_at_help,&__help,_QUOTE_ARGUMENTS,true);
8551 
_member(const gen & args,GIAC_CONTEXT)8552   gen _member(const gen & args,GIAC_CONTEXT){
8553     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8554     gen g=args;
8555     vecteur v;
8556     if (args.type!=_VECT){
8557       g=args.eval(eval_level(contextptr),contextptr);
8558       if (g.type!=_VECT)
8559 	return symbolic(at_member,args);
8560       v=*g._VECTptr;
8561     }
8562     else {
8563       v=*args._VECTptr;
8564       if (v.size()>1){
8565 	v[0]=eval(v[0],eval_level(contextptr),contextptr);
8566 	v[1]=eval(v[1],eval_level(contextptr),contextptr);
8567       }
8568     }
8569     int s=int(v.size());
8570     if (s<2)
8571       return gentoofewargs("");
8572     int i=-1;
8573     if (v[1].type==_MAP){
8574       const gen_map & m=*v[1]._MAPptr;
8575       gen_map::const_iterator it=m.find(v[0]),itend=m.end();
8576       return change_subtype(it!=itend,_INT_BOOLEAN);
8577     }
8578     if (v[0].type==_STRNG && v[1].type==_STRNG){
8579       string f=*v[0]._STRNGptr,s=*v[1]._STRNGptr;
8580       int pos=s.find(f);
8581       if (pos<0 || pos>=s.size())
8582 	i=0;
8583       else
8584 	i=pos+1;
8585     }
8586     else {
8587       if (v[1].type!=_VECT)
8588 	return gensizeerr(contextptr);
8589       i=equalposcomp(*v[1]._VECTptr,v[0]);
8590     }
8591     if (s==3){
8592       gen tmpsto;
8593       if (array_start(contextptr))
8594 	tmpsto=sto(i,v[2],contextptr);
8595       else
8596 	tmpsto=sto(i-1,v[2],contextptr);
8597       if (is_undef(tmpsto)) return tmpsto;
8598     }
8599     return i;
8600   }
8601   static const char _member_s []="member";
8602   static define_unary_function_eval_quoted (__member,&_member,_member_s);
8603   define_unary_function_ptr5( at_member ,alias_at_member,&__member,_QUOTE_ARGUMENTS,true);
8604 
8605   // tablefunc(expression,[var,min,step])
_tablefunc(const gen & args,GIAC_CONTEXT)8606   gen _tablefunc(const gen & args,GIAC_CONTEXT){
8607     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8608     gen f,x=vx_var,xstart=gnuplot_xmin,step=(gnuplot_xmax-gnuplot_xmin)/10;
8609     gen xmax=gnuplot_xmax;
8610     if (args.type==_VECT){
8611       vecteur & v=*args._VECTptr;
8612       int s=int(v.size());
8613       if (!s)
8614 	return gentoofewargs("");
8615       f=v[0];
8616       if (s>1)
8617 	x=v[1];
8618       if (s>2)
8619 	xstart=v[2];
8620       if (s>3)
8621 	step=v[3];
8622       if (s>4)
8623 	xmax=v[4];
8624     }
8625     else
8626       f=args;
8627     if (f.is_symb_of_sommet(at_program)){
8628       f=f[3];
8629       x=f[1];
8630     }
8631     vecteur l0(makevecteur(x,f));
8632     gen graphe=symbolic(at_plotfunc,
8633 			gen(makevecteur(_cell(makevecteur(vecteur(1,minus_one),vecteur(1,zero)),contextptr),
8634 					symb_equal(_cell(makevecteur(vecteur(1,minus_one),vecteur(1,minus_one)),contextptr),symb_interval(xstart,xmax))
8635 				    ),_SEQ__VECT));
8636     graphe.subtype=_SPREAD__SYMB;
8637     vecteur l1(makevecteur(step,graphe));
8638     gen l31(_cell(makevecteur(vecteur(1,minus_one),vecteur(1,zero)),contextptr)+_cell(makevecteur(plus_one,vecteur(1,zero)),contextptr));
8639     l31.subtype=_SPREAD__SYMB;
8640     gen l32(symb_evalf(symbolic(at_subst,gen(makevecteur(_cell(makevecteur(zero,vecteur(1,zero)),contextptr),_cell(makevecteur(zero,vecteur(1,minus_one)),contextptr),_cell(makevecteur(vecteur(1,zero),vecteur(1,minus_one)),contextptr)),_SEQ__VECT))));
8641     l32.subtype=_SPREAD__SYMB;
8642     vecteur l2(makevecteur(xstart,l32));
8643     vecteur l3(makevecteur(l31,l32));
8644     return makevecteur(l0,l1,l2,l3);
8645   }
8646   static const char _tablefunc_s []="tablefunc";
8647   static define_unary_function_eval (__tablefunc,&_tablefunc,_tablefunc_s);
8648   define_unary_function_ptr5( at_tablefunc ,alias_at_tablefunc,&__tablefunc,0,true);
8649 
8650   // tableseq(expression,[var,value])
8651   // var is a vector of dim the number of terms in the recurrence
_tableseq(const gen & args,GIAC_CONTEXT)8652   gen _tableseq(const gen & args,GIAC_CONTEXT){
8653     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8654     gen f,x=vx_var,uzero=zero;
8655     int dim=1;
8656     double xmin=gnuplot_xmin,xmax=gnuplot_xmax;
8657     if (args.type==_VECT){
8658       vecteur & v=*args._VECTptr;
8659       int s=int(v.size());
8660       if (!s)
8661 	return gentoofewargs("");
8662       f=v[0];
8663       if (s>1)
8664 	x=v[1];
8665       if (s>2)
8666 	uzero=evalf_double(v[2],1,contextptr);
8667       if (x.type==_VECT){
8668 	dim=int(x._VECTptr->size());
8669 	if (uzero.type!=_VECT)
8670 	  return gentypeerr(contextptr);
8671 	if (uzero._VECTptr->front().type==_VECT)
8672 	  uzero=uzero._VECTptr->front();
8673 	if ( (uzero.type!=_VECT) || (signed(uzero._VECTptr->size())!=dim) )
8674 	  return gendimerr(contextptr);
8675       }
8676       else {
8677 	if (uzero.type==_VECT && uzero._VECTptr->size()==3){
8678 	  vecteur & uv=*uzero._VECTptr;
8679 	  if (uv[1].type!=_DOUBLE_ || uv[2].type!=_DOUBLE_)
8680 	    return gensizeerr(contextptr);
8681 	  xmin=uv[1]._DOUBLE_val;
8682 	  xmax=uv[2]._DOUBLE_val;
8683 	  uzero=uv[0];
8684 	}
8685       }
8686     }
8687     else
8688       f=args;
8689     if (f.is_symb_of_sommet(at_program)){
8690       f=f[3];
8691       x=f[1];
8692     }
8693     vecteur res;
8694     res.push_back(f);
8695     if (x.type!=_VECT){
8696       res.push_back(x);
8697       if (dim!=1)
8698 	res.push_back(dim);
8699       else {
8700 	gen l31(symbolic(at_plotseq,
8701 		       gen(makevecteur(
8702 				       _cell(makevecteur(zero,vecteur(1,zero)),contextptr),
8703 				       symb_equal(_cell(makevecteur(vecteur(1,-1),vecteur(1,zero)),contextptr),makevecteur(_cell(makevecteur(vecteur(1,plus_one),vecteur(1,zero)),contextptr),xmin,xmax)),
8704 				       //symb_equal(_cell(makevecteur(plus_one,vecteur(1,zero)),contextptr),makevecteur(_cell(makevecteur(vecteur(1,plus_one),vecteur(1,zero)),contextptr),xmin,xmax)),
8705 				       9,at_tableseq),_SEQ__VECT
8706 			   )
8707 		       )
8708 	      );
8709 	l31.subtype=_SPREAD__SYMB;
8710 	res.push_back(l31);
8711       }
8712       res.push_back(uzero);
8713       gen l51(symb_evalf(symbolic(at_subst,gen(makevecteur(_cell(makevecteur(zero,vecteur(1,zero)),contextptr),_cell(makevecteur(plus_one,vecteur(1,zero)),contextptr),_cell(makevecteur(vecteur(1,minus_one),vecteur(1,zero)),contextptr)),_SEQ__VECT))));
8714       l51.subtype=_SPREAD__SYMB;
8715       res.push_back(l51);
8716     }
8717     else {
8718       for (int i=0;i<dim;++i)
8719 	res.push_back(x[i]);
8720       vecteur tmp1,tmp2;
8721       for (int i=0;i<dim;++i){
8722 	res.push_back(uzero[i]);
8723 	tmp1.push_back(_cell(makevecteur(i+1,vecteur(1,zero)),contextptr));
8724 	tmp2.push_back(_cell(makevecteur(vecteur(1,i-dim),vecteur(1,zero)),contextptr));
8725       }
8726       gen l41(symb_eval(symbolic(at_subst,gen(makevecteur(_cell(makevecteur(zero,vecteur(1,zero)),contextptr),tmp1,tmp2),_SEQ__VECT))));
8727       l41.subtype=_SPREAD__SYMB;
8728       res.push_back(l41);
8729     }
8730     return mtran(vecteur(1,res));
8731   }
8732   static const char _tableseq_s []="tableseq";
8733   static define_unary_function_eval_quoted (__tableseq,&_tableseq,_tableseq_s);
8734   define_unary_function_ptr5( at_tableseq ,alias_at_tableseq,&__tableseq,_QUOTE_ARGUMENTS,true);
8735 
protectevalorevalf(const gen & g,int level,bool approx,GIAC_CONTEXT)8736   gen protectevalorevalf(const gen & g,int level,bool approx,GIAC_CONTEXT){
8737     gen res;
8738 #ifdef HAVE_LIBGSL //
8739     gsl_set_error_handler_off();
8740 #endif //
8741     ctrl_c = false; interrupted=false;
8742     // save cas_setup in case of an exception
8743     vecteur cas_setup_save = cas_setup(contextptr);
8744     if (cas_setup_save.size()>5 && cas_setup_save[5].type==_VECT && cas_setup_save[5]._VECTptr->size()==2){
8745       vecteur & v = *cas_setup_save[5]._VECTptr;
8746       if (is_strictly_greater(v[0],1e-6,contextptr)){
8747 	*logptr(contextptr) << gettext("Restoring epsilon to 1e-6 from ") << v[0] << '\n';
8748 	epsilon(1e-6,contextptr);
8749       }
8750       if (is_strictly_greater(v[1],1e-6,contextptr)){
8751 	*logptr(contextptr) << gettext("Restoring proba epsilon to 1e-6 from ") << v[0] << '\n';
8752 	proba_epsilon(contextptr)=1e-6;
8753       }
8754       cas_setup_save=cas_setup(contextptr);
8755     }
8756     debug_struct dbg;
8757     dbg=*debug_ptr(contextptr);
8758 #ifndef NO_STDEXCEPT
8759     try {
8760 #endif
8761       res=approx?g.evalf(level,contextptr):g.eval(level,contextptr);
8762 #ifndef NO_STDEXCEPT
8763     }
8764     catch (std::runtime_error & e){
8765       last_evaled_argptr(contextptr)=NULL;
8766       *debug_ptr(contextptr)=dbg;
8767       res=string2gen(e.what(),false);
8768       res.subtype=-1;
8769       ctrl_c=false; interrupted=false;
8770       // something went wrong, so restore the old cas_setup
8771       cas_setup(cas_setup_save, contextptr);
8772     }
8773 #endif
8774     return res;
8775   }
8776 
protectevalf(const gen & g,int level,GIAC_CONTEXT)8777   gen protectevalf(const gen & g,int level, GIAC_CONTEXT){
8778     return protectevalorevalf(g,level,true,contextptr);
8779   }
8780 
protecteval(const gen & g,int level,GIAC_CONTEXT)8781   gen protecteval(const gen & g,int level, GIAC_CONTEXT){
8782     return protectevalorevalf(g,level,approx_mode(contextptr),contextptr);
8783   }
8784 
printasnodisp(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)8785   static string printasnodisp(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
8786     int maplemode=xcas_mode(contextptr) & 0x07;
8787     if (maplemode==1 || maplemode==2){
8788       string res=feuille.print(contextptr);
8789       int l=int(res.size()),j;
8790       for (j=l-1;j>=0 && res[j]==' ';--j)
8791 	;
8792       if (res[j]==';')
8793 	res[j]=':';
8794       else
8795 	res += ':';
8796       return res;
8797     }
8798     return sommetstr+("("+feuille.print(contextptr)+")");
8799   }
_nodisp(const gen & args,GIAC_CONTEXT)8800   gen _nodisp(const gen & args,GIAC_CONTEXT){
8801     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8802     return string2gen("Done",false);
8803   }
8804   static const char _nodisp_s []="nodisp";
8805   static define_unary_function_eval2 (__nodisp,(const gen_op_context)_nodisp,_nodisp_s,&printasnodisp);
8806   define_unary_function_ptr5( at_nodisp ,alias_at_nodisp,&__nodisp,0,true);
8807 
_unapply(const gen & args,GIAC_CONTEXT)8808   gen _unapply(const gen & args,GIAC_CONTEXT){
8809     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8810     if ( (args.type!=_VECT) || args._VECTptr->empty() )
8811       return gentypeerr(contextptr);
8812     vecteur v=*args._VECTptr,w;
8813     int s=int(v.size());
8814     if (s<2)
8815       w=vecteur(1,vx_var);
8816     else {
8817       if (s==2 && v[1].type==_VECT)
8818 	w=*v[1]._VECTptr;
8819       else
8820 	w=vecteur(v.begin()+1,v.end());
8821     }
8822     gen g=subst(v[0].eval(eval_level(contextptr),contextptr),w,w,false,contextptr);
8823     if (g.type==_VECT && !g.subtype)
8824       g=makevecteur(g);
8825     return symbolic(at_program,gen(makevecteur(gen(w,_SEQ__VECT),w*zero,g),_SEQ__VECT));
8826   }
8827   static const char _unapply_s []="unapply";
8828   static define_unary_function_eval_quoted (__unapply,&_unapply,_unapply_s);
8829   define_unary_function_ptr5( at_unapply ,alias_at_unapply,&__unapply,_QUOTE_ARGUMENTS,true);
8830 
_makevector(const gen & args,GIAC_CONTEXT)8831   gen _makevector(const gen & args,GIAC_CONTEXT){
8832     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8833     if (args.type!=_VECT)
8834       return vecteur(1,args);
8835     vecteur & v=*args._VECTptr;
8836     if (ckmatrix(args))
8837       return gen(v,_MATRIX__VECT);
8838     return v;
8839   }
8840   static const char _makevector_s []="makevector";
8841   static define_unary_function_eval (__makevector,&_makevector,_makevector_s);
8842   define_unary_function_ptr5( at_makevector ,alias_at_makevector,&__makevector,0,true);
8843 
8844 
_makesuite(const gen & args,GIAC_CONTEXT)8845   gen _makesuite(const gen & args,GIAC_CONTEXT){
8846     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8847     if (args.type!=_VECT)
8848       return vecteur(1,args);
8849     vecteur & v=*args._VECTptr;
8850     return gen(v,_SEQ__VECT);
8851   }
8852   static const char _makesuite_s []="makesuite";
8853   static define_unary_function_eval (__makesuite,&_makesuite,_makesuite_s);
8854   define_unary_function_ptr5( at_makesuite ,alias_at_makesuite,&__makesuite,0,true);
8855 
_matrix(const gen & g,const context * contextptr)8856   gen _matrix(const gen & g,const context * contextptr){
8857     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
8858     if (g.type==_MAP){
8859       vecteur res;
8860       if (!convert(*g._MAPptr,res))
8861 	return gensizeerr(contextptr);
8862       return res;
8863     }
8864     if (g.type==_INT_) return _makemat(g,contextptr);
8865     if (g.type!=_VECT)
8866       return gentypeerr(contextptr);
8867     vecteur v=*g._VECTptr;
8868     if (ckmatrix(v))
8869       return gen(v,_MATRIX__VECT);
8870     int vs=int(v.size());
8871     if (vs<2)
8872       return gentypeerr(contextptr);
8873     if (vs==2 && v[0].type==_INT_ && v[1].type==_VECT){
8874       int l=giacmax(v[0].val,0);
8875       vecteur res(l);
8876       vecteur w(*v[1]._VECTptr);
8877       if (ckmatrix(w))
8878 	aplatir(*v[1]._VECTptr,w);
8879       int s=giacmin(l,int(w.size()));
8880       for (int i=0;i<s;++i)
8881 	res[i]=w[i];
8882       return gen(res,_MATRIX__VECT);
8883     }
8884     if (vs==2){
8885       v.push_back(zero);
8886       ++vs;
8887     }
8888     if ( (v[0].type!=_INT_) || (v[1].type!=_INT_) )
8889       return gensizeerr(contextptr);
8890     int l(giacmax(v[0].val,1)),c(giacmax(v[1].val,1));
8891     if (l*longlong(c)>LIST_SIZE_LIMIT)
8892       return gendimerr(contextptr);
8893     if (vs==3 && v[2].type<=_IDNT){
8894       vecteur res(l);
8895       for (int i=0;i<l;++i)
8896 	res[i]=vecteur(c,v[2]);
8897       return gen(res,_MATRIX__VECT);
8898     }
8899     bool transpose=(vs>3);
8900     if (transpose){ // try to merge arguments there
8901       // v[2]..v[vs-1] represents flattened submatrices
8902       vecteur v2;
8903       for (int i=2;i<vs;++i){
8904 	if (v[i].type!=_VECT)
8905 	  return gentypeerr(contextptr);
8906 	vecteur & w = *v[i]._VECTptr;
8907 	int vis=int(w.size());
8908 	if (vis % l)
8909 	  return gendimerr(contextptr);
8910 	int nc=vis/l;
8911 	for (int J=0;J<nc;++J){
8912 	  for (int I=J;I<vis;I+=nc)
8913 	    v2.push_back(w[I]);
8914 	}
8915       }
8916       v[2]=v2;
8917       swapint(l,c);
8918     }
8919     if (v[2].type==_VECT){
8920       vecteur w=*v[2]._VECTptr;
8921       int s=int(w.size());
8922       if (ckmatrix(w)){
8923 	int ss=0;
8924 	if (s)
8925 	  ss=int(w[0]._VECTptr->size());
8926 	int ll=giacmin(l,s);
8927 	for (int i=0;i<ll;++i){
8928 	  if (ss<c)
8929 	    w[i]=mergevecteur(*w[i]._VECTptr,vecteur(c-ss));
8930 	  else
8931 	    w[i]=vecteur(w[i]._VECTptr->begin(),w[i]._VECTptr->begin()+c);
8932 	}
8933 	if (s<l)
8934 	  w=mergevecteur(w,vecteur(l-s,vecteur(c)));
8935 	else
8936 	  w=vecteur(w.begin(),w.begin()+l);
8937 	return gen(makefreematrice(w),_MATRIX__VECT);
8938       }
8939       else {
8940 	vecteur res;
8941 	if (s<l*c)
8942 	  w=mergevecteur(w,vecteur(l*c-s));
8943 	for (int i=0;i<l;++i)
8944 	  res.push_back(vecteur(w.begin()+i*c,w.begin()+(i+1)*c));
8945 	if (transpose)
8946 	  res=mtran(res);
8947 	return gen(makefreematrice(res),_MATRIX__VECT);
8948       }
8949     }
8950     // v[2] as a function, should take 2 args
8951     gen f=v[2];
8952     if (!f.is_symb_of_sommet(at_program))
8953       return gen(vecteur(l,vecteur(c,f)),_MATRIX__VECT);
8954     vecteur res(l);
8955     int decal=array_start(contextptr); //(xcas_mode(contextptr)!=0);
8956     for (int i=decal;i<l+decal;++i){
8957       vecteur tmp(c);
8958       for (int j=decal;j<c+decal;++j)
8959 	tmp[j-decal]=f(gen(makevecteur(i,j),_SEQ__VECT),contextptr);
8960       res[i-decal]=tmp;
8961     }
8962     return gen(res,_MATRIX__VECT);
8963   }
8964   static const char _matrix_s []="matrix";
8965   static define_unary_function_eval (__matrix,&_matrix,_matrix_s);
8966   define_unary_function_ptr5( at_matrix ,alias_at_matrix,&__matrix,0,true);
8967 
printasbreak(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)8968   static string printasbreak(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
8969     if (abs_calc_mode(contextptr)==38)
8970       return "BREAK ";
8971     if (xcas_mode(contextptr)==3)
8972       return "Exit ";
8973     else
8974       return sommetstr;
8975   }
_break(const gen & args,GIAC_CONTEXT)8976   gen _break(const gen & args,GIAC_CONTEXT){
8977     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8978     return symbolic(at_break,0);
8979   }
8980   static const char _break_s []="break";
8981   static define_unary_function_eval2_index (104,__break,&_break,_break_s,&printasbreak);
8982   define_unary_function_ptr5( at_break ,alias_at_break ,&__break,0,T_BREAK);
8983 
printascontinue(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)8984   static string printascontinue(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
8985     if (abs_calc_mode(contextptr)==38)
8986       return "CONTINUE ";
8987     if (xcas_mode(contextptr)==3)
8988       return "Cycle ";
8989     else
8990       return sommetstr;
8991   }
_continue(const gen & args,GIAC_CONTEXT)8992   gen _continue(const gen & args,GIAC_CONTEXT){
8993     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
8994     return symbolic(at_continue,0);
8995   }
8996   static const char _continue_s []="continue";
8997   static define_unary_function_eval2_index (106,__continue,&_continue,_continue_s,&printascontinue);
8998   define_unary_function_ptr( at_continue ,alias_at_continue ,&__continue);
8999 
printaslabel(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)9000   static string printaslabel(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
9001     if (xcas_mode(contextptr)==3)
9002       return "Lbl "+feuille.print(contextptr);
9003     else
9004       return "label "+feuille.print(contextptr);
9005   }
_label(const gen & args,GIAC_CONTEXT)9006   gen _label(const gen & args,GIAC_CONTEXT){
9007     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9008     return symbolic(at_label,args);
9009   }
9010   static const char _label_s []="label";
9011   static define_unary_function_eval2 (__label,&_label,_label_s,&printaslabel);
9012   define_unary_function_ptr5( at_label ,alias_at_label ,&__label,0,T_RETURN);
9013 
printasgoto(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)9014   static string printasgoto(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
9015     if (xcas_mode(contextptr)==3)
9016       return "Goto "+feuille.print(contextptr);
9017     else
9018       return "goto "+feuille.print(contextptr);
9019   }
_goto(const gen & args,GIAC_CONTEXT)9020   gen _goto(const gen & args,GIAC_CONTEXT){
9021     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9022     if (args.type==_VECT && args.subtype==_SEQ__VECT && args._VECTptr->size()==2)
9023       return _position(change_subtype(args,0),contextptr);
9024     return symbolic(at_goto,args);
9025   }
9026   static const char _goto_s []="goto";
9027   static define_unary_function_eval2 (__goto,&_goto,_goto_s,&printasgoto);
9028   define_unary_function_ptr5( at_goto ,alias_at_goto ,&__goto,0,T_RETURN);
9029 
9030   /*
9031   static vecteur local_vars(const vecteur & v,GIAC_CONTEXT){
9032     const_iterateur it=v.begin(),itend=v.end();
9033     vecteur res;
9034     for (;it!=itend;++it){
9035       if (it->type==_IDNT &&
9036 	  (contextptr?contextptr->tabptr->find(*it->_IDNTptr->name)==contextptr->tabptr->end():(!it->_IDNTptr->localvalue || it->_IDNTptr->localvalue->empty()))
9037 	  )
9038 	res.push_back(*it);
9039     }
9040     return res;
9041   }
9042   */
printastilocal(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)9043   static string printastilocal(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
9044     if ( (feuille.type!=_VECT) || (feuille._VECTptr->size()!=2) )
9045       return gettext("invalid |");
9046     return string("(")+feuille._VECTptr->front().print(contextptr)+string("|")+feuille._VECTptr->back().print(contextptr)+')';
9047   }
_tilocal(const gen & args,const context * contextptr)9048   gen _tilocal(const gen & args,const context * contextptr){
9049     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9050     if (args.type!=_VECT || args._VECTptr->size()!=2)
9051       return symbolic(at_tilocal,args);
9052     vecteur & v=*args._VECTptr;
9053     if (v[1].type==_INT_)
9054       return _bitor(args,contextptr);
9055     if (is_equal(v.front()))
9056       return symb_equal(_tilocal(makesequence((v.front()._SYMBptr->feuille)[0],v.back()),contextptr),_tilocal(makesequence((v.front()._SYMBptr->feuille)[1],v.back()),contextptr));
9057     // find local variables
9058     vecteur cond(gen2vecteur(v[1]));
9059     vecteur docond,vars;
9060     const_iterateur it=cond.begin(),itend=cond.end();
9061     for (;it!=itend;++it){
9062       if (it->type!=_SYMB)
9063 	continue;
9064       unary_function_ptr & u=it->_SYMBptr->sommet;
9065       gen & g=it->_SYMBptr->feuille;
9066       if ( (g.type!=_VECT) || (g._VECTptr->empty()) )
9067 	return gensizeerr(contextptr);
9068       if (u==at_equal || u==at_equal2){
9069 	gen tmp=g._VECTptr->front(),tmp2=g._VECTptr->back();
9070 	if (tmp.type==_IDNT){
9071 	  gen tmp1(eval(tmp,eval_level(contextptr),contextptr));
9072 	  if (tmp1.type==_IDNT)
9073 	    tmp=tmp1;
9074 	  tmp.subtype=0; // otherwise if inside a folder sto will affect tmp!
9075 	  vars.push_back(tmp);
9076 	  tmp2=subst(tmp2,tmp,symb_quote(tmp),false,contextptr);
9077 	}
9078 	docond.push_back(symbolic(at_sto,gen(makevecteur(tmp2,tmp),_SEQ__VECT)));
9079 	continue;
9080       }
9081       if (u==at_sto){
9082 	if (g._VECTptr->back().type==_IDNT)
9083 	  vars.push_back(g._VECTptr->back());
9084 	docond.push_back(*it);
9085 	continue;
9086       }
9087       gen gf=g._VECTptr->front();
9088       if (gf.type==_IDNT)
9089 	vars.push_back(gf);
9090       if (gf.type==_SYMB && gf._SYMBptr->feuille.type==_VECT && gf._SYMBptr->feuille._VECTptr->size()==2 && gf._SYMBptr->feuille._VECTptr->front().type==_IDNT)
9091 	vars.push_back(gf._SYMBptr->feuille._VECTptr->front());
9092       if (it->type==_SYMB && it->_SYMBptr->sommet!=at_superieur_strict && it->_SYMBptr->sommet!=at_superieur_egal && it->_SYMBptr->sommet!=at_inferieur_strict && it->_SYMBptr->sommet!=at_inferieur_egal &&it->_SYMBptr->sommet!=at_and)
9093 	return gensizeerr(gettext("Invalid |"));
9094       docond.push_back(symbolic(at_assume,*it));
9095     }
9096     vecteur v0(vars.size(),zero);
9097     gen gv(v[0]);
9098     // Replace v[0] by its value if it is a global identifier
9099     if (gv.type==_IDNT){
9100       if (contextptr){
9101 	sym_tab::const_iterator it=contextptr->tabptr->find(gv._IDNTptr->id_name),itend=contextptr->tabptr->end();
9102 	if (it!=itend)
9103 	  gv=it->second;
9104       }
9105       else {
9106 	if (gv._IDNTptr->value)
9107 	  gv=*gv._IDNTptr->value;
9108       }
9109     }
9110     /*
9111     // Replace local variables by their value in gv
9112     vecteur vname(*_lname(gv,contextptr)._VECTptr),docondvar(*_lname(docond,contextptr)._VECTptr);
9113     vecteur vval(vname);
9114     iterateur jt=vval.begin(),jtend=vval.end();
9115     for (;jt!=jtend;++jt){
9116       if (jt->type!=_IDNT || equalposcomp(docondvar,*jt))
9117 	continue;
9118       if (contextptr){
9119 	sym_tab::const_iterator kt=contextptr->tabptr->find(*jt->_IDNTptr->name);
9120 	if (kt!=contextptr->tabptr->end())
9121 	  *jt=kt->second;
9122       }
9123       else {
9124 	if (jt->_IDNTptr->localvalue && !jt->_IDNTptr->localvalue->empty())
9125 	  *jt=jt->_IDNTptr->localvalue->back();
9126       }
9127     }
9128     gv=quotesubst(gv,vname,vval,contextptr);
9129     */
9130     // Replace vars global IDNT by local IDNT
9131     vecteur vname=vars;
9132     iterateur jt=vname.begin(),jtend=vname.end();
9133     for (;jt!=jtend;++jt)
9134       jt->subtype=_GLOBAL__EVAL;
9135     vecteur vval=vars;
9136     jt=vval.begin(),jtend=vval.end();
9137     for (;jt!=jtend;++jt)
9138       jt->subtype=0;
9139     gv=quotesubst(gv,vname,vval,contextptr);
9140     docond=*quotesubst(docond,vname,vval,contextptr)._VECTptr;
9141     gen prg=symb_program(gen(vname,_SEQ__VECT),gen(v0,_SEQ__VECT),symb_bloc(makevecteur(docond,gv)),contextptr);
9142     return prg(gen(v0,_SEQ__VECT),contextptr);
9143   }
9144   static const char _tilocal_s []="|";
9145   static define_unary_function_eval4_index (103,__tilocal,&_tilocal,_tilocal_s,&printastilocal,&texprintsommetasoperator);
9146   define_unary_function_ptr5( at_tilocal ,alias_at_tilocal,&__tilocal,_QUOTE_ARGUMENTS,0);
9147 
printasdialog(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)9148   static string printasdialog(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
9149     return "Dialog "+symbolic(at_bloc,feuille).print(contextptr)+indent(contextptr)+"EndDialog";
9150   }
printasinputform(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)9151   string printasinputform(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
9152     if (xcas_mode(contextptr)==3)
9153       return printasdialog(feuille,sommetstr,contextptr);
9154     return sommetstr+("("+feuille.print(contextptr)+")");
9155   }
9156 
9157   // Eval everything except IDNT and symbolics with
inputform_pre_analysis(const gen & g,GIAC_CONTEXT)9158   vecteur inputform_pre_analysis(const gen & g,GIAC_CONTEXT){
9159     vecteur v(gen2vecteur(g));
9160     if (python_compat(contextptr)){
9161       gen g_=eval(g,1,contextptr);
9162       if (g_.type!=_STRNG)
9163 	g_=string2gen(g_.print(contextptr),false);
9164       v=makevecteur(g_,g_,identificateur("_input_"),1);
9165       // v=gen2vecteur(eval(g,1,contextptr));
9166     }
9167     int s=int(v.size());
9168     for (int i=0;i<s;++i){
9169       if (v[i].type==_IDNT || v[i].type!=_SYMB)
9170 	continue;
9171       unary_function_ptr & u =v[i]._SYMBptr->sommet;
9172       if ( (u==at_output) || (u==at_Text) || (u==at_Title) || (u==at_click) || (u==at_Request) || (u==at_choosebox) || (u==at_DropDown) || (u==at_Popup) || u==at_of || u==at_at)
9173 	continue;
9174       v[i]=protecteval(v[i],eval_level(contextptr),contextptr);
9175     }
9176     return v;
9177   }
inputform_post_analysis(const vecteur & v,const gen & res,GIAC_CONTEXT)9178   gen inputform_post_analysis(const vecteur & v,const gen & res,GIAC_CONTEXT){
9179     gen tmp=res.eval(eval_level(contextptr),contextptr);
9180     if (tmp.type==_VECT && !tmp._VECTptr->empty() && python_compat(contextptr))
9181       return tmp._VECTptr->back();
9182     return tmp;
9183   }
9184   // user input sent back to the parent process
_inputform(const gen & args,GIAC_CONTEXT)9185   gen _inputform(const gen & args,GIAC_CONTEXT){
9186     if (interactive_op_tab && interactive_op_tab[1])
9187       return interactive_op_tab[1](args,contextptr);
9188     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9189     string cs(gettext("inputform may be used in a window environment only"));
9190 #if defined WIN32 || (!defined HAVE_SIGNAL_H_OLD)
9191     *logptr(contextptr) << cs << '\n';
9192     return string2gen(cs,false);
9193 #else
9194     if (child_id){
9195       *logptr(contextptr) << cs << '\n';
9196       return string2gen(cs,false);
9197     }
9198     // pre-analysis
9199     vecteur v(gen2vecteur(args));
9200     // int vs=signed(v.size());
9201     gen res;
9202     // form
9203     ofstream child_out(cas_sortie_name().c_str());
9204     gen e(symbolic(at_inputform,args));
9205     *logptr(contextptr) << gettext("Archiving ") << e << '\n';
9206     archive(child_out,e,contextptr);
9207     archive(child_out,e,contextptr);
9208     if ( (args.type==_VECT) && (args._VECTptr->empty()) )
9209       child_out << "User input requested\n" << '¤' ;
9210     else
9211       child_out << args << '¤' ;
9212     child_out.close();
9213     kill_and_wait_sigusr2();
9214     ifstream child_in(cas_entree_name().c_str());
9215     res= unarchive(child_in,contextptr);
9216     child_in.close();
9217     *logptr(contextptr) << gettext("Inputform reads ") << res << '\n';
9218     // post analysis
9219     return inputform_post_analysis(v,res,contextptr);
9220 #endif
9221   }
9222   static const char _inputform_s []="inputform";
9223 #if defined RTOS_THREADX || defined NSPIRE
9224   static define_unary_function_eval(__inputform,&_inputform,_inputform_s);
9225 #else
9226   unary_function_eval __inputform(1,&_inputform,_inputform_s,&printasinputform);
9227 #endif
9228   define_unary_function_ptr5( at_inputform ,alias_at_inputform,&__inputform,_QUOTE_ARGUMENTS,true);
9229 
_choosebox(const gen & args,GIAC_CONTEXT)9230   gen _choosebox(const gen & args,GIAC_CONTEXT){
9231     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9232     return __inputform.op(symbolic(at_choosebox,args),contextptr);
9233   }
9234   static const char _choosebox_s []="choosebox";
9235   static define_unary_function_eval_quoted (__choosebox,&_choosebox,_choosebox_s);
9236   define_unary_function_ptr5( at_choosebox ,alias_at_choosebox,&__choosebox,_QUOTE_ARGUMENTS,true);
9237 
_output(const gen & args,GIAC_CONTEXT)9238   gen _output(const gen & args,GIAC_CONTEXT){
9239     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9240     return __inputform.op(symbolic(at_output,args),contextptr);
9241   }
9242   static const char _output_s []="output";
9243   static define_unary_function_eval_quoted (__output,&_output,_output_s);
9244   define_unary_function_ptr5( at_output ,alias_at_output,&__output,_QUOTE_ARGUMENTS,true);
9245 
_input(const gen & args,bool textinput,GIAC_CONTEXT)9246   gen _input(const gen & args,bool textinput,GIAC_CONTEXT){
9247     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9248     vecteur v(gen2vecteur(args));
9249     gen res(args);
9250     if (python_compat(contextptr)){
9251       res=eval(args,1,contextptr);
9252       if (res.type!=_STRNG)
9253 	res=string2gen(res.print(contextptr),false);
9254 #ifdef GIAC_HAS_STO_38
9255       if (res.type==_STRNG)
9256 	res=string2gen(aspen_input(res._STRNGptr->c_str()),false);
9257       return res;
9258 #endif
9259       return __click.op(makevecteur(res,0,identificateur("_input_"),1),contextptr);
9260     }
9261     const_iterateur it=v.begin(),itend=v.end();
9262     if (it==itend)
9263       return __click.op(args,contextptr);
9264     if (res.type==_STRNG){
9265       return __click.op(res,contextptr);
9266     }
9267     for (;it!=itend;++it){
9268       if (it->type==_IDNT || it->is_symb_of_sommet(at_at) || it->is_symb_of_sommet(at_of)){
9269 	if (textinput)
9270 	  res=__click.op(makevecteur(string2gen(it->print(contextptr)),0,*it,1),contextptr);
9271 	else
9272 	  res=__click.op(makevecteur(string2gen(it->print(contextptr),false),0,*it),contextptr);
9273       }
9274       if (it+1==itend)
9275 	break;
9276       if (it->type==_STRNG && ( (it+1)->type==_IDNT || (it+1)->is_symb_of_sommet(at_at) || (it+1)->is_symb_of_sommet(at_of))){
9277 	if (textinput)
9278 	  res=__click.op(makevecteur(*it,0,*(it+1),1),contextptr);
9279 	else
9280 	  res=__click.op(makevecteur(*it,0,*(it+1)),contextptr);
9281 	++it;
9282       }
9283     }
9284     if (is_zero(res))
9285       return gensizeerr(contextptr);
9286     return res;
9287   }
9288 
printastifunction(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)9289   string printastifunction(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
9290     if (feuille.type==_VECT && feuille.subtype==_SEQ__VECT){
9291       if (feuille._VECTptr->empty())
9292 	return string(sommetstr)+" ";
9293       else
9294 	return sommetstr+(" ("+feuille.print(contextptr)+')');
9295     }
9296     return sommetstr+(" "+feuille.print(contextptr));
9297   }
_Text(const gen & args,GIAC_CONTEXT)9298   gen _Text(const gen & args,GIAC_CONTEXT){
9299     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9300     return __inputform.op(symbolic(at_Text,args),contextptr);
9301   }
9302   static const char _Text_s []="Text";
9303   static define_unary_function_eval2_quoted (__Text,&_Text,_Text_s,&printastifunction);
9304   define_unary_function_ptr5( at_Text ,alias_at_Text,&__Text,_QUOTE_ARGUMENTS,0);
9305 
_Title(const gen & args,GIAC_CONTEXT)9306   gen _Title(const gen & args,GIAC_CONTEXT){
9307     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9308     return __inputform.op(symbolic(at_Title,args),contextptr);
9309   }
9310   static const char _Title_s []="Title";
9311   static define_unary_function_eval2_quoted (__Title,&_Title,_Title_s,&printastifunction);
9312   define_unary_function_ptr5( at_Title ,alias_at_Title,&__Title,_QUOTE_ARGUMENTS,0);
9313 
_Request(const gen & args,GIAC_CONTEXT)9314   gen _Request(const gen & args,GIAC_CONTEXT){
9315     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9316     return __inputform.op(symbolic(at_Request,args),contextptr);
9317   }
9318   static const char _Request_s []="Request";
9319   static define_unary_function_eval2_quoted (__Request,&_Request,_Request_s,&printastifunction);
9320   define_unary_function_ptr5( at_Request ,alias_at_Request,&__Request,_QUOTE_ARGUMENTS,0);
9321 
_DropDown(const gen & args,GIAC_CONTEXT)9322   gen _DropDown(const gen & args,GIAC_CONTEXT){
9323     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9324     return __inputform.op(symbolic(at_DropDown,args),contextptr);
9325   }
9326   static const char _DropDown_s []="DropDown";
9327   static define_unary_function_eval2_quoted (__DropDown,&_DropDown,_DropDown_s,&printastifunction);
9328   define_unary_function_ptr5( at_DropDown ,alias_at_DropDown,&__DropDown,_QUOTE_ARGUMENTS,0);
9329 
_Popup(const gen & args,GIAC_CONTEXT)9330   gen _Popup(const gen & args,GIAC_CONTEXT){
9331     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9332     return __inputform.op(symbolic(at_Popup,args),contextptr);
9333   }
9334   static const char _Popup_s []="Popup";
9335   static define_unary_function_eval2_quoted (__Popup,&_Popup,_Popup_s,&printastifunction);
9336   define_unary_function_ptr5( at_Popup ,alias_at_Popup,&__Popup,_QUOTE_ARGUMENTS,0);
9337 
_Dialog(const gen & args,GIAC_CONTEXT)9338   gen _Dialog(const gen & args,GIAC_CONTEXT){
9339     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9340     return __inputform.op(args,contextptr);
9341   }
9342   static const char _Dialog_s []="Dialog";
9343   static define_unary_function_eval2_index (89,__Dialog,&_Dialog,_Dialog_s,&printasdialog);
9344   define_unary_function_ptr5( at_Dialog ,alias_at_Dialog,&__Dialog,_QUOTE_ARGUMENTS,0);
9345 
_expr(const gen & args,GIAC_CONTEXT)9346   gen _expr(const gen & args,GIAC_CONTEXT){
9347     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9348     if (args.type==_VECT && args._VECTptr->size()==2 && args._VECTptr->front().type==_STRNG && args._VECTptr->back().type==_INT_){
9349       int mode=args._VECTptr->back().val;
9350       bool rpnmode=mode<0;
9351       mode=absint(mode) % 256;
9352       if (mode>3)
9353 	return gensizeerr(contextptr);
9354       int save_mode=xcas_mode(contextptr);
9355       bool save_rpnmode=rpn_mode(contextptr);
9356       xcas_mode(contextptr)=mode;
9357       rpn_mode(contextptr)=rpnmode;
9358       gen res=eval(gen(*args._VECTptr->front()._STRNGptr,contextptr),eval_level(contextptr),contextptr);
9359       xcas_mode(contextptr)=save_mode;
9360       rpn_mode(contextptr)=save_rpnmode;
9361       return res;
9362     }
9363     if (args.type==_VECT && args._VECTptr->size()==2 && args._VECTptr->front().type==_STRNG && args._VECTptr->back()==at_quote)
9364       return gen(*args._VECTptr->front()._STRNGptr,contextptr);
9365     if (args.type==_VECT && !args._VECTptr->empty() && args._VECTptr->front().type==_FUNC){
9366       vecteur v(args._VECTptr->begin()+1,args._VECTptr->end());
9367       return symbolic(*args._VECTptr->front()._FUNCptr,gen(v,_SEQ__VECT));
9368     }
9369     if (args.type!=_STRNG)
9370       return symbolic(at_expr,args);
9371     return eval(gen(*args._STRNGptr,contextptr),eval_level(contextptr),contextptr);
9372   }
9373   static const char _expr_s []="expr";
9374   static define_unary_function_eval (__expr,&_expr,_expr_s);
9375   define_unary_function_ptr5( at_expr ,alias_at_expr,&__expr,0,true);
9376 
9377   static const char _execute_s []="execute";
9378   static define_unary_function_eval (__execute,&_expr,_execute_s);
9379   define_unary_function_ptr5( at_execute ,alias_at_execute,&__execute,0,true);
9380 
_string(const gen & args,GIAC_CONTEXT)9381   gen _string(const gen & args,GIAC_CONTEXT){
9382     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9383     int maxp=MAX_PRINTABLE_ZINT;
9384     MAX_PRINTABLE_ZINT=1000000;
9385     string res;
9386     if (args.type==_VECT && args.subtype==_SEQ__VECT){
9387       const_iterateur it=args._VECTptr->begin(),itend=args._VECTptr->end();
9388       for (;it!=itend;){
9389 	if (it->type!=_STRNG){
9390 	  res += it->print(contextptr);
9391 	  ++it;
9392 	  if (it!=itend)
9393 	    res += ',';
9394 	  continue;
9395 	}
9396 	res += *it->_STRNGptr;
9397 	++it;
9398 	if (it==itend)
9399 	  return string2gen(res,false);
9400 	if (it->type==_STRNG)
9401 	  res += '\n';
9402       }
9403     }
9404     else
9405       res=args.print(contextptr);
9406     MAX_PRINTABLE_ZINT=maxp;
9407     return string2gen(res,false);
9408   }
9409   static const char _string_s []="string";
9410   static define_unary_function_eval (__string,&_string,_string_s);
9411   define_unary_function_ptr5( at_string ,alias_at_string,&__string,0,true);
9412 
9413   static const char _str_s []="str";
9414   static define_unary_function_eval (__str,&_string,_str_s);
9415   define_unary_function_ptr5( at_str ,alias_at_str,&__str,0,true);
9416 
_part(const gen & args,GIAC_CONTEXT)9417   gen _part(const gen & args,GIAC_CONTEXT){
9418     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9419     if ( (args.type==_VECT) && args._VECTptr->size()==2 ){
9420       gen & i=args._VECTptr->back();
9421       gen & g=args._VECTptr->front();
9422       if (i.type!=_INT_ || i.val<=0){
9423 	if (g.type!=_SYMB)
9424 	  return string2gen(g.print(contextptr),false);
9425 	else
9426 	  return string2gen(g._SYMBptr->sommet.ptr()->s,false);
9427       }
9428       else {
9429 	if (g.type!=_SYMB){
9430 	  if (i.val!=1)
9431 	    return gensizeerr(contextptr);
9432 	  return g;
9433 	}
9434 	else {
9435 	  vecteur v(gen2vecteur(g._SYMBptr->feuille));
9436 	  if (signed(v.size())<i.val)
9437 	    return gensizeerr(contextptr);
9438 	  return v[i.val-1];
9439 	}
9440       }
9441     }
9442     if (args.type==_SYMB)
9443       return int(gen2vecteur(args._SYMBptr->feuille).size());
9444     return 0;
9445   }
9446   static const char _part_s []="part";
9447   static define_unary_function_eval (__part,&_part,_part_s);
9448   define_unary_function_ptr5( at_part ,alias_at_part,&__part,0,true);
9449 
tiasc_translate(const string & s)9450   string tiasc_translate(const string & s){
9451     int l=int(s.size());
9452     string t("");
9453     for (int i=0;i<l;++i){
9454       char c=s[i];
9455       if (c=='\r')
9456 	continue;
9457       if (c=='@'){
9458 	t += "//";
9459 	continue;
9460       }
9461       if (c=='\\'){
9462 	++i;
9463 	string ti_escape("");
9464 	for (;i<l;++i){
9465 	  char c=s[i];
9466 	  if (c=='\\' || c==' '){
9467 	    break;
9468 	  }
9469 	  ti_escape += c;
9470 	}
9471 	if (i==l || c==' ')
9472 	  return t+"::"+ti_escape;
9473 	if (ti_escape=="->"){
9474 	  t += "=>";
9475 	  continue;
9476 	}
9477 	if (ti_escape=="(C)"){ // comment
9478 	  t += "//";
9479 	  continue;
9480 	}
9481 	if (ti_escape=="(-)"){
9482 	  t += '-';
9483 	  continue;
9484 	}
9485 	if (ti_escape=="e"){
9486 	  t += "exp(1)";
9487 	  continue;
9488 	}
9489 	if (ti_escape=="i"){
9490 	  t += '\xa1';
9491 	  continue;
9492 	}
9493 	t += ti_escape;
9494       }
9495       else
9496 	t += c;
9497     }
9498     if (t==string(t.size(),' '))
9499       return "";
9500     return t;
9501   }
9502 
_Pause(const gen & g,GIAC_CONTEXT)9503   gen _Pause(const gen & g,GIAC_CONTEXT){
9504     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
9505     gen g1=g;
9506     if (is_integer(g1) || g1.type==_REAL)
9507       g1=evalf_double(g,1,contextptr);
9508     if (g1.type==_DOUBLE_){
9509       wait_1ms(g1._DOUBLE_val*1000);
9510     }
9511     else
9512       __interactive.op(symbolic(at_Pause,g),contextptr);
9513     return 0;
9514   }
9515   static const char _Pause_s []="Pause";
9516   static define_unary_function_eval2 (__Pause,&_Pause,_Pause_s,&printastifunction);
9517   define_unary_function_ptr5( at_Pause ,alias_at_Pause ,&__Pause,0,T_RETURN);
9518 
9519   static const char _sleep_s []="sleep";
9520   static define_unary_function_eval (__sleep,&_Pause,_sleep_s);
9521   define_unary_function_ptr5( at_sleep ,alias_at_sleep,&__sleep,0,true);
9522 
_monotonic(const gen & g,GIAC_CONTEXT)9523   gen _monotonic(const gen & g,GIAC_CONTEXT){
9524     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
9525 #ifdef NSPIRE_NEWLIB
9526     return int(unsigned(millis()/1000.) & ((1u<<31)-1));
9527 #endif
9528 #ifdef FXCG
9529     return RTC_GetTicks();
9530 #else
9531 #if defined __APPLE__ || defined EMCC || !defined HAVE_LIBRT
9532     return (int) clock();
9533 #else
9534     timespec t;
9535     clock_gettime(CLOCK_MONOTONIC,&t);
9536     return t.tv_sec+t.tv_nsec*1e-9;
9537 #endif
9538 #endif
9539   }
9540   static const char _monotonic_s []="monotonic";
9541   static define_unary_function_eval (__monotonic,&_monotonic,_monotonic_s);
9542   define_unary_function_ptr5( at_monotonic ,alias_at_monotonic,&__monotonic,0,true);
9543 
9544   static const char _DelVar_s []="DelVar";
9545   static define_unary_function_eval2_quoted (__DelVar,&_purge,_DelVar_s,&printastifunction);
9546   define_unary_function_ptr5( at_DelVar ,alias_at_DelVar,&__DelVar,_QUOTE_ARGUMENTS,T_RETURN);
9547 
9548   static const char _del_s []="del";
9549   static define_unary_function_eval2_quoted (__del,&_purge,_del_s,&printastifunction);
9550   define_unary_function_ptr5( at_del ,alias_at_del,&__del,_QUOTE_ARGUMENTS,T_RETURN);
9551 
_Row(const gen & g,GIAC_CONTEXT)9552   gen _Row(const gen & g,GIAC_CONTEXT){
9553     if (interactive_op_tab && interactive_op_tab[6])
9554       return interactive_op_tab[6](g,contextptr);
9555     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
9556     return spread_Row(contextptr);
9557   }
9558   static const char _Row_s []="Row";
9559 #if defined RTOS_THREADX || defined NSPIRE
9560   static define_unary_function_eval(__Row,&_Row,_Row_s);
9561 #else
9562   unary_function_eval __Row(0,&_Row,_Row_s,&printastifunction);
9563 #endif
9564   define_unary_function_ptr( at_Row ,alias_at_Row ,&__Row);
9565 
_Col(const gen & g,GIAC_CONTEXT)9566   gen _Col(const gen & g,GIAC_CONTEXT){
9567     if (interactive_op_tab && interactive_op_tab[7])
9568       return interactive_op_tab[7](g,contextptr);
9569     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
9570     return spread_Col(contextptr);
9571   }
9572   static const char _Col_s []="Col";
9573 #if defined RTOS_THREADX || defined NSPIRE
9574   static define_unary_function_eval(__Col,&_Col,_Col_s);
9575 #else
9576   unary_function_eval __Col(0,&_Col,_Col_s,&printastifunction);
9577 #endif
9578   define_unary_function_ptr( at_Col ,alias_at_Col ,&__Col);
9579 
matrix_apply(const gen & a,const gen & b,gen (* f)(const gen &,const gen &))9580   gen matrix_apply(const gen & a,const gen & b,gen (* f) (const gen &, const gen &) ){
9581     if (a.type!=_VECT || b.type!=_VECT || a._VECTptr->size()!=b._VECTptr->size())
9582       return apply(a,b,f);
9583     const_iterateur it=a._VECTptr->begin(),itend=a._VECTptr->end(),jt=b._VECTptr->begin();
9584     vecteur res;
9585     res.reserve(itend-it);
9586     for (;it!=itend;++it,++jt){
9587       res.push_back(apply(*it,*jt,f));
9588     }
9589     return gen(res,a.subtype);
9590   }
matrix_apply(const gen & a,const gen & b,GIAC_CONTEXT,gen (* f)(const gen &,const gen &,GIAC_CONTEXT))9591   gen matrix_apply(const gen & a,const gen & b,GIAC_CONTEXT,gen (* f) (const gen &, const gen &,GIAC_CONTEXT) ){
9592     if (a.type!=_VECT || b.type!=_VECT || a._VECTptr->size()!=b._VECTptr->size())
9593       return apply(a,b,contextptr,f);
9594     const_iterateur it=a._VECTptr->begin(),itend=a._VECTptr->end(),jt=b._VECTptr->begin();
9595     vecteur res;
9596     res.reserve(itend-it);
9597     for (;it!=itend;++it,++jt){
9598       res.push_back(apply(*it,*jt,contextptr,f));
9599     }
9600     return gen(res,a.subtype);
9601   }
prod(const gen & a,const gen & b)9602   gen prod(const gen & a,const gen &b){
9603     return a*b;
9604   }
somme(const gen & a,const gen & b)9605   gen somme(const gen & a,const gen &b){
9606     return a+b;
9607   }
_pointprod(const gen & g,GIAC_CONTEXT)9608   gen _pointprod(const gen & g,GIAC_CONTEXT){
9609     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
9610     gen a,b;
9611     if (!check_binary(g,a,b))
9612       return a;
9613     return matrix_apply(a,b,contextptr,operator_times);
9614   }
9615   static const char _pointprod_s []=".*";
9616   static define_unary_function_eval4_index (92,__pointprod,&_pointprod,_pointprod_s,&printsommetasoperator,&texprintsommetasoperator);
9617   define_unary_function_ptr( at_pointprod ,alias_at_pointprod ,&__pointprod);
9618 
pointdivision(const gen & a,const gen & b,GIAC_CONTEXT)9619   gen pointdivision(const gen & a,const gen &b,GIAC_CONTEXT){
9620     if (a.type==_VECT && b.type!=_VECT)
9621       return apply1st(a,b,contextptr,pointdivision);
9622     if (a.type!=_VECT && b.type==_VECT)
9623       return apply2nd(a,b,contextptr,pointdivision);
9624     //return a/b;
9625     // reactivated 22 oct 15 for [[1,2],[3,4]] ./ [[3,4],[5,6]]
9626     return matrix_apply(a,b,contextptr,rdiv);
9627   }
_pointdivision(const gen & g,GIAC_CONTEXT)9628   gen _pointdivision(const gen & g,GIAC_CONTEXT){
9629     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
9630     gen a,b;
9631     if (!check_binary(g,a,b))
9632       return a;
9633     return pointdivision(a,b,contextptr);
9634   }
9635   static const char _pointdivision_s []="./";
9636   static define_unary_function_eval4_index (94,__pointdivision,&_pointdivision,_pointdivision_s,&printsommetasoperator,&texprintsommetasoperator);
9637   define_unary_function_ptr( at_pointdivision ,alias_at_pointdivision ,&__pointdivision);
9638 
9639   gen giac_pow(const gen &,const gen &,GIAC_CONTEXT);
pointpow(const gen & a,const gen & b,GIAC_CONTEXT)9640   gen pointpow(const gen & a,const gen &b,GIAC_CONTEXT){
9641     if (b.type!=_VECT && a.type==_VECT){
9642       return apply(a,b,contextptr,pointpow);
9643     }
9644     return matrix_apply(a,b,contextptr,giac_pow);
9645   }
_pointpow(const gen & g,GIAC_CONTEXT)9646   gen _pointpow(const gen & g,GIAC_CONTEXT){
9647     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
9648     gen a,b;
9649     if (!check_binary(g,a,b))
9650       return a;
9651     return pointpow(a,b,contextptr);
9652   }
9653   static const char _pointpow_s []=".^";
9654   static define_unary_function_eval4_index (96,__pointpow,&_pointpow,_pointpow_s,&printsommetasoperator,&texprintsommetasoperator);
9655   define_unary_function_ptr( at_pointpow ,alias_at_pointpow ,&__pointpow);
9656 
printassuffix(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)9657   string printassuffix(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
9658     return feuille.print(contextptr)+sommetstr;
9659   }
_pourcent(const gen & g,GIAC_CONTEXT)9660   gen _pourcent(const gen & g,GIAC_CONTEXT){
9661     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
9662     return rdiv(g,100,contextptr);
9663   }
9664   static const char _pourcent_s []="%";
9665   static define_unary_function_eval2_index (100,__pourcent,&_pourcent,_pourcent_s,&printassuffix);
9666   define_unary_function_ptr( at_pourcent ,alias_at_pourcent ,&__pourcent);
9667 
_hash(const gen & g,GIAC_CONTEXT)9668   gen _hash(const gen & g,GIAC_CONTEXT){
9669     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
9670     if (g.type!=_STRNG)
9671       return g;
9672     return gen(*g._STRNGptr,contextptr);
9673   }
9674   static const char _hash_s []="make_symbol";
9675   static define_unary_function_eval_index (98,__hash,&_hash,_hash_s);
9676   define_unary_function_ptr5( at_hash ,alias_at_hash ,&__hash,0,true);
9677 
9678   bool user_screen=false;
9679   int user_screen_io_x=0,user_screen_io_y=0;
9680   int user_screen_fontsize=14;
_interactive(const gen & args,GIAC_CONTEXT)9681   gen _interactive(const gen & args,GIAC_CONTEXT){
9682     if (interactive_op_tab && interactive_op_tab[2])
9683       return interactive_op_tab[2](args,contextptr);
9684     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9685 #if defined(WIN32) || !defined(HAVE_SIGNAL_H_OLD)
9686     return 0;
9687 #else
9688     if (child_id)
9689       return 0;
9690     ofstream child_out(cas_sortie_name().c_str());
9691     gen e(symbolic(at_interactive,args));
9692     // *logptr(contextptr) << e << '\n';
9693     archive(child_out,e,contextptr);
9694     archive(child_out,e,contextptr);
9695     child_out.close();
9696     kill_and_wait_sigusr2();
9697     ifstream child_in(cas_entree_name().c_str());
9698     gen res= unarchive(child_in,contextptr);
9699     child_in.close();
9700     return res;
9701 #endif
9702   }
9703   static const char _interactive_s []="interactive";
9704 #if defined RTOS_THREADX || defined NSPIRE || defined FXCG
9705   define_unary_function_eval_index(1,__interactive,&_interactive,_interactive_s);
9706   // const unary_function_eval __interactive(1,&_interactive,_interactive_s);
9707 #else
9708   unary_function_eval __interactive(1,&_interactive,_interactive_s);
9709 #endif
9710   define_unary_function_ptr5( at_interactive ,alias_at_interactive,&__interactive,_QUOTE_ARGUMENTS,true);
9711 
9712   // v=[ [idnt,value] ... ]
9713   // search g in v if found return value
9714   // else return g unevaluated
find_in_folder(vecteur & v,const gen & g)9715   gen find_in_folder(vecteur & v,const gen & g){
9716     const_iterateur it=v.begin(),itend=v.end();
9717     for (;it!=itend;++it){
9718       if (it->type!=_VECT || it->_VECTptr->size()!=2)
9719 	continue;
9720       vecteur & w=*it->_VECTptr;
9721       if (w[0]==g)
9722 	return w[1];
9723     }
9724     return g;
9725   }
9726 
_ti_semi(const gen & args,GIAC_CONTEXT)9727   gen _ti_semi(const gen & args,GIAC_CONTEXT){
9728     if ( args.type==_STRNG &&  args.subtype==-1) return  args;
9729     if (args.type!=_VECT || args._VECTptr->size()!=2)
9730       return symbolic(at_ti_semi,args);
9731     vecteur & v=*args._VECTptr;
9732     matrice m1,m2;
9733     if (!ckmatrix(v[0])){
9734       if (v[0].type==_VECT)
9735 	m1=vecteur(1,*v[0]._VECTptr);
9736       else
9737 	m1=vecteur(1,vecteur(1,v[0]));
9738     }
9739     else
9740       m1=*v[0]._VECTptr;
9741     if (!ckmatrix(v[1])){
9742       if (v[1].type==_VECT)
9743 	m2=vecteur(1,*v[1]._VECTptr);
9744       else
9745 	m2=vecteur(1,vecteur(1,v[1]));
9746     }
9747     else
9748       m2=*v[1]._VECTptr;
9749     // *logptr(contextptr) << m1 << " " << m2 << '\n';
9750     return mergevecteur(m1,m2);
9751   }
9752   static const char _ti_semi_s []=";";
9753   static define_unary_function_eval4 (__ti_semi,&_ti_semi,_ti_semi_s,&printsommetasoperator,&texprintsommetasoperator);
9754   define_unary_function_ptr( at_ti_semi ,alias_at_ti_semi ,&__ti_semi);
9755 
widget_size(const gen & g,GIAC_CONTEXT)9756   gen widget_size(const gen & g,GIAC_CONTEXT){
9757     if (interactive_op_tab && interactive_op_tab[9])
9758       return interactive_op_tab[9](g,contextptr);
9759     return zero;
9760   }
9761   static const char _widget_size_s []="widget_size";
9762   // const string _widget_size_s ="widget_size";
9763 #if defined RTOS_THREADX || defined NSPIRE
9764   define_unary_function_eval(__widget_size,&widget_size,_widget_size_s);
9765   // const unary_function_eval __widget_size(0,&widget_size,_widget_size_s);
9766 #else
9767   unary_function_eval __widget_size(0,&widget_size,_widget_size_s);
9768 #endif
9769   define_unary_function_ptr5( at_widget_size ,alias_at_widget_size,&__widget_size,0,true);
9770 
keyboard(const gen & g,GIAC_CONTEXT)9771   gen keyboard(const gen & g,GIAC_CONTEXT){
9772     return zero;
9773   }
9774   static const char _keyboard_s []="keyboard";
9775 #if defined RTOS_THREADX || defined NSPIRE
9776   static define_unary_function_eval(__keyboard,&keyboard,_keyboard_s);
9777   // const unary_function_eval __keyboard(0,&keyboard,_keyboard_s);
9778 #else
9779   unary_function_eval __keyboard(0,&keyboard,_keyboard_s);
9780 #endif
9781   define_unary_function_ptr5( at_keyboard ,alias_at_keyboard,&__keyboard,0,true);
9782 
9783 #ifndef KHICAS // see kadd.cc
current_sheet(const gen & g,GIAC_CONTEXT)9784   gen current_sheet(const gen & g,GIAC_CONTEXT){
9785     if (interactive_op_tab && interactive_op_tab[5])
9786       return interactive_op_tab[5](g,contextptr);
9787     return zero;
9788   }
9789   static const char _current_sheet_s []="current_sheet";
9790 #if defined RTOS_THREADX || defined NSPIRE
9791   static define_unary_function_eval(__current_sheet,&current_sheet,_current_sheet_s);
9792 #else
9793   unary_function_eval __current_sheet(1,&current_sheet,_current_sheet_s);
9794 #endif
9795   define_unary_function_ptr5( at_current_sheet ,alias_at_current_sheet,&__current_sheet,_QUOTE_ARGUMENTS,true);
9796 #endif
9797 
printasmaple_lib(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)9798   static string printasmaple_lib(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
9799     if (feuille.type!=_VECT || feuille._VECTptr->size()!=2)
9800       return gettext("Error printasmaple_lib");
9801     vecteur & v=*feuille._VECTptr;
9802     return v[0].print(contextptr)+"["+v[1].print(contextptr)+"]";
9803   }
maple_lib(const gen & g,GIAC_CONTEXT)9804   gen maple_lib(const gen & g,GIAC_CONTEXT){
9805     if (g.type!=_VECT || g._VECTptr->size()!=2)
9806       return gensizeerr(contextptr);
9807     vecteur & v=*g._VECTptr;
9808     return v[1];
9809   }
9810   static const char _maple_lib_s[]="maple_lib";
9811 #if defined RTOS_THREADX || defined NSPIRE
9812   static define_unary_function_eval2_index(110,__maple_lib,&maple_lib,_maple_lib_s,&printasmaple_lib);
9813 #else
9814   const unary_function_eval __maple_lib(110,&maple_lib,_maple_lib_s,&printasmaple_lib);
9815 #endif
9816   define_unary_function_ptr( at_maple_lib ,alias_at_maple_lib ,&__maple_lib);
9817 
window_switch(const gen & g,GIAC_CONTEXT)9818   gen window_switch(const gen & g,GIAC_CONTEXT){
9819     return zero; // defined by GUI handler
9820   }
9821   static const char _window_switch_s []="window_switch";
9822 #if defined RTOS_THREADX || defined NSPIRE
9823   static define_unary_function_eval(__window_switch,&window_switch,_window_switch_s);
9824 #else
9825   const unary_function_eval __window_switch(0,&window_switch,_window_switch_s);
9826 #endif
9827   define_unary_function_ptr( at_window_switch ,alias_at_window_switch ,&__window_switch);
9828 
9829 
9830   // Funcion has been changed -> simplify
9831   static const char _simplifier_s []="simplifier";
9832   static define_unary_function_eval (__simplifier,&_simplify,_simplifier_s);
9833   define_unary_function_ptr5( at_simplifier ,alias_at_simplifier,&__simplifier,0,true);
9834 
_regroup(const gen & g,GIAC_CONTEXT)9835   gen _regroup(const gen &g,GIAC_CONTEXT){
9836     return _simplifier(g,contextptr);
9837   }
9838   static const char _regrouper_s []="regroup";
9839   static define_unary_function_eval (__regrouper,&_regroup,_regrouper_s);
9840   define_unary_function_ptr5( at_regrouper ,alias_at_regrouper,&__regrouper,0,true);
9841 
find_or_make_symbol(const string & s,bool check38,GIAC_CONTEXT)9842   gen find_or_make_symbol(const string & s,bool check38,GIAC_CONTEXT){
9843     gen tmp;
9844     find_or_make_symbol(s,tmp,0,check38,contextptr);
9845     return tmp;
9846   }
9847 
9848   // fundemental metric units
9849   const mksa_unit __m_unit={1,1,0,0,0,0,0,0,0};
9850   const mksa_unit __kg_unit={1,0,1,0,0,0,0,0,0};
9851   const mksa_unit __s_unit={1,0,0,1,0,0,0,0,0};
9852   const mksa_unit __A_unit={1,0,0,0,1,0,0,0,0};
9853   const mksa_unit __K_unit={1,0,0,0,0,1,0,0,0};
9854   const mksa_unit __mol_unit={1,0,0,0,0,0,1,0,0};
9855   const mksa_unit __cd_unit={1,0,0,0,0,0,0,1,0};
9856   const mksa_unit __E_unit={1,0,0,0,0,0,0,0,1};
9857   const mksa_unit __Bq_unit={1,0,0,-1,0,0,0,0,0};
9858   const mksa_unit __C_unit={1,0,0,1,1,0,0,0,0};
9859   const mksa_unit __F_unit={1,-2,-1,4,2,0,0,0,0};
9860   const mksa_unit __Gy_unit={1,2,0,-2,0,0,0,0,0};
9861   const mksa_unit __H_unit={1,2,1,-2,-2,0,0,0,0};
9862   const mksa_unit __Hz_unit={1,0,0,-1,0,0,0,0,0};
9863   const mksa_unit __J_unit={1,2,1,-2,0,0,0,0,0};
9864   const mksa_unit __mho_unit={1,-2,-1,3,2,0,0,0,0};
9865   const mksa_unit __N_unit={1,1,1,-2,0,0,0,0,0};
9866   const mksa_unit __Ohm_unit={1,2,1,-3,-2,0,0,0,0};
9867   const mksa_unit __Pa_unit={1,-1,1,-2,0,0,0,0,0};
9868   const mksa_unit __rad_unit={1,0,0,0,0,0,0,0,0};
9869   const mksa_unit __S_unit={1,-2,-1,3,2,0,0,0,0};
9870   const mksa_unit __Sv_unit={1,2,0,-2,0,0,0,0,0};
9871   const mksa_unit __T_unit={1,0,1,-2,-1,0,0,0,0};
9872   const mksa_unit __V_unit={1,2,1,-3,-1,0,0,0,0};
9873   const mksa_unit __W_unit={1,2,1,-3,0,0,0,0,0};
9874   const mksa_unit __Wb_unit={1,2,1,-2,-1,0,0,0,0};
9875   const mksa_unit __Js_unit={1,2,1,-1,0,0,0,0,0};
9876   // To each unit we associate a number and a vector of powers of kg, m, s
9877   /*
9878   map_charptr_gen unit_conversion_map;
9879   gen mksa_register(const char * s,const gen & equiv){
9880     unit_conversion_map[s+1]=equiv;
9881     return find_or_make_symbol(s,false,context0);
9882   }
9883   */
9884 #ifdef USTL
unit_conversion_map()9885   ustl::map<const char *, const mksa_unit *,ltstr> & unit_conversion_map(){
9886     static ustl::map<const char *, const mksa_unit *,ltstr> * unit_conversion_mapptr=0;
9887     if (!unit_conversion_mapptr)
9888       unit_conversion_mapptr=new ustl::map<const char *, const mksa_unit *,ltstr>;
9889     return *unit_conversion_mapptr;
9890   }
9891 #else
unit_conversion_map()9892   std::map<const char *, const mksa_unit *,ltstr> & unit_conversion_map(){
9893     static std::map<const char *, const mksa_unit *,ltstr> * unit_conversion_mapptr=0;
9894     if (!unit_conversion_mapptr)
9895       unit_conversion_mapptr=new std::map<const char *, const mksa_unit *,ltstr>;
9896     return *unit_conversion_mapptr;
9897   }
9898 #endif
9899 
9900 #ifdef STATIC_BUILTIN_LEXER_FUNCTIONS
9901   static const alias_identificateur alias_identificateur_A_unit_rom={0,0,"_A",0,0};
9902   const identificateur & _IDNT_id_A_unit_rom=* (const identificateur *) &alias_identificateur_A_unit_rom;
9903   const alias_ref_identificateur ref_A_unit_rom={-1,0,0,"_A",0,0};
9904   const define_alias_gen(alias_A_unit_rom,_IDNT,0,&ref_A_unit_rom);
9905   const gen & A_unit_rom_IDNT_e = * (gen *) & alias_A_unit_rom;
9906 
9907   static const alias_identificateur alias_identificateur_Angstrom_unit_rom={0,0,"_Angstrom",0,0};
9908   const identificateur & _IDNT_id_Angstrom_unit_rom=* (const identificateur *) &alias_identificateur_Angstrom_unit_rom;
9909   const alias_ref_identificateur ref_Angstrom_unit_rom={-1,0,0,"_Angstrom",0,0};
9910   const define_alias_gen(alias_Angstrom_unit_rom,_IDNT,0,&ref_Angstrom_unit_rom);
9911   const gen & Angstrom_unit_rom_IDNT_e = * (gen *) & alias_Angstrom_unit_rom;
9912 
9913   static const alias_identificateur alias_identificateur_Bq_unit_rom={0,0,"_Bq",0,0};
9914   const identificateur & _IDNT_id_Bq_unit_rom=* (const identificateur *) &alias_identificateur_Bq_unit_rom;
9915   const alias_ref_identificateur ref_Bq_unit_rom={-1,0,0,"_Bq",0,0};
9916   const define_alias_gen(alias_Bq_unit_rom,_IDNT,0,&ref_Bq_unit_rom);
9917   const gen & Bq_unit_rom_IDNT_e = * (gen *) & alias_Bq_unit_rom;
9918 
9919   static const alias_identificateur alias_identificateur_yd_unit_rom={0,0,"_yd",0,0};
9920   const identificateur & _IDNT_id_yd_unit_rom=* (const identificateur *) &alias_identificateur_yd_unit_rom;
9921   const alias_ref_identificateur ref_yd_unit_rom={-1,0,0,"_yd",0,0};
9922   const define_alias_gen(alias_yd_unit_rom,_IDNT,0,&ref_yd_unit_rom);
9923   const gen & yd_unit_rom_IDNT_e = * (gen *) & alias_yd_unit_rom;
9924 
9925   static const alias_identificateur alias_identificateur_yr_unit_rom={0,0,"_yr",0,0};
9926   const identificateur & _IDNT_id_yr_unit_rom=* (const identificateur *) &alias_identificateur_yr_unit_rom;
9927   const alias_ref_identificateur ref_yr_unit_rom={-1,0,0,"_yr",0,0};
9928   const define_alias_gen(alias_yr_unit_rom,_IDNT,0,&ref_yr_unit_rom);
9929   const gen & yr_unit_rom_IDNT_e = * (gen *) & alias_yr_unit_rom;
9930 
9931   static const alias_identificateur alias_identificateur_Btu_unit_rom={0,0,"_Btu",0,0};
9932   const identificateur & _IDNT_id_Btu_unit_rom=* (const identificateur *) &alias_identificateur_Btu_unit_rom;
9933   const alias_ref_identificateur ref_Btu_unit_rom={-1,0,0,"_Btu",0,0};
9934   const define_alias_gen(alias_Btu_unit_rom,_IDNT,0,&ref_Btu_unit_rom);
9935   const gen & Btu_unit_rom_IDNT_e = * (gen *) & alias_Btu_unit_rom;
9936 
9937   static const alias_identificateur alias_identificateur_R__unit_rom={0,0,"_R_",0,0};
9938   const identificateur & _IDNT_id_R__unit_rom=* (const identificateur *) &alias_identificateur_R__unit_rom;
9939   const alias_ref_identificateur ref_R__unit_rom={-1,0,0,"_R_",0,0};
9940   const define_alias_gen(alias_R__unit_rom,_IDNT,0,&ref_R__unit_rom);
9941   const gen & R__unit_rom_IDNT_e = * (gen *) & alias_R__unit_rom;
9942 
9943   static const alias_identificateur alias_identificateur_epsilon0__unit_rom={0,0,"_epsilon0_",0,0};
9944   const identificateur & _IDNT_id_epsilon0__unit_rom=* (const identificateur *) &alias_identificateur_epsilon0__unit_rom;
9945   const alias_ref_identificateur ref_epsilon0__unit_rom={-1,0,0,"_epsilon0_",0,0};
9946   const define_alias_gen(alias_epsilon0__unit_rom,_IDNT,0,&ref_epsilon0__unit_rom);
9947   const gen & epsilon0__unit_rom_IDNT_e = * (gen *) & alias_epsilon0__unit_rom;
9948 
9949   static const alias_identificateur alias_identificateur_a0__unit_rom={0,0,"_a0_",0,0};
9950   const identificateur & _IDNT_id_a0__unit_rom=* (const identificateur *) &alias_identificateur_a0__unit_rom;
9951   const alias_ref_identificateur ref_a0__unit_rom={-1,0,0,"_a0_",0,0};
9952   const define_alias_gen(alias_a0__unit_rom,_IDNT,0,&ref_a0__unit_rom);
9953   const gen & a0__unit_rom_IDNT_e = * (gen *) & alias_a0__unit_rom;
9954 
9955   static const alias_identificateur alias_identificateur_RSun__unit_rom={0,0,"_RSun_",0,0};
9956   const identificateur & _IDNT_id_RSun__unit_rom=* (const identificateur *) &alias_identificateur_RSun__unit_rom;
9957   const alias_ref_identificateur ref_RSun__unit_rom={-1,0,0,"_RSun_",0,0};
9958   const define_alias_gen(alias_RSun__unit_rom,_IDNT,0,&ref_RSun__unit_rom);
9959   const gen & RSun__unit_rom_IDNT_e = * (gen *) & alias_RSun__unit_rom;
9960 
9961   static const alias_identificateur alias_identificateur_REarth__unit_rom={0,0,"_REarth_",0,0};
9962   const identificateur & _IDNT_id_REarth__unit_rom=* (const identificateur *) &alias_identificateur_REarth__unit_rom;
9963   const alias_ref_identificateur ref_REarth__unit_rom={-1,0,0,"_REarth_",0,0};
9964   const define_alias_gen(alias_REarth__unit_rom,_IDNT,0,&ref_REarth__unit_rom);
9965   const gen & REarth__unit_rom_IDNT_e = * (gen *) & alias_REarth__unit_rom;
9966 
9967   static const alias_identificateur alias_identificateur_Fdy_unit_rom={0,0,"_Fdy",0,0};
9968   const identificateur & _IDNT_id_Fdy_unit_rom=* (const identificateur *) &alias_identificateur_Fdy_unit_rom;
9969   const alias_ref_identificateur ref_Fdy_unit_rom={-1,0,0,"_Fdy",0,0};
9970   const define_alias_gen(alias_Fdy_unit_rom,_IDNT,0,&ref_Fdy_unit_rom);
9971   const gen & Fdy_unit_rom_IDNT_e = * (gen *) & alias_Fdy_unit_rom;
9972 
9973   static const alias_identificateur alias_identificateur_F_unit_rom={0,0,"_F",0,0};
9974   const identificateur & _IDNT_id_F_unit_rom=* (const identificateur *) &alias_identificateur_F_unit_rom;
9975   const alias_ref_identificateur ref_F_unit_rom={-1,0,0,"_F",0,0};
9976   const define_alias_gen(alias_F_unit_rom,_IDNT,0,&ref_F_unit_rom);
9977   const gen & F_unit_rom_IDNT_e = * (gen *) & alias_F_unit_rom;
9978 
9979   static const alias_identificateur alias_identificateur_FF_unit_rom={0,0,"_FF",0,0};
9980   const identificateur & _IDNT_id_FF_unit_rom=* (const identificateur *) &alias_identificateur_FF_unit_rom;
9981   const alias_ref_identificateur ref_FF_unit_rom={-1,0,0,"_FF",0,0};
9982   const define_alias_gen(alias_FF_unit_rom,_IDNT,0,&ref_FF_unit_rom);
9983   const gen & FF_unit_rom_IDNT_e = * (gen *) & alias_FF_unit_rom;
9984 
9985   static const alias_identificateur alias_identificateur_Faraday__unit_rom={0,0,"_Faraday_",0,0};
9986   const identificateur & _IDNT_id_Faraday__unit_rom=* (const identificateur *) &alias_identificateur_Faraday__unit_rom;
9987   const alias_ref_identificateur ref_Faraday__unit_rom={-1,0,0,"_Faraday_",0,0};
9988   const define_alias_gen(alias_Faraday__unit_rom,_IDNT,0,&ref_Faraday__unit_rom);
9989   const gen & Faraday__unit_rom_IDNT_e = * (gen *) & alias_Faraday__unit_rom;
9990 
9991   static const alias_identificateur alias_identificateur_G__unit_rom={0,0,"_G_",0,0};
9992   const identificateur & _IDNT_id_G__unit_rom=* (const identificateur *) &alias_identificateur_G__unit_rom;
9993   const alias_ref_identificateur ref_G__unit_rom={-1,0,0,"_G_",0,0};
9994   const define_alias_gen(alias_G__unit_rom,_IDNT,0,&ref_G__unit_rom);
9995   const gen & G__unit_rom_IDNT_e = * (gen *) & alias_G__unit_rom;
9996 
9997   static const alias_identificateur alias_identificateur_Gal_unit_rom={0,0,"_Gal",0,0};
9998   const identificateur & _IDNT_id_Gal_unit_rom=* (const identificateur *) &alias_identificateur_Gal_unit_rom;
9999   const alias_ref_identificateur ref_Gal_unit_rom={-1,0,0,"_Gal",0,0};
10000   const define_alias_gen(alias_Gal_unit_rom,_IDNT,0,&ref_Gal_unit_rom);
10001   const gen & Gal_unit_rom_IDNT_e = * (gen *) & alias_Gal_unit_rom;
10002 
10003   static const alias_identificateur alias_identificateur_Gy_unit_rom={0,0,"_Gy",0,0};
10004   const identificateur & _IDNT_id_Gy_unit_rom=* (const identificateur *) &alias_identificateur_Gy_unit_rom;
10005   const alias_ref_identificateur ref_Gy_unit_rom={-1,0,0,"_Gy",0,0};
10006   const define_alias_gen(alias_Gy_unit_rom,_IDNT,0,&ref_Gy_unit_rom);
10007   const gen & Gy_unit_rom_IDNT_e = * (gen *) & alias_Gy_unit_rom;
10008 
10009   static const alias_identificateur alias_identificateur_H_unit_rom={0,0,"_H",0,0};
10010   const identificateur & _IDNT_id_H_unit_rom=* (const identificateur *) &alias_identificateur_H_unit_rom;
10011   const alias_ref_identificateur ref_H_unit_rom={-1,0,0,"_H",0,0};
10012   const define_alias_gen(alias_H_unit_rom,_IDNT,0,&ref_H_unit_rom);
10013   const gen & H_unit_rom_IDNT_e = * (gen *) & alias_H_unit_rom;
10014 
10015   static const alias_identificateur alias_identificateur_HFCC_unit_rom={0,0,"_HFCC",0,0};
10016   const identificateur & _IDNT_id_HFCC_unit_rom=* (const identificateur *) &alias_identificateur_HFCC_unit_rom;
10017   const alias_ref_identificateur ref_HFCC_unit_rom={-1,0,0,"_HFCC",0,0};
10018   const define_alias_gen(alias_HFCC_unit_rom,_IDNT,0,&ref_HFCC_unit_rom);
10019   const gen & HFCC_unit_rom_IDNT_e = * (gen *) & alias_HFCC_unit_rom;
10020 
10021   static const alias_identificateur alias_identificateur_Hz_unit_rom={0,0,"_Hz",0,0};
10022   const identificateur & _IDNT_id_Hz_unit_rom=* (const identificateur *) &alias_identificateur_Hz_unit_rom;
10023   const alias_ref_identificateur ref_Hz_unit_rom={-1,0,0,"_Hz",0,0};
10024   const define_alias_gen(alias_Hz_unit_rom,_IDNT,0,&ref_Hz_unit_rom);
10025   const gen & Hz_unit_rom_IDNT_e = * (gen *) & alias_Hz_unit_rom;
10026 
10027   static const alias_identificateur alias_identificateur_IO__unit_rom={0,0,"_IO_",0,0};
10028   const identificateur & _IDNT_id_IO__unit_rom=* (const identificateur *) &alias_identificateur_IO__unit_rom;
10029   const alias_ref_identificateur ref_IO__unit_rom={-1,0,0,"_IO_",0,0};
10030   const define_alias_gen(alias_IO__unit_rom,_IDNT,0,&ref_IO__unit_rom);
10031   const gen & IO__unit_rom_IDNT_e = * (gen *) & alias_IO__unit_rom;
10032 
10033   static const alias_identificateur alias_identificateur_J_unit_rom={0,0,"_J",0,0};
10034   const identificateur & _IDNT_id_J_unit_rom=* (const identificateur *) &alias_identificateur_J_unit_rom;
10035   const alias_ref_identificateur ref_J_unit_rom={-1,0,0,"_J",0,0};
10036   const define_alias_gen(alias_J_unit_rom,_IDNT,0,&ref_J_unit_rom);
10037   const gen & J_unit_rom_IDNT_e = * (gen *) & alias_J_unit_rom;
10038 
10039   static const alias_identificateur alias_identificateur_K_unit_rom={0,0,"_K",0,0};
10040   const identificateur & _IDNT_id_K_unit_rom=* (const identificateur *) &alias_identificateur_K_unit_rom;
10041   const alias_ref_identificateur ref_K_unit_rom={-1,0,0,"_K",0,0};
10042   const define_alias_gen(alias_K_unit_rom,_IDNT,0,&ref_K_unit_rom);
10043   const gen & K_unit_rom_IDNT_e = * (gen *) & alias_K_unit_rom;
10044 
10045   static const alias_identificateur alias_identificateur_L_unit_rom={0,0,"_L",0,0};
10046   const identificateur & _IDNT_id_L_unit_rom=* (const identificateur *) &alias_identificateur_L_unit_rom;
10047   const alias_ref_identificateur ref_L_unit_rom={-1,0,0,"_L",0,0};
10048   const define_alias_gen(alias_L_unit_rom,_IDNT,0,&ref_L_unit_rom);
10049   const gen & L_unit_rom_IDNT_e = * (gen *) & alias_L_unit_rom;
10050 
10051   static const alias_identificateur alias_identificateur_N_unit_rom={0,0,"_N",0,0};
10052   const identificateur & _IDNT_id_N_unit_rom=* (const identificateur *) &alias_identificateur_N_unit_rom;
10053   const alias_ref_identificateur ref_N_unit_rom={-1,0,0,"_N",0,0};
10054   const define_alias_gen(alias_N_unit_rom,_IDNT,0,&ref_N_unit_rom);
10055   const gen & N_unit_rom_IDNT_e = * (gen *) & alias_N_unit_rom;
10056 
10057   static const alias_identificateur alias_identificateur_NA__unit_rom={0,0,"_NA_",0,0};
10058   const identificateur & _IDNT_id_NA__unit_rom=* (const identificateur *) &alias_identificateur_NA__unit_rom;
10059   const alias_ref_identificateur ref_NA__unit_rom={-1,0,0,"_NA_",0,0};
10060   const define_alias_gen(alias_NA__unit_rom,_IDNT,0,&ref_NA__unit_rom);
10061   const gen & NA__unit_rom_IDNT_e = * (gen *) & alias_NA__unit_rom;
10062 
10063   static const alias_identificateur alias_identificateur_Ohm_unit_rom={0,0,"_Ohm",0,0};
10064   const identificateur & _IDNT_id_Ohm_unit_rom=* (const identificateur *) &alias_identificateur_Ohm_unit_rom;
10065   const alias_ref_identificateur ref_Ohm_unit_rom={-1,0,0,"_Ohm",0,0};
10066   const define_alias_gen(alias_Ohm_unit_rom,_IDNT,0,&ref_Ohm_unit_rom);
10067   const gen & Ohm_unit_rom_IDNT_e = * (gen *) & alias_Ohm_unit_rom;
10068 
10069   static const alias_identificateur alias_identificateur_P_unit_rom={0,0,"_P",0,0};
10070   const identificateur & _IDNT_id_P_unit_rom=* (const identificateur *) &alias_identificateur_P_unit_rom;
10071   const alias_ref_identificateur ref_P_unit_rom={-1,0,0,"_P",0,0};
10072   const define_alias_gen(alias_P_unit_rom,_IDNT,0,&ref_P_unit_rom);
10073   const gen & P_unit_rom_IDNT_e = * (gen *) & alias_P_unit_rom;
10074 
10075   static const alias_identificateur alias_identificateur_PSun__unit_rom={0,0,"_PSun_",0,0};
10076   const identificateur & _IDNT_id_PSun__unit_rom=* (const identificateur *) &alias_identificateur_PSun__unit_rom;
10077   const alias_ref_identificateur ref_PSun__unit_rom={-1,0,0,"_PSun_",0,0};
10078   const define_alias_gen(alias_PSun__unit_rom,_IDNT,0,&ref_PSun__unit_rom);
10079   const gen & PSun__unit_rom_IDNT_e = * (gen *) & alias_PSun__unit_rom;
10080 
10081   static const alias_identificateur alias_identificateur_Pa_unit_rom={0,0,"_Pa",0,0};
10082   const identificateur & _IDNT_id_Pa_unit_rom=* (const identificateur *) &alias_identificateur_Pa_unit_rom;
10083   const alias_ref_identificateur ref_Pa_unit_rom={-1,0,0,"_Pa",0,0};
10084   const define_alias_gen(alias_Pa_unit_rom,_IDNT,0,&ref_Pa_unit_rom);
10085   const gen & Pa_unit_rom_IDNT_e = * (gen *) & alias_Pa_unit_rom;
10086 
10087   static const alias_identificateur alias_identificateur_R_unit_rom={0,0,"_R",0,0};
10088   const identificateur & _IDNT_id_R_unit_rom=* (const identificateur *) &alias_identificateur_R_unit_rom;
10089   const alias_ref_identificateur ref_R_unit_rom={-1,0,0,"_R",0,0};
10090   const define_alias_gen(alias_R_unit_rom,_IDNT,0,&ref_R_unit_rom);
10091   const gen & R_unit_rom_IDNT_e = * (gen *) & alias_R_unit_rom;
10092 
10093   static const alias_identificateur alias_identificateur_Rankine_unit_rom={0,0,"_Rankine",0,0};
10094   const identificateur & _IDNT_id_Rankine_unit_rom=* (const identificateur *) &alias_identificateur_Rankine_unit_rom;
10095   const alias_ref_identificateur ref_Rankine_unit_rom={-1,0,0,"_Rankine",0,0};
10096   const define_alias_gen(alias_Rankine_unit_rom,_IDNT,0,&ref_Rankine_unit_rom);
10097   const gen & Rankine_unit_rom_IDNT_e = * (gen *) & alias_Rankine_unit_rom;
10098 
10099   static const alias_identificateur alias_identificateur_Rinfinity__unit_rom={0,0,"_Rinfinity_",0,0};
10100   const identificateur & _IDNT_id_Rinfinity__unit_rom=* (const identificateur *) &alias_identificateur_Rinfinity__unit_rom;
10101   const alias_ref_identificateur ref_Rinfinity__unit_rom={-1,0,0,"_Rinfinity_",0,0};
10102   const define_alias_gen(alias_Rinfinity__unit_rom,_IDNT,0,&ref_Rinfinity__unit_rom);
10103   const gen & Rinfinity__unit_rom_IDNT_e = * (gen *) & alias_Rinfinity__unit_rom;
10104 
10105   static const alias_identificateur alias_identificateur_S_unit_rom={0,0,"_S",0,0};
10106   const identificateur & _IDNT_id_S_unit_rom=* (const identificateur *) &alias_identificateur_S_unit_rom;
10107   const alias_ref_identificateur ref_S_unit_rom={-1,0,0,"_S",0,0};
10108   const define_alias_gen(alias_S_unit_rom,_IDNT,0,&ref_S_unit_rom);
10109   const gen & S_unit_rom_IDNT_e = * (gen *) & alias_S_unit_rom;
10110 
10111   static const alias_identificateur alias_identificateur_St_unit_rom={0,0,"_St",0,0};
10112   const identificateur & _IDNT_id_St_unit_rom=* (const identificateur *) &alias_identificateur_St_unit_rom;
10113   const alias_ref_identificateur ref_St_unit_rom={-1,0,0,"_St",0,0};
10114   const define_alias_gen(alias_St_unit_rom,_IDNT,0,&ref_St_unit_rom);
10115   const gen & St_unit_rom_IDNT_e = * (gen *) & alias_St_unit_rom;
10116 
10117   static const alias_identificateur alias_identificateur_StdP__unit_rom={0,0,"_StdP_",0,0};
10118   const identificateur & _IDNT_id_StdP__unit_rom=* (const identificateur *) &alias_identificateur_StdP__unit_rom;
10119   const alias_ref_identificateur ref_StdP__unit_rom={-1,0,0,"_StdP_",0,0};
10120   const define_alias_gen(alias_StdP__unit_rom,_IDNT,0,&ref_StdP__unit_rom);
10121   const gen & StdP__unit_rom_IDNT_e = * (gen *) & alias_StdP__unit_rom;
10122 
10123   static const alias_identificateur alias_identificateur_StdT__unit_rom={0,0,"_StdT_",0,0};
10124   const identificateur & _IDNT_id_StdT__unit_rom=* (const identificateur *) &alias_identificateur_StdT__unit_rom;
10125   const alias_ref_identificateur ref_StdT__unit_rom={-1,0,0,"_StdT_",0,0};
10126   const define_alias_gen(alias_StdT__unit_rom,_IDNT,0,&ref_StdT__unit_rom);
10127   const gen & StdT__unit_rom_IDNT_e = * (gen *) & alias_StdT__unit_rom;
10128 
10129   static const alias_identificateur alias_identificateur_Sv_unit_rom={0,0,"_Sv",0,0};
10130   const identificateur & _IDNT_id_Sv_unit_rom=* (const identificateur *) &alias_identificateur_Sv_unit_rom;
10131   const alias_ref_identificateur ref_Sv_unit_rom={-1,0,0,"_Sv",0,0};
10132   const define_alias_gen(alias_Sv_unit_rom,_IDNT,0,&ref_Sv_unit_rom);
10133   const gen & Sv_unit_rom_IDNT_e = * (gen *) & alias_Sv_unit_rom;
10134 
10135   static const alias_identificateur alias_identificateur_T_unit_rom={0,0,"_T",0,0};
10136   const identificateur & _IDNT_id_T_unit_rom=* (const identificateur *) &alias_identificateur_T_unit_rom;
10137   const alias_ref_identificateur ref_T_unit_rom={-1,0,0,"_T",0,0};
10138   const define_alias_gen(alias_T_unit_rom,_IDNT,0,&ref_T_unit_rom);
10139   const gen & T_unit_rom_IDNT_e = * (gen *) & alias_T_unit_rom;
10140 
10141   static const alias_identificateur alias_identificateur_Torr_unit_rom={0,0,"_Torr",0,0};
10142   const identificateur & _IDNT_id_Torr_unit_rom=* (const identificateur *) &alias_identificateur_Torr_unit_rom;
10143   const alias_ref_identificateur ref_Torr_unit_rom={-1,0,0,"_Torr",0,0};
10144   const define_alias_gen(alias_Torr_unit_rom,_IDNT,0,&ref_Torr_unit_rom);
10145   const gen & Torr_unit_rom_IDNT_e = * (gen *) & alias_Torr_unit_rom;
10146 
10147   static const alias_identificateur alias_identificateur_V_unit_rom={0,0,"_V",0,0};
10148   const identificateur & _IDNT_id_V_unit_rom=* (const identificateur *) &alias_identificateur_V_unit_rom;
10149   const alias_ref_identificateur ref_V_unit_rom={-1,0,0,"_V",0,0};
10150   const define_alias_gen(alias_V_unit_rom,_IDNT,0,&ref_V_unit_rom);
10151   const gen & V_unit_rom_IDNT_e = * (gen *) & alias_V_unit_rom;
10152 
10153   static const alias_identificateur alias_identificateur_Vm__unit_rom={0,0,"_Vm_",0,0};
10154   const identificateur & _IDNT_id_Vm__unit_rom=* (const identificateur *) &alias_identificateur_Vm__unit_rom;
10155   const alias_ref_identificateur ref_Vm__unit_rom={-1,0,0,"_Vm_",0,0};
10156   const define_alias_gen(alias_Vm__unit_rom,_IDNT,0,&ref_Vm__unit_rom);
10157   const gen & Vm__unit_rom_IDNT_e = * (gen *) & alias_Vm__unit_rom;
10158 
10159   static const alias_identificateur alias_identificateur_W_unit_rom={0,0,"_W",0,0};
10160   const identificateur & _IDNT_id_W_unit_rom=* (const identificateur *) &alias_identificateur_W_unit_rom;
10161   const alias_ref_identificateur ref_W_unit_rom={-1,0,0,"_W",0,0};
10162   const define_alias_gen(alias_W_unit_rom,_IDNT,0,&ref_W_unit_rom);
10163   const gen & W_unit_rom_IDNT_e = * (gen *) & alias_W_unit_rom;
10164 
10165   static const alias_identificateur alias_identificateur_Wb_unit_rom={0,0,"_Wb",0,0};
10166   const identificateur & _IDNT_id_Wb_unit_rom=* (const identificateur *) &alias_identificateur_Wb_unit_rom;
10167   const alias_ref_identificateur ref_Wb_unit_rom={-1,0,0,"_Wb",0,0};
10168   const define_alias_gen(alias_Wb_unit_rom,_IDNT,0,&ref_Wb_unit_rom);
10169   const gen & Wb_unit_rom_IDNT_e = * (gen *) & alias_Wb_unit_rom;
10170 
10171   static const alias_identificateur alias_identificateur_Wh_unit_rom={0,0,"_Wh",0,0};
10172   const identificateur & _IDNT_id_Wh_unit_rom=* (const identificateur *) &alias_identificateur_Wh_unit_rom;
10173   const alias_ref_identificateur ref_Wh_unit_rom={-1,0,0,"_Wh",0,0};
10174   const define_alias_gen(alias_Wh_unit_rom,_IDNT,0,&ref_Wh_unit_rom);
10175   const gen & Wh_unit_rom_IDNT_e = * (gen *) & alias_Wh_unit_rom;
10176 
10177   static const alias_identificateur alias_identificateur_a_unit_rom={0,0,"_a",0,0};
10178   const identificateur & _IDNT_id_a_unit_rom=* (const identificateur *) &alias_identificateur_a_unit_rom;
10179   const alias_ref_identificateur ref_a_unit_rom={-1,0,0,"_a",0,0};
10180   const define_alias_gen(alias_a_unit_rom,_IDNT,0,&ref_a_unit_rom);
10181   const gen & a_unit_rom_IDNT_e = * (gen *) & alias_a_unit_rom;
10182 
10183   static const alias_identificateur alias_identificateur_acre_unit_rom={0,0,"_acre",0,0};
10184   const identificateur & _IDNT_id_acre_unit_rom=* (const identificateur *) &alias_identificateur_acre_unit_rom;
10185   const alias_ref_identificateur ref_acre_unit_rom={-1,0,0,"_acre",0,0};
10186   const define_alias_gen(alias_acre_unit_rom,_IDNT,0,&ref_acre_unit_rom);
10187   const gen & acre_unit_rom_IDNT_e = * (gen *) & alias_acre_unit_rom;
10188 
10189   static const alias_identificateur alias_identificateur_alpha__unit_rom={0,0,"_alpha_",0,0};
10190   const identificateur & _IDNT_id_alpha__unit_rom=* (const identificateur *) &alias_identificateur_alpha__unit_rom;
10191   const alias_ref_identificateur ref_alpha__unit_rom={-1,0,0,"_alpha_",0,0};
10192   const define_alias_gen(alias_alpha__unit_rom,_IDNT,0,&ref_alpha__unit_rom);
10193   const gen & alpha__unit_rom_IDNT_e = * (gen *) & alias_alpha__unit_rom;
10194 
10195   static const alias_identificateur alias_identificateur_arcmin_unit_rom={0,0,"_arcmin",0,0};
10196   const identificateur & _IDNT_id_arcmin_unit_rom=* (const identificateur *) &alias_identificateur_arcmin_unit_rom;
10197   const alias_ref_identificateur ref_arcmin_unit_rom={-1,0,0,"_arcmin",0,0};
10198   const define_alias_gen(alias_arcmin_unit_rom,_IDNT,0,&ref_arcmin_unit_rom);
10199   const gen & arcmin_unit_rom_IDNT_e = * (gen *) & alias_arcmin_unit_rom;
10200 
10201   static const alias_identificateur alias_identificateur_arcs_unit_rom={0,0,"_arcs",0,0};
10202   const identificateur & _IDNT_id_arcs_unit_rom=* (const identificateur *) &alias_identificateur_arcs_unit_rom;
10203   const alias_ref_identificateur ref_arcs_unit_rom={-1,0,0,"_arcs",0,0};
10204   const define_alias_gen(alias_arcs_unit_rom,_IDNT,0,&ref_arcs_unit_rom);
10205   const gen & arcs_unit_rom_IDNT_e = * (gen *) & alias_arcs_unit_rom;
10206 
10207   static const alias_identificateur alias_identificateur_atm_unit_rom={0,0,"_atm",0,0};
10208   const identificateur & _IDNT_id_atm_unit_rom=* (const identificateur *) &alias_identificateur_atm_unit_rom;
10209   const alias_ref_identificateur ref_atm_unit_rom={-1,0,0,"_atm",0,0};
10210   const define_alias_gen(alias_atm_unit_rom,_IDNT,0,&ref_atm_unit_rom);
10211   const gen & atm_unit_rom_IDNT_e = * (gen *) & alias_atm_unit_rom;
10212 
10213   static const alias_identificateur alias_identificateur_au_unit_rom={0,0,"_au",0,0};
10214   const identificateur & _IDNT_id_au_unit_rom=* (const identificateur *) &alias_identificateur_au_unit_rom;
10215   const alias_ref_identificateur ref_au_unit_rom={-1,0,0,"_au",0,0};
10216   const define_alias_gen(alias_au_unit_rom,_IDNT,0,&ref_au_unit_rom);
10217   const gen & au_unit_rom_IDNT_e = * (gen *) & alias_au_unit_rom;
10218 
10219   static const alias_identificateur alias_identificateur_bar_unit_rom={0,0,"_bar",0,0};
10220   const identificateur & _IDNT_id_bar_unit_rom=* (const identificateur *) &alias_identificateur_bar_unit_rom;
10221   const alias_ref_identificateur ref_bar_unit_rom={-1,0,0,"_bar",0,0};
10222   const define_alias_gen(alias_bar_unit_rom,_IDNT,0,&ref_bar_unit_rom);
10223   const gen & bar_unit_rom_IDNT_e = * (gen *) & alias_bar_unit_rom;
10224 
10225   static const alias_identificateur alias_identificateur_b_unit_rom={0,0,"_b",0,0};
10226   const identificateur & _IDNT_id_b_unit_rom=* (const identificateur *) &alias_identificateur_b_unit_rom;
10227   const alias_ref_identificateur ref_b_unit_rom={-1,0,0,"_b",0,0};
10228   const define_alias_gen(alias_b_unit_rom,_IDNT,0,&ref_b_unit_rom);
10229   const gen & b_unit_rom_IDNT_e = * (gen *) & alias_b_unit_rom;
10230 
10231   static const alias_identificateur alias_identificateur_bbl_unit_rom={0,0,"_bbl",0,0};
10232   const identificateur & _IDNT_id_bbl_unit_rom=* (const identificateur *) &alias_identificateur_bbl_unit_rom;
10233   const alias_ref_identificateur ref_bbl_unit_rom={-1,0,0,"_bbl",0,0};
10234   const define_alias_gen(alias_bbl_unit_rom,_IDNT,0,&ref_bbl_unit_rom);
10235   const gen & bbl_unit_rom_IDNT_e = * (gen *) & alias_bbl_unit_rom;
10236 
10237   static const alias_identificateur alias_identificateur_bblep_unit_rom={0,0,"_bblep",0,0};
10238   const identificateur & _IDNT_id_bblep_unit_rom=* (const identificateur *) &alias_identificateur_bblep_unit_rom;
10239   const alias_ref_identificateur ref_bblep_unit_rom={-1,0,0,"_bblep",0,0};
10240   const define_alias_gen(alias_bblep_unit_rom,_IDNT,0,&ref_bblep_unit_rom);
10241   const gen & bblep_unit_rom_IDNT_e = * (gen *) & alias_bblep_unit_rom;
10242 
10243   static const alias_identificateur alias_identificateur_boe_unit_rom={0,0,"_boe",0,0};
10244   const identificateur & _IDNT_id_boe_unit_rom=* (const identificateur *) &alias_identificateur_boe_unit_rom;
10245   const alias_ref_identificateur ref_boe_unit_rom={-1,0,0,"_boe",0,0};
10246   const define_alias_gen(alias_boe_unit_rom,_IDNT,0,&ref_boe_unit_rom);
10247   const gen & boe_unit_rom_IDNT_e = * (gen *) & alias_boe_unit_rom;
10248 
10249   static const alias_identificateur alias_identificateur_bu_unit_rom={0,0,"_bu",0,0};
10250   const identificateur & _IDNT_id_bu_unit_rom=* (const identificateur *) &alias_identificateur_bu_unit_rom;
10251   const alias_ref_identificateur ref_bu_unit_rom={-1,0,0,"_bu",0,0};
10252   const define_alias_gen(alias_bu_unit_rom,_IDNT,0,&ref_bu_unit_rom);
10253   const gen & bu_unit_rom_IDNT_e = * (gen *) & alias_bu_unit_rom;
10254 
10255   static const alias_identificateur alias_identificateur_buUS_unit_rom={0,0,"_buUS",0,0};
10256   const identificateur & _IDNT_id_buUS_unit_rom=* (const identificateur *) &alias_identificateur_buUS_unit_rom;
10257   const alias_ref_identificateur ref_buUS_unit_rom={-1,0,0,"_buUS",0,0};
10258   const define_alias_gen(alias_buUS_unit_rom,_IDNT,0,&ref_buUS_unit_rom);
10259   const gen & buUS_unit_rom_IDNT_e = * (gen *) & alias_buUS_unit_rom;
10260 
10261   static const alias_identificateur alias_identificateur_c3__unit_rom={0,0,"_c3_",0,0};
10262   const identificateur & _IDNT_id_c3__unit_rom=* (const identificateur *) &alias_identificateur_c3__unit_rom;
10263   const alias_ref_identificateur ref_c3__unit_rom={-1,0,0,"_c3_",0,0};
10264   const define_alias_gen(alias_c3__unit_rom,_IDNT,0,&ref_c3__unit_rom);
10265   const gen & c3__unit_rom_IDNT_e = * (gen *) & alias_c3__unit_rom;
10266 
10267   static const alias_identificateur alias_identificateur_c__unit_rom={0,0,"_c_",0,0};
10268   const identificateur & _IDNT_id_c__unit_rom=* (const identificateur *) &alias_identificateur_c__unit_rom;
10269   const alias_ref_identificateur ref_c__unit_rom={-1,0,0,"_c_",0,0};
10270   const define_alias_gen(alias_c__unit_rom,_IDNT,0,&ref_c__unit_rom);
10271   const gen & c__unit_rom_IDNT_e = * (gen *) & alias_c__unit_rom;
10272 
10273   static const alias_identificateur alias_identificateur_cal_unit_rom={0,0,"_cal",0,0};
10274   const identificateur & _IDNT_id_cal_unit_rom=* (const identificateur *) &alias_identificateur_cal_unit_rom;
10275   const alias_ref_identificateur ref_cal_unit_rom={-1,0,0,"_cal",0,0};
10276   const define_alias_gen(alias_cal_unit_rom,_IDNT,0,&ref_cal_unit_rom);
10277   const gen & cal_unit_rom_IDNT_e = * (gen *) & alias_cal_unit_rom;
10278 
10279   static const alias_identificateur alias_identificateur_cd_unit_rom={0,0,"_cd",0,0};
10280   const identificateur & _IDNT_id_cd_unit_rom=* (const identificateur *) &alias_identificateur_cd_unit_rom;
10281   const alias_ref_identificateur ref_cd_unit_rom={-1,0,0,"_cd",0,0};
10282   const define_alias_gen(alias_cd_unit_rom,_IDNT,0,&ref_cd_unit_rom);
10283   const gen & cd_unit_rom_IDNT_e = * (gen *) & alias_cd_unit_rom;
10284 
10285   static const alias_identificateur alias_identificateur_cf_unit_rom={0,0,"_cf",0,0};
10286   const identificateur & _IDNT_id_cf_unit_rom=* (const identificateur *) &alias_identificateur_cf_unit_rom;
10287   const alias_ref_identificateur ref_cf_unit_rom={-1,0,0,"_cf",0,0};
10288   const define_alias_gen(alias_cf_unit_rom,_IDNT,0,&ref_cf_unit_rom);
10289   const gen & cf_unit_rom_IDNT_e = * (gen *) & alias_cf_unit_rom;
10290 
10291   static const alias_identificateur alias_identificateur_chain_unit_rom={0,0,"_chain",0,0};
10292   const identificateur & _IDNT_id_chain_unit_rom=* (const identificateur *) &alias_identificateur_chain_unit_rom;
10293   const alias_ref_identificateur ref_chain_unit_rom={-1,0,0,"_chain",0,0};
10294   const define_alias_gen(alias_chain_unit_rom,_IDNT,0,&ref_chain_unit_rom);
10295   const gen & chain_unit_rom_IDNT_e = * (gen *) & alias_chain_unit_rom;
10296 
10297   static const alias_identificateur alias_identificateur_ct_unit_rom={0,0,"_ct",0,0};
10298   const identificateur & _IDNT_id_ct_unit_rom=* (const identificateur *) &alias_identificateur_ct_unit_rom;
10299   const alias_ref_identificateur ref_ct_unit_rom={-1,0,0,"_ct",0,0};
10300   const define_alias_gen(alias_ct_unit_rom,_IDNT,0,&ref_ct_unit_rom);
10301   const gen & ct_unit_rom_IDNT_e = * (gen *) & alias_ct_unit_rom;
10302 
10303   static const alias_identificateur alias_identificateur_cu_unit_rom={0,0,"_cu",0,0};
10304   const identificateur & _IDNT_id_cu_unit_rom=* (const identificateur *) &alias_identificateur_cu_unit_rom;
10305   const alias_ref_identificateur ref_cu_unit_rom={-1,0,0,"_cu",0,0};
10306   const define_alias_gen(alias_cu_unit_rom,_IDNT,0,&ref_cu_unit_rom);
10307   const gen & cu_unit_rom_IDNT_e = * (gen *) & alias_cu_unit_rom;
10308 
10309   static const alias_identificateur alias_identificateur_d_unit_rom={0,0,"_d",0,0};
10310   const identificateur & _IDNT_id_d_unit_rom=* (const identificateur *) &alias_identificateur_d_unit_rom;
10311   const alias_ref_identificateur ref_d_unit_rom={-1,0,0,"_d",0,0};
10312   const define_alias_gen(alias_d_unit_rom,_IDNT,0,&ref_d_unit_rom);
10313   const gen & d_unit_rom_IDNT_e = * (gen *) & alias_d_unit_rom;
10314 
10315   static const alias_identificateur alias_identificateur_dB_unit_rom={0,0,"_dB",0,0};
10316   const identificateur & _IDNT_id_dB_unit_rom=* (const identificateur *) &alias_identificateur_dB_unit_rom;
10317   const alias_ref_identificateur ref_dB_unit_rom={-1,0,0,"_dB",0,0};
10318   const define_alias_gen(alias_dB_unit_rom,_IDNT,0,&ref_dB_unit_rom);
10319   const gen & dB_unit_rom_IDNT_e = * (gen *) & alias_dB_unit_rom;
10320 
10321   static const alias_identificateur alias_identificateur_deg_unit_rom={0,0,"_deg",0,0};
10322   const identificateur & _IDNT_id_deg_unit_rom=* (const identificateur *) &alias_identificateur_deg_unit_rom;
10323   const alias_ref_identificateur ref_deg_unit_rom={-1,0,0,"_deg",0,0};
10324   const define_alias_gen(alias_deg_unit_rom,_IDNT,0,&ref_deg_unit_rom);
10325   const gen & deg_unit_rom_IDNT_e = * (gen *) & alias_deg_unit_rom;
10326 
10327   static const alias_identificateur alias_identificateur_dyn_unit_rom={0,0,"_dyn",0,0};
10328   const identificateur & _IDNT_id_dyn_unit_rom=* (const identificateur *) &alias_identificateur_dyn_unit_rom;
10329   const alias_ref_identificateur ref_dyn_unit_rom={-1,0,0,"_dyn",0,0};
10330   const define_alias_gen(alias_dyn_unit_rom,_IDNT,0,&ref_dyn_unit_rom);
10331   const gen & dyn_unit_rom_IDNT_e = * (gen *) & alias_dyn_unit_rom;
10332 
10333   static const alias_identificateur alias_identificateur_eV_unit_rom={0,0,"_eV",0,0};
10334   const identificateur & _IDNT_id_eV_unit_rom=* (const identificateur *) &alias_identificateur_eV_unit_rom;
10335   const alias_ref_identificateur ref_eV_unit_rom={-1,0,0,"_eV",0,0};
10336   const define_alias_gen(alias_eV_unit_rom,_IDNT,0,&ref_eV_unit_rom);
10337   const gen & eV_unit_rom_IDNT_e = * (gen *) & alias_eV_unit_rom;
10338 
10339   static const alias_identificateur alias_identificateur_epsilon0q__unit_rom={0,0,"_epsilon0q_",0,0};
10340   const identificateur & _IDNT_id_epsilon0q__unit_rom=* (const identificateur *) &alias_identificateur_epsilon0q__unit_rom;
10341   const alias_ref_identificateur ref_epsilon0q__unit_rom={-1,0,0,"_epsilon0q_",0,0};
10342   const define_alias_gen(alias_epsilon0q__unit_rom,_IDNT,0,&ref_epsilon0q__unit_rom);
10343   const gen & epsilon0q__unit_rom_IDNT_e = * (gen *) & alias_epsilon0q__unit_rom;
10344 
10345   static const alias_identificateur alias_identificateur_epsilonox__unit_rom={0,0,"_epsilonox",0,0};
10346   const identificateur & _IDNT_id_epsilonox__unit_rom=* (const identificateur *) &alias_identificateur_epsilonox__unit_rom;
10347   const alias_ref_identificateur ref_epsilonox__unit_rom={-1,0,0,"_epsilonox",0,0};
10348   const define_alias_gen(alias_epsilonox__unit_rom,_IDNT,0,&ref_epsilonox__unit_rom);
10349   const gen & epsilonox__unit_rom_IDNT_e = * (gen *) & alias_epsilonox__unit_rom;
10350 
10351   static const alias_identificateur alias_identificateur_epsilonsi__unit_rom={0,0,"_epsilonsi_",0,0};
10352   const identificateur & _IDNT_id_epsilonsi__unit_rom=* (const identificateur *) &alias_identificateur_epsilonsi__unit_rom;
10353   const alias_ref_identificateur ref_epsilonsi__unit_rom={-1,0,0,"_epsilonsi_",0,0};
10354   const define_alias_gen(alias_epsilonsi__unit_rom,_IDNT,0,&ref_epsilonsi__unit_rom);
10355   const gen & epsilonsi__unit_rom_IDNT_e = * (gen *) & alias_epsilonsi__unit_rom;
10356 
10357   static const alias_identificateur alias_identificateur_erg_unit_rom={0,0,"_erg",0,0};
10358   const identificateur & _IDNT_id_erg_unit_rom=* (const identificateur *) &alias_identificateur_erg_unit_rom;
10359   const alias_ref_identificateur ref_erg_unit_rom={-1,0,0,"_erg",0,0};
10360   const define_alias_gen(alias_erg_unit_rom,_IDNT,0,&ref_erg_unit_rom);
10361   const gen & erg_unit_rom_IDNT_e = * (gen *) & alias_erg_unit_rom;
10362 
10363   static const alias_identificateur alias_identificateur_f0__unit_rom={0,0,"_f0_",0,0};
10364   const identificateur & _IDNT_id_f0__unit_rom=* (const identificateur *) &alias_identificateur_f0__unit_rom;
10365   const alias_ref_identificateur ref_f0__unit_rom={-1,0,0,"_f0_",0,0};
10366   const define_alias_gen(alias_f0__unit_rom,_IDNT,0,&ref_f0__unit_rom);
10367   const gen & f0__unit_rom_IDNT_e = * (gen *) & alias_f0__unit_rom;
10368 
10369   static const alias_identificateur alias_identificateur_fath_unit_rom={0,0,"_fath",0,0};
10370   const identificateur & _IDNT_id_fath_unit_rom=* (const identificateur *) &alias_identificateur_fath_unit_rom;
10371   const alias_ref_identificateur ref_fath_unit_rom={-1,0,0,"_fath",0,0};
10372   const define_alias_gen(alias_fath_unit_rom,_IDNT,0,&ref_fath_unit_rom);
10373   const gen & fath_unit_rom_IDNT_e = * (gen *) & alias_fath_unit_rom;
10374 
10375   static const alias_identificateur alias_identificateur_fbm_unit_rom={0,0,"_fbm",0,0};
10376   const identificateur & _IDNT_id_fbm_unit_rom=* (const identificateur *) &alias_identificateur_fbm_unit_rom;
10377   const alias_ref_identificateur ref_fbm_unit_rom={-1,0,0,"_fbm",0,0};
10378   const define_alias_gen(alias_fbm_unit_rom,_IDNT,0,&ref_fbm_unit_rom);
10379   const gen & fbm_unit_rom_IDNT_e = * (gen *) & alias_fbm_unit_rom;
10380 
10381   static const alias_identificateur alias_identificateur_fc_unit_rom={0,0,"_fc",0,0};
10382   const identificateur & _IDNT_id_fc_unit_rom=* (const identificateur *) &alias_identificateur_fc_unit_rom;
10383   const alias_ref_identificateur ref_fc_unit_rom={-1,0,0,"_fc",0,0};
10384   const define_alias_gen(alias_fc_unit_rom,_IDNT,0,&ref_fc_unit_rom);
10385   const gen & fc_unit_rom_IDNT_e = * (gen *) & alias_fc_unit_rom;
10386 
10387   static const alias_identificateur alias_identificateur_fermi_unit_rom={0,0,"_fermi",0,0};
10388   const identificateur & _IDNT_id_fermi_unit_rom=* (const identificateur *) &alias_identificateur_fermi_unit_rom;
10389   const alias_ref_identificateur ref_fermi_unit_rom={-1,0,0,"_fermi",0,0};
10390   const define_alias_gen(alias_fermi_unit_rom,_IDNT,0,&ref_fermi_unit_rom);
10391   const gen & fermi_unit_rom_IDNT_e = * (gen *) & alias_fermi_unit_rom;
10392 
10393   static const alias_identificateur alias_identificateur_flam_unit_rom={0,0,"_flam",0,0};
10394   const identificateur & _IDNT_id_flam_unit_rom=* (const identificateur *) &alias_identificateur_flam_unit_rom;
10395   const alias_ref_identificateur ref_flam_unit_rom={-1,0,0,"_flam",0,0};
10396   const define_alias_gen(alias_flam_unit_rom,_IDNT,0,&ref_flam_unit_rom);
10397   const gen & flam_unit_rom_IDNT_e = * (gen *) & alias_flam_unit_rom;
10398 
10399   static const alias_identificateur alias_identificateur_fm_unit_rom={0,0,"_fm",0,0};
10400   const identificateur & _IDNT_id_fm_unit_rom=* (const identificateur *) &alias_identificateur_fm_unit_rom;
10401   const alias_ref_identificateur ref_fm_unit_rom={-1,0,0,"_fm",0,0};
10402   const define_alias_gen(alias_fm_unit_rom,_IDNT,0,&ref_fm_unit_rom);
10403   const gen & fm_unit_rom_IDNT_e = * (gen *) & alias_fm_unit_rom;
10404 
10405   static const alias_identificateur alias_identificateur_ft_unit_rom={0,0,"_ft",0,0};
10406   const identificateur & _IDNT_id_ft_unit_rom=* (const identificateur *) &alias_identificateur_ft_unit_rom;
10407   const alias_ref_identificateur ref_ft_unit_rom={-1,0,0,"_ft",0,0};
10408   const define_alias_gen(alias_ft_unit_rom,_IDNT,0,&ref_ft_unit_rom);
10409   const gen & ft_unit_rom_IDNT_e = * (gen *) & alias_ft_unit_rom;
10410 
10411   static const alias_identificateur alias_identificateur_ftUS_unit_rom={0,0,"_ftUS",0,0};
10412   const identificateur & _IDNT_id_ftUS_unit_rom=* (const identificateur *) &alias_identificateur_ftUS_unit_rom;
10413   const alias_ref_identificateur ref_ftUS_unit_rom={-1,0,0,"_ftUS",0,0};
10414   const define_alias_gen(alias_ftUS_unit_rom,_IDNT,0,&ref_ftUS_unit_rom);
10415   const gen & ftUS_unit_rom_IDNT_e = * (gen *) & alias_ftUS_unit_rom;
10416 
10417   static const alias_identificateur alias_identificateur_g_unit_rom={0,0,"_g",0,0};
10418   const identificateur & _IDNT_id_g_unit_rom=* (const identificateur *) &alias_identificateur_g_unit_rom;
10419   const alias_ref_identificateur ref_g_unit_rom={-1,0,0,"_g",0,0};
10420   const define_alias_gen(alias_g_unit_rom,_IDNT,0,&ref_g_unit_rom);
10421   const gen & g_unit_rom_IDNT_e = * (gen *) & alias_g_unit_rom;
10422 
10423   static const alias_identificateur alias_identificateur_g__unit_rom={0,0,"_g_",0,0};
10424   const identificateur & _IDNT_id_g__unit_rom=* (const identificateur *) &alias_identificateur_g__unit_rom;
10425   const alias_ref_identificateur ref_g__unit_rom={-1,0,0,"_g_",0,0};
10426   const define_alias_gen(alias_g__unit_rom,_IDNT,0,&ref_g__unit_rom);
10427   const gen & g__unit_rom_IDNT_e = * (gen *) & alias_g__unit_rom;
10428 
10429   static const alias_identificateur alias_identificateur_galC_unit_rom={0,0,"_galC",0,0};
10430   const identificateur & _IDNT_id_galC_unit_rom=* (const identificateur *) &alias_identificateur_galC_unit_rom;
10431   const alias_ref_identificateur ref_galC_unit_rom={-1,0,0,"_galC",0,0};
10432   const define_alias_gen(alias_galC_unit_rom,_IDNT,0,&ref_galC_unit_rom);
10433   const gen & galC_unit_rom_IDNT_e = * (gen *) & alias_galC_unit_rom;
10434 
10435   static const alias_identificateur alias_identificateur_galUK_unit_rom={0,0,"_galUK",0,0};
10436   const identificateur & _IDNT_id_galUK_unit_rom=* (const identificateur *) &alias_identificateur_galUK_unit_rom;
10437   const alias_ref_identificateur ref_galUK_unit_rom={-1,0,0,"_galUK",0,0};
10438   const define_alias_gen(alias_galUK_unit_rom,_IDNT,0,&ref_galUK_unit_rom);
10439   const gen & galUK_unit_rom_IDNT_e = * (gen *) & alias_galUK_unit_rom;
10440 
10441   static const alias_identificateur alias_identificateur_galUS_unit_rom={0,0,"_galUS",0,0};
10442   const identificateur & _IDNT_id_galUS_unit_rom=* (const identificateur *) &alias_identificateur_galUS_unit_rom;
10443   const alias_ref_identificateur ref_galUS_unit_rom={-1,0,0,"_galUS",0,0};
10444   const define_alias_gen(alias_galUS_unit_rom,_IDNT,0,&ref_galUS_unit_rom);
10445   const gen & galUS_unit_rom_IDNT_e = * (gen *) & alias_galUS_unit_rom;
10446 
10447   static const alias_identificateur alias_identificateur_gf_unit_rom={0,0,"_gf",0,0};
10448   const identificateur & _IDNT_id_gf_unit_rom=* (const identificateur *) &alias_identificateur_gf_unit_rom;
10449   const alias_ref_identificateur ref_gf_unit_rom={-1,0,0,"_gf",0,0};
10450   const define_alias_gen(alias_gf_unit_rom,_IDNT,0,&ref_gf_unit_rom);
10451   const gen & gf_unit_rom_IDNT_e = * (gen *) & alias_gf_unit_rom;
10452 
10453   static const alias_identificateur alias_identificateur_gmol_unit_rom={0,0,"_gmol",0,0};
10454   const identificateur & _IDNT_id_gmol_unit_rom=* (const identificateur *) &alias_identificateur_gmol_unit_rom;
10455   const alias_ref_identificateur ref_gmol_unit_rom={-1,0,0,"_gmol",0,0};
10456   const define_alias_gen(alias_gmol_unit_rom,_IDNT,0,&ref_gmol_unit_rom);
10457   const gen & gmol_unit_rom_IDNT_e = * (gen *) & alias_gmol_unit_rom;
10458 
10459   static const alias_identificateur alias_identificateur_gon_unit_rom={0,0,"_gon",0,0};
10460   const identificateur & _IDNT_id_gon_unit_rom=* (const identificateur *) &alias_identificateur_gon_unit_rom;
10461   const alias_ref_identificateur ref_gon_unit_rom={-1,0,0,"_gon",0,0};
10462   const define_alias_gen(alias_gon_unit_rom,_IDNT,0,&ref_gon_unit_rom);
10463   const gen & gon_unit_rom_IDNT_e = * (gen *) & alias_gon_unit_rom;
10464 
10465   static const alias_identificateur alias_identificateur_grad_unit_rom={0,0,"_grad",0,0};
10466   const identificateur & _IDNT_id_grad_unit_rom=* (const identificateur *) &alias_identificateur_grad_unit_rom;
10467   const alias_ref_identificateur ref_grad_unit_rom={-1,0,0,"_grad",0,0};
10468   const define_alias_gen(alias_grad_unit_rom,_IDNT,0,&ref_grad_unit_rom);
10469   const gen & grad_unit_rom_IDNT_e = * (gen *) & alias_grad_unit_rom;
10470 
10471   static const alias_identificateur alias_identificateur_grain_unit_rom={0,0,"_grain",0,0};
10472   const identificateur & _IDNT_id_grain_unit_rom=* (const identificateur *) &alias_identificateur_grain_unit_rom;
10473   const alias_ref_identificateur ref_grain_unit_rom={-1,0,0,"_grain",0,0};
10474   const define_alias_gen(alias_grain_unit_rom,_IDNT,0,&ref_grain_unit_rom);
10475   const gen & grain_unit_rom_IDNT_e = * (gen *) & alias_grain_unit_rom;
10476 
10477   static const alias_identificateur alias_identificateur_h_unit_rom={0,0,"_h",0,0};
10478   const identificateur & _IDNT_id_h_unit_rom=* (const identificateur *) &alias_identificateur_h_unit_rom;
10479   const alias_ref_identificateur ref_h_unit_rom={-1,0,0,"_h",0,0};
10480   const define_alias_gen(alias_h_unit_rom,_IDNT,0,&ref_h_unit_rom);
10481   const gen & h_unit_rom_IDNT_e = * (gen *) & alias_h_unit_rom;
10482 
10483   static const alias_identificateur alias_identificateur_h__unit_rom={0,0,"_h_",0,0};
10484   const identificateur & _IDNT_id_h__unit_rom=* (const identificateur *) &alias_identificateur_h__unit_rom;
10485   const alias_ref_identificateur ref_h__unit_rom={-1,0,0,"_h_",0,0};
10486   const define_alias_gen(alias_h__unit_rom,_IDNT,0,&ref_h__unit_rom);
10487   const gen & h__unit_rom_IDNT_e = * (gen *) & alias_h__unit_rom;
10488 
10489   static const alias_identificateur alias_identificateur_ha_unit_rom={0,0,"_ha",0,0};
10490   const identificateur & _IDNT_id_ha_unit_rom=* (const identificateur *) &alias_identificateur_ha_unit_rom;
10491   const alias_ref_identificateur ref_ha_unit_rom={-1,0,0,"_ha",0,0};
10492   const define_alias_gen(alias_ha_unit_rom,_IDNT,0,&ref_ha_unit_rom);
10493   const gen & ha_unit_rom_IDNT_e = * (gen *) & alias_ha_unit_rom;
10494 
10495   static const alias_identificateur alias_identificateur_hbar__unit_rom={0,0,"_hbar_",0,0};
10496   const identificateur & _IDNT_id_hbar__unit_rom=* (const identificateur *) &alias_identificateur_hbar__unit_rom;
10497   const alias_ref_identificateur ref_hbar__unit_rom={-1,0,0,"_hbar_",0,0};
10498   const define_alias_gen(alias_hbar__unit_rom,_IDNT,0,&ref_hbar__unit_rom);
10499   const gen & hbar__unit_rom_IDNT_e = * (gen *) & alias_hbar__unit_rom;
10500 
10501   static const alias_identificateur alias_identificateur_hp_unit_rom={0,0,"_hp",0,0};
10502   const identificateur & _IDNT_id_hp_unit_rom=* (const identificateur *) &alias_identificateur_hp_unit_rom;
10503   const alias_ref_identificateur ref_hp_unit_rom={-1,0,0,"_hp",0,0};
10504   const define_alias_gen(alias_hp_unit_rom,_IDNT,0,&ref_hp_unit_rom);
10505   const gen & hp_unit_rom_IDNT_e = * (gen *) & alias_hp_unit_rom;
10506 
10507   static const alias_identificateur alias_identificateur_inH2O_unit_rom={0,0,"_inH2O",0,0};
10508   const identificateur & _IDNT_id_inH2O_unit_rom=* (const identificateur *) &alias_identificateur_inH2O_unit_rom;
10509   const alias_ref_identificateur ref_inH2O_unit_rom={-1,0,0,"_inH2O",0,0};
10510   const define_alias_gen(alias_inH2O_unit_rom,_IDNT,0,&ref_inH2O_unit_rom);
10511   const gen & inH2O_unit_rom_IDNT_e = * (gen *) & alias_inH2O_unit_rom;
10512 
10513   static const alias_identificateur alias_identificateur_inHg_unit_rom={0,0,"_inHg",0,0};
10514   const identificateur & _IDNT_id_inHg_unit_rom=* (const identificateur *) &alias_identificateur_inHg_unit_rom;
10515   const alias_ref_identificateur ref_inHg_unit_rom={-1,0,0,"_inHg",0,0};
10516   const define_alias_gen(alias_inHg_unit_rom,_IDNT,0,&ref_inHg_unit_rom);
10517   const gen & inHg_unit_rom_IDNT_e = * (gen *) & alias_inHg_unit_rom;
10518 
10519   static const alias_identificateur alias_identificateur_inch_unit_rom={0,0,"_inch",0,0};
10520   const identificateur & _IDNT_id_inch_unit_rom=* (const identificateur *) &alias_identificateur_inch_unit_rom;
10521   const alias_ref_identificateur ref_inch_unit_rom={-1,0,0,"_inch",0,0};
10522   const define_alias_gen(alias_inch_unit_rom,_IDNT,0,&ref_inch_unit_rom);
10523   const gen & inch_unit_rom_IDNT_e = * (gen *) & alias_inch_unit_rom;
10524 
10525   static const alias_identificateur alias_identificateur_j_unit_rom={0,0,"_j",0,0};
10526   const identificateur & _IDNT_id_j_unit_rom=* (const identificateur *) &alias_identificateur_j_unit_rom;
10527   const alias_ref_identificateur ref_j_unit_rom={-1,0,0,"_j",0,0};
10528   const define_alias_gen(alias_j_unit_rom,_IDNT,0,&ref_j_unit_rom);
10529   const gen & j_unit_rom_IDNT_e = * (gen *) & alias_j_unit_rom;
10530 
10531   static const alias_identificateur alias_identificateur_k__unit_rom={0,0,"_k_",0,0};
10532   const identificateur & _IDNT_id_k__unit_rom=* (const identificateur *) &alias_identificateur_k__unit_rom;
10533   const alias_ref_identificateur ref_k__unit_rom={-1,0,0,"_k_",0,0};
10534   const define_alias_gen(alias_k__unit_rom,_IDNT,0,&ref_k__unit_rom);
10535   const gen & k__unit_rom_IDNT_e = * (gen *) & alias_k__unit_rom;
10536 
10537   static const alias_identificateur alias_identificateur_kip_unit_rom={0,0,"_kip",0,0};
10538   const identificateur & _IDNT_id_kip_unit_rom=* (const identificateur *) &alias_identificateur_kip_unit_rom;
10539   const alias_ref_identificateur ref_kip_unit_rom={-1,0,0,"_kip",0,0};
10540   const define_alias_gen(alias_kip_unit_rom,_IDNT,0,&ref_kip_unit_rom);
10541   const gen & kip_unit_rom_IDNT_e = * (gen *) & alias_kip_unit_rom;
10542 
10543   static const alias_identificateur alias_identificateur_knot_unit_rom={0,0,"_knot",0,0};
10544   const identificateur & _IDNT_id_knot_unit_rom=* (const identificateur *) &alias_identificateur_knot_unit_rom;
10545   const alias_ref_identificateur ref_knot_unit_rom={-1,0,0,"_knot",0,0};
10546   const define_alias_gen(alias_knot_unit_rom,_IDNT,0,&ref_knot_unit_rom);
10547   const gen & knot_unit_rom_IDNT_e = * (gen *) & alias_knot_unit_rom;
10548 
10549   static const alias_identificateur alias_identificateur_kph_unit_rom={0,0,"_kph",0,0};
10550   const identificateur & _IDNT_id_kph_unit_rom=* (const identificateur *) &alias_identificateur_kph_unit_rom;
10551   const alias_ref_identificateur ref_kph_unit_rom={-1,0,0,"_kph",0,0};
10552   const define_alias_gen(alias_kph_unit_rom,_IDNT,0,&ref_kph_unit_rom);
10553   const gen & kph_unit_rom_IDNT_e = * (gen *) & alias_kph_unit_rom;
10554 
10555   static const alias_identificateur alias_identificateur_kq__unit_rom={0,0,"_kq",0,0};
10556   const identificateur & _IDNT_id_kq__unit_rom=* (const identificateur *) &alias_identificateur_kq__unit_rom;
10557   const alias_ref_identificateur ref_kq__unit_rom={-1,0,0,"_kq_",0,0};
10558   const define_alias_gen(alias_kq__unit_rom,_IDNT,0,&ref_kq__unit_rom);
10559   const gen & kq__unit_rom_IDNT_e = * (gen *) & alias_kq__unit_rom;
10560 
10561   static const alias_identificateur alias_identificateur_l_unit_rom={0,0,"_l",0,0};
10562   const identificateur & _IDNT_id_l_unit_rom=* (const identificateur *) &alias_identificateur_l_unit_rom;
10563   const alias_ref_identificateur ref_l_unit_rom={-1,0,0,"_l",0,0};
10564   const define_alias_gen(alias_l_unit_rom,_IDNT,0,&ref_l_unit_rom);
10565   const gen & l_unit_rom_IDNT_e = * (gen *) & alias_l_unit_rom;
10566 
10567   static const alias_identificateur alias_identificateur_lam_unit_rom={0,0,"_lam",0,0};
10568   const identificateur & _IDNT_id_lam_unit_rom=* (const identificateur *) &alias_identificateur_lam_unit_rom;
10569   const alias_ref_identificateur ref_lam_unit_rom={-1,0,0,"_lam",0,0};
10570   const define_alias_gen(alias_lam_unit_rom,_IDNT,0,&ref_lam_unit_rom);
10571   const gen & lam_unit_rom_IDNT_e = * (gen *) & alias_lam_unit_rom;
10572 
10573   static const alias_identificateur alias_identificateur_lambda0_unit_rom={0,0,"_lambda0",0,0};
10574   const identificateur & _IDNT_id_lambda0_unit_rom=* (const identificateur *) &alias_identificateur_lambda0_unit_rom;
10575   const alias_ref_identificateur ref_lambda0_unit_rom={-1,0,0,"_lambda0",0,0};
10576   const define_alias_gen(alias_lambda0_unit_rom,_IDNT,0,&ref_lambda0_unit_rom);
10577   const gen & lambda0_unit_rom_IDNT_e = * (gen *) & alias_lambda0_unit_rom;
10578 
10579   static const alias_identificateur alias_identificateur_lambdac__unit_rom={0,0,"_lambdac_",0,0};
10580   const identificateur & _IDNT_id_lambdac__unit_rom=* (const identificateur *) &alias_identificateur_lambdac__unit_rom;
10581   const alias_ref_identificateur ref_lambdac__unit_rom={-1,0,0,"_lambdac_",0,0};
10582   const define_alias_gen(alias_lambdac__unit_rom,_IDNT,0,&ref_lambdac__unit_rom);
10583   const gen & lambdac__unit_rom_IDNT_e = * (gen *) & alias_lambdac__unit_rom;
10584 
10585   static const alias_identificateur alias_identificateur_lb_unit_rom={0,0,"_lb",0,0};
10586   const identificateur & _IDNT_id_lb_unit_rom=* (const identificateur *) &alias_identificateur_lb_unit_rom;
10587   const alias_ref_identificateur ref_lb_unit_rom={-1,0,0,"_lb",0,0};
10588   const define_alias_gen(alias_lb_unit_rom,_IDNT,0,&ref_lb_unit_rom);
10589   const gen & lb_unit_rom_IDNT_e = * (gen *) & alias_lb_unit_rom;
10590 
10591   static const alias_identificateur alias_identificateur_lbf_unit_rom={0,0,"_lbf",0,0};
10592   const identificateur & _IDNT_id_lbf_unit_rom=* (const identificateur *) &alias_identificateur_lbf_unit_rom;
10593   const alias_ref_identificateur ref_lbf_unit_rom={-1,0,0,"_lbf",0,0};
10594   const define_alias_gen(alias_lbf_unit_rom,_IDNT,0,&ref_lbf_unit_rom);
10595   const gen & lbf_unit_rom_IDNT_e = * (gen *) & alias_lbf_unit_rom;
10596 
10597   static const alias_identificateur alias_identificateur_lbmol_unit_rom={0,0,"_lbmol",0,0};
10598   const identificateur & _IDNT_id_lbmol_unit_rom=* (const identificateur *) &alias_identificateur_lbmol_unit_rom;
10599   const alias_ref_identificateur ref_lbmol_unit_rom={-1,0,0,"_lbmol",0,0};
10600   const define_alias_gen(alias_lbmol_unit_rom,_IDNT,0,&ref_lbmol_unit_rom);
10601   const gen & lbmol_unit_rom_IDNT_e = * (gen *) & alias_lbmol_unit_rom;
10602 
10603   static const alias_identificateur alias_identificateur_lbt_unit_rom={0,0,"_lbt",0,0};
10604   const identificateur & _IDNT_id_lbt_unit_rom=* (const identificateur *) &alias_identificateur_lbt_unit_rom;
10605   const alias_ref_identificateur ref_lbt_unit_rom={-1,0,0,"_lbt",0,0};
10606   const define_alias_gen(alias_lbt_unit_rom,_IDNT,0,&ref_lbt_unit_rom);
10607   const gen & lbt_unit_rom_IDNT_e = * (gen *) & alias_lbt_unit_rom;
10608 
10609   static const alias_identificateur alias_identificateur_lep_unit_rom={0,0,"_lep",0,0};
10610   const identificateur & _IDNT_id_lep_unit_rom=* (const identificateur *) &alias_identificateur_lep_unit_rom;
10611   const alias_ref_identificateur ref_lep_unit_rom={-1,0,0,"_lep",0,0};
10612   const define_alias_gen(alias_lep_unit_rom,_IDNT,0,&ref_lep_unit_rom);
10613   const gen & lep_unit_rom_IDNT_e = * (gen *) & alias_lep_unit_rom;
10614 
10615   static const alias_identificateur alias_identificateur_liqpt_unit_rom={0,0,"_liqpt",0,0};
10616   const identificateur & _IDNT_id_liqpt_unit_rom=* (const identificateur *) &alias_identificateur_liqpt_unit_rom;
10617   const alias_ref_identificateur ref_liqpt_unit_rom={-1,0,0,"_liqpt",0,0};
10618   const define_alias_gen(alias_liqpt_unit_rom,_IDNT,0,&ref_liqpt_unit_rom);
10619   const gen & liqpt_unit_rom_IDNT_e = * (gen *) & alias_liqpt_unit_rom;
10620 
10621   static const alias_identificateur alias_identificateur_lyr_unit_rom={0,0,"_lyr",0,0};
10622   const identificateur & _IDNT_id_lyr_unit_rom=* (const identificateur *) &alias_identificateur_lyr_unit_rom;
10623   const alias_ref_identificateur ref_lyr_unit_rom={-1,0,0,"_lyr",0,0};
10624   const define_alias_gen(alias_lyr_unit_rom,_IDNT,0,&ref_lyr_unit_rom);
10625   const gen & lyr_unit_rom_IDNT_e = * (gen *) & alias_lyr_unit_rom;
10626 
10627   static const alias_identificateur alias_identificateur_m_unit_rom={0,0,"_m",0,0};
10628   const identificateur & _IDNT_id_m_unit_rom=* (const identificateur *) &alias_identificateur_m_unit_rom;
10629   const alias_ref_identificateur ref_m_unit_rom={-1,0,0,"_m",0,0};
10630   const define_alias_gen(alias_m_unit_rom,_IDNT,0,&ref_m_unit_rom);
10631   const gen & m_unit_rom_IDNT_e = * (gen *) & alias_m_unit_rom;
10632 
10633   static const alias_identificateur alias_identificateur_mEarth__unit_rom={0,0,"_mEarth_",0,0};
10634   const identificateur & _IDNT_id_mEarth__unit_rom=* (const identificateur *) &alias_identificateur_mEarth__unit_rom;
10635   const alias_ref_identificateur ref_mEarth__unit_rom={-1,0,0,"_mEarth_",0,0};
10636   const define_alias_gen(alias_mEarth__unit_rom,_IDNT,0,&ref_mEarth__unit_rom);
10637   const gen & mEarth__unit_rom_IDNT_e = * (gen *) & alias_mEarth__unit_rom;
10638 
10639   static const alias_identificateur alias_identificateur_mSun__unit_rom={0,0,"_mSun_",0,0};
10640   const identificateur & _IDNT_id_mSun__unit_rom=* (const identificateur *) &alias_identificateur_mSun__unit_rom;
10641   const alias_ref_identificateur ref_mSun__unit_rom={-1,0,0,"_mSun_",0,0};
10642   const define_alias_gen(alias_mSun__unit_rom,_IDNT,0,&ref_mSun__unit_rom);
10643   const gen & mSun__unit_rom_IDNT_e = * (gen *) & alias_mSun__unit_rom;
10644 
10645   static const alias_identificateur alias_identificateur_me__unit_rom={0,0,"_me_",0,0};
10646   const identificateur & _IDNT_id_me__unit_rom=* (const identificateur *) &alias_identificateur_me__unit_rom;
10647   const alias_ref_identificateur ref_me__unit_rom={-1,0,0,"_me_",0,0};
10648   const define_alias_gen(alias_me__unit_rom,_IDNT,0,&ref_me__unit_rom);
10649   const gen & me__unit_rom_IDNT_e = * (gen *) & alias_me__unit_rom;
10650 
10651   static const alias_identificateur alias_identificateur_mho_unit_rom={0,0,"_mho",0,0};
10652   const identificateur & _IDNT_id_mho_unit_rom=* (const identificateur *) &alias_identificateur_mho_unit_rom;
10653   const alias_ref_identificateur ref_mho_unit_rom={-1,0,0,"_mho",0,0};
10654   const define_alias_gen(alias_mho_unit_rom,_IDNT,0,&ref_mho_unit_rom);
10655   const gen & mho_unit_rom_IDNT_e = * (gen *) & alias_mho_unit_rom;
10656 
10657   static const alias_identificateur alias_identificateur_mi_unit_rom={0,0,"_mi",0,0};
10658   const identificateur & _IDNT_id_mi_unit_rom=* (const identificateur *) &alias_identificateur_mi_unit_rom;
10659   const alias_ref_identificateur ref_mi_unit_rom={-1,0,0,"_mi",0,0};
10660   const define_alias_gen(alias_mi_unit_rom,_IDNT,0,&ref_mi_unit_rom);
10661   const gen & mi_unit_rom_IDNT_e = * (gen *) & alias_mi_unit_rom;
10662 
10663   static const alias_identificateur alias_identificateur_miUS_unit_rom={0,0,"_miUS",0,0};
10664   const identificateur & _IDNT_id_miUS_unit_rom=* (const identificateur *) &alias_identificateur_miUS_unit_rom;
10665   const alias_ref_identificateur ref_miUS_unit_rom={-1,0,0,"_miUS",0,0};
10666   const define_alias_gen(alias_miUS_unit_rom,_IDNT,0,&ref_miUS_unit_rom);
10667   const gen & miUS_unit_rom_IDNT_e = * (gen *) & alias_miUS_unit_rom;
10668 
10669   static const alias_identificateur alias_identificateur_mil_unit_rom={0,0,"_mil",0,0};
10670   const identificateur & _IDNT_id_mil_unit_rom=* (const identificateur *) &alias_identificateur_mil_unit_rom;
10671   const alias_ref_identificateur ref_mil_unit_rom={-1,0,0,"_mil",0,0};
10672   const define_alias_gen(alias_mil_unit_rom,_IDNT,0,&ref_mil_unit_rom);
10673   const gen & mil_unit_rom_IDNT_e = * (gen *) & alias_mil_unit_rom;
10674 
10675   static const alias_identificateur alias_identificateur_mile_unit_rom={0,0,"_mile",0,0};
10676   const identificateur & _IDNT_id_mile_unit_rom=* (const identificateur *) &alias_identificateur_mile_unit_rom;
10677   const alias_ref_identificateur ref_mile_unit_rom={-1,0,0,"_mile",0,0};
10678   const define_alias_gen(alias_mile_unit_rom,_IDNT,0,&ref_mile_unit_rom);
10679   const gen & mile_unit_rom_IDNT_e = * (gen *) & alias_mile_unit_rom;
10680 
10681   static const alias_identificateur alias_identificateur_mille_unit_rom={0,0,"_mille",0,0};
10682   const identificateur & _IDNT_id_mille_unit_rom=* (const identificateur *) &alias_identificateur_mille_unit_rom;
10683   const alias_ref_identificateur ref_mille_unit_rom={-1,0,0,"_mille",0,0};
10684   const define_alias_gen(alias_mille_unit_rom,_IDNT,0,&ref_mille_unit_rom);
10685   const gen & mille_unit_rom_IDNT_e = * (gen *) & alias_mille_unit_rom;
10686 
10687   static const alias_identificateur alias_identificateur_min_unit_rom={0,0,"_min",0,0};
10688   const identificateur & _IDNT_id_min_unit_rom=* (const identificateur *) &alias_identificateur_min_unit_rom;
10689   const alias_ref_identificateur ref_min_unit_rom={-1,0,0,"_min",0,0};
10690   const define_alias_gen(alias_min_unit_rom,_IDNT,0,&ref_min_unit_rom);
10691   const gen & min_unit_rom_IDNT_e = * (gen *) & alias_min_unit_rom;
10692 
10693   static const alias_identificateur alias_identificateur_mmHg_unit_rom={0,0,"_mmHg",0,0};
10694   const identificateur & _IDNT_id_mmHg_unit_rom=* (const identificateur *) &alias_identificateur_mmHg_unit_rom;
10695   const alias_ref_identificateur ref_mmHg_unit_rom={-1,0,0,"_mmHg",0,0};
10696   const define_alias_gen(alias_mmHg_unit_rom,_IDNT,0,&ref_mmHg_unit_rom);
10697   const gen & mmHg_unit_rom_IDNT_e = * (gen *) & alias_mmHg_unit_rom;
10698 
10699   static const alias_identificateur alias_identificateur_mn_unit_rom={0,0,"_mn",0,0};
10700   const identificateur & _IDNT_id_mn_unit_rom=* (const identificateur *) &alias_identificateur_mn_unit_rom;
10701   const alias_ref_identificateur ref_mn_unit_rom={-1,0,0,"_mn",0,0};
10702   const define_alias_gen(alias_mn_unit_rom,_IDNT,0,&ref_mn_unit_rom);
10703   const gen & mn_unit_rom_IDNT_e = * (gen *) & alias_mn_unit_rom;
10704 
10705   static const alias_identificateur alias_identificateur_mol_unit_rom={0,0,"_mol",0,0};
10706   const identificateur & _IDNT_id_mol_unit_rom=* (const identificateur *) &alias_identificateur_mol_unit_rom;
10707   const alias_ref_identificateur ref_mol_unit_rom={-1,0,0,"_mol",0,0};
10708   const define_alias_gen(alias_mol_unit_rom,_IDNT,0,&ref_mol_unit_rom);
10709   const gen & mol_unit_rom_IDNT_e = * (gen *) & alias_mol_unit_rom;
10710 
10711   static const alias_identificateur alias_identificateur_molK_unit_rom={0,0,"_molK",0,0};
10712   const identificateur & _IDNT_id_molK_unit_rom=* (const identificateur *) &alias_identificateur_molK_unit_rom;
10713   const alias_ref_identificateur ref_molK_unit_rom={-1,0,0,"_molK",0,0};
10714   const define_alias_gen(alias_molK_unit_rom,_IDNT,0,&ref_molK_unit_rom);
10715   const gen & molK_unit_rom_IDNT_e = * (gen *) & alias_molK_unit_rom;
10716 
10717   static const alias_identificateur alias_identificateur_mp__unit_rom={0,0,"_mp_",0,0};
10718   const identificateur & _IDNT_id_mp__unit_rom=* (const identificateur *) &alias_identificateur_mp__unit_rom;
10719   const alias_ref_identificateur ref_mp__unit_rom={-1,0,0,"_mp_",0,0};
10720   const define_alias_gen(alias_mp__unit_rom,_IDNT,0,&ref_mp__unit_rom);
10721   const gen & mp__unit_rom_IDNT_e = * (gen *) & alias_mp__unit_rom;
10722 
10723   static const alias_identificateur alias_identificateur_mph_unit_rom={0,0,"_mph",0,0};
10724   const identificateur & _IDNT_id_mph_unit_rom=* (const identificateur *) &alias_identificateur_mph_unit_rom;
10725   const alias_ref_identificateur ref_mph_unit_rom={-1,0,0,"_mph",0,0};
10726   const define_alias_gen(alias_mph_unit_rom,_IDNT,0,&ref_mph_unit_rom);
10727   const gen & mph_unit_rom_IDNT_e = * (gen *) & alias_mph_unit_rom;
10728 
10729   static const alias_identificateur alias_identificateur_mpme__unit_rom={0,0,"_mpme_",0,0};
10730   const identificateur & _IDNT_id_mpme__unit_rom=* (const identificateur *) &alias_identificateur_mpme__unit_rom;
10731   const alias_ref_identificateur ref_mpme__unit_rom={-1,0,0,"_mpme",0,0};
10732   const define_alias_gen(alias_mpme__unit_rom,_IDNT,0,&ref_mpme__unit_rom);
10733   const gen & mpme__unit_rom_IDNT_e = * (gen *) & alias_mpme__unit_rom;
10734 
10735   static const alias_identificateur alias_identificateur_mu0__unit_rom={0,0,"_mu0_",0,0};
10736   const identificateur & _IDNT_id_mu0__unit_rom=* (const identificateur *) &alias_identificateur_mu0__unit_rom;
10737   const alias_ref_identificateur ref_mu0__unit_rom={-1,0,0,"_mu0_",0,0};
10738   const define_alias_gen(alias_mu0__unit_rom,_IDNT,0,&ref_mu0__unit_rom);
10739   const gen & mu0__unit_rom_IDNT_e = * (gen *) & alias_mu0__unit_rom;
10740 
10741   static const alias_identificateur alias_identificateur_muB__unit_rom={0,0,"_muB_",0,0};
10742   const identificateur & _IDNT_id_muB__unit_rom=* (const identificateur *) &alias_identificateur_muB__unit_rom;
10743   const alias_ref_identificateur ref_muB__unit_rom={-1,0,0,"_muB_",0,0};
10744   const define_alias_gen(alias_muB__unit_rom,_IDNT,0,&ref_muB__unit_rom);
10745   const gen & muB__unit_rom_IDNT_e = * (gen *) & alias_muB__unit_rom;
10746 
10747   static const alias_identificateur alias_identificateur_muN__unit_rom={0,0,"_muN_",0,0};
10748   const identificateur & _IDNT_id_muN__unit_rom=* (const identificateur *) &alias_identificateur_muN__unit_rom;
10749   const alias_ref_identificateur ref_muN__unit_rom={-1,0,0,"_muN_",0,0};
10750   const define_alias_gen(alias_muN__unit_rom,_IDNT,0,&ref_muN__unit_rom);
10751   const gen & muN__unit_rom_IDNT_e = * (gen *) & alias_muN__unit_rom;
10752 
10753   static const alias_identificateur alias_identificateur_nmi_unit_rom={0,0,"_nmi",0,0};
10754   const identificateur & _IDNT_id_nmi_unit_rom=* (const identificateur *) &alias_identificateur_nmi_unit_rom;
10755   const alias_ref_identificateur ref_nmi_unit_rom={-1,0,0,"_nmi",0,0};
10756   const define_alias_gen(alias_nmi_unit_rom,_IDNT,0,&ref_nmi_unit_rom);
10757   const gen & nmi_unit_rom_IDNT_e = * (gen *) & alias_nmi_unit_rom;
10758 
10759   static const alias_identificateur alias_identificateur_oz_unit_rom={0,0,"_oz",0,0};
10760   const identificateur & _IDNT_id_oz_unit_rom=* (const identificateur *) &alias_identificateur_oz_unit_rom;
10761   const alias_ref_identificateur ref_oz_unit_rom={-1,0,0,"_oz",0,0};
10762   const define_alias_gen(alias_oz_unit_rom,_IDNT,0,&ref_oz_unit_rom);
10763   const gen & oz_unit_rom_IDNT_e = * (gen *) & alias_oz_unit_rom;
10764 
10765   static const alias_identificateur alias_identificateur_ozUK_unit_rom={0,0,"_ozUK",0,0};
10766   const identificateur & _IDNT_id_ozUK_unit_rom=* (const identificateur *) &alias_identificateur_ozUK_unit_rom;
10767   const alias_ref_identificateur ref_ozUK_unit_rom={-1,0,0,"_ozUK",0,0};
10768   const define_alias_gen(alias_ozUK_unit_rom,_IDNT,0,&ref_ozUK_unit_rom);
10769   const gen & ozUK_unit_rom_IDNT_e = * (gen *) & alias_ozUK_unit_rom;
10770 
10771   static const alias_identificateur alias_identificateur_ozfl_unit_rom={0,0,"_ozfl",0,0};
10772   const identificateur & _IDNT_id_ozfl_unit_rom=* (const identificateur *) &alias_identificateur_ozfl_unit_rom;
10773   const alias_ref_identificateur ref_ozfl_unit_rom={-1,0,0,"_ozfl",0,0};
10774   const define_alias_gen(alias_ozfl_unit_rom,_IDNT,0,&ref_ozfl_unit_rom);
10775   const gen & ozfl_unit_rom_IDNT_e = * (gen *) & alias_ozfl_unit_rom;
10776 
10777   static const alias_identificateur alias_identificateur_ozt_unit_rom={0,0,"_ozt",0,0};
10778   const identificateur & _IDNT_id_ozt_unit_rom=* (const identificateur *) &alias_identificateur_ozt_unit_rom;
10779   const alias_ref_identificateur ref_ozt_unit_rom={-1,0,0,"_ozt",0,0};
10780   const define_alias_gen(alias_ozt_unit_rom,_IDNT,0,&ref_ozt_unit_rom);
10781   const gen & ozt_unit_rom_IDNT_e = * (gen *) & alias_ozt_unit_rom;
10782 
10783   static const alias_identificateur alias_identificateur_pc_unit_rom={0,0,"_pc",0,0};
10784   const identificateur & _IDNT_id_pc_unit_rom=* (const identificateur *) &alias_identificateur_pc_unit_rom;
10785   const alias_ref_identificateur ref_pc_unit_rom={-1,0,0,"_pc",0,0};
10786   const define_alias_gen(alias_pc_unit_rom,_IDNT,0,&ref_pc_unit_rom);
10787   const gen & pc_unit_rom_IDNT_e = * (gen *) & alias_pc_unit_rom;
10788 
10789   static const alias_identificateur alias_identificateur_pdl_unit_rom={0,0,"_pdl",0,0};
10790   const identificateur & _IDNT_id_pdl_unit_rom=* (const identificateur *) &alias_identificateur_pdl_unit_rom;
10791   const alias_ref_identificateur ref_pdl_unit_rom={-1,0,0,"_pdl",0,0};
10792   const define_alias_gen(alias_pdl_unit_rom,_IDNT,0,&ref_pdl_unit_rom);
10793   const gen & pdl_unit_rom_IDNT_e = * (gen *) & alias_pdl_unit_rom;
10794 
10795   static const alias_identificateur alias_identificateur_phi__unit_rom={0,0,"_phi_",0,0};
10796   const identificateur & _IDNT_id_phi__unit_rom=* (const identificateur *) &alias_identificateur_phi__unit_rom;
10797   const alias_ref_identificateur ref_phi__unit_rom={-1,0,0,"_phi_",0,0};
10798   const define_alias_gen(alias_phi__unit_rom,_IDNT,0,&ref_phi__unit_rom);
10799   const gen & phi__unit_rom_IDNT_e = * (gen *) & alias_phi__unit_rom;
10800 
10801   static const alias_identificateur alias_identificateur_pk_unit_rom={0,0,"_pk",0,0};
10802   const identificateur & _IDNT_id_pk_unit_rom=* (const identificateur *) &alias_identificateur_pk_unit_rom;
10803   const alias_ref_identificateur ref_pk_unit_rom={-1,0,0,"_pk",0,0};
10804   const define_alias_gen(alias_pk_unit_rom,_IDNT,0,&ref_pk_unit_rom);
10805   const gen & pk_unit_rom_IDNT_e = * (gen *) & alias_pk_unit_rom;
10806 
10807   static const alias_identificateur alias_identificateur_psi_unit_rom={0,0,"_psi",0,0};
10808   const identificateur & _IDNT_id_psi_unit_rom=* (const identificateur *) &alias_identificateur_psi_unit_rom;
10809   const alias_ref_identificateur ref_psi_unit_rom={-1,0,0,"_psi",0,0};
10810   const define_alias_gen(alias_psi_unit_rom,_IDNT,0,&ref_psi_unit_rom);
10811   const gen & psi_unit_rom_IDNT_e = * (gen *) & alias_psi_unit_rom;
10812 
10813   static const alias_identificateur alias_identificateur_pt_unit_rom={0,0,"_pt",0,0};
10814   const identificateur & _IDNT_id_pt_unit_rom=* (const identificateur *) &alias_identificateur_pt_unit_rom;
10815   const alias_ref_identificateur ref_pt_unit_rom={-1,0,0,"_pt",0,0};
10816   const define_alias_gen(alias_pt_unit_rom,_IDNT,0,&ref_pt_unit_rom);
10817   const gen & pt_unit_rom_IDNT_e = * (gen *) & alias_pt_unit_rom;
10818 
10819   static const alias_identificateur alias_identificateur_ptUK_unit_rom={0,0,"_ptUK",0,0};
10820   const identificateur & _IDNT_id_ptUK_unit_rom=* (const identificateur *) &alias_identificateur_ptUK_unit_rom;
10821   const alias_ref_identificateur ref_ptUK_unit_rom={-1,0,0,"_ptUK",0,0};
10822   const define_alias_gen(alias_ptUK_unit_rom,_IDNT,0,&ref_ptUK_unit_rom);
10823   const gen & ptUK_unit_rom_IDNT_e = * (gen *) & alias_ptUK_unit_rom;
10824 
10825   static const alias_identificateur alias_identificateur_qe_unit_rom={0,0,"_qe",0,0};
10826   const identificateur & _IDNT_id_qe_unit_rom=* (const identificateur *) &alias_identificateur_qe_unit_rom;
10827   const alias_ref_identificateur ref_qe_unit_rom={-1,0,0,"_qe",0,0};
10828   const define_alias_gen(alias_qe_unit_rom,_IDNT,0,&ref_qe_unit_rom);
10829   const gen & qe_unit_rom_IDNT_e = * (gen *) & alias_qe_unit_rom;
10830 
10831   static const alias_identificateur alias_identificateur_qepsilon0__unit_rom={0,0,"_qepsilon0_",0,0};
10832   const identificateur & _IDNT_id_qepsilon0__unit_rom=* (const identificateur *) &alias_identificateur_qepsilon0__unit_rom;
10833   const alias_ref_identificateur ref_qepsilon0__unit_rom={-1,0,0,"_qepsilon0_",0,0};
10834   const define_alias_gen(alias_qepsilon0__unit_rom,_IDNT,0,&ref_qepsilon0__unit_rom);
10835   const gen & qepsilon0__unit_rom_IDNT_e = * (gen *) & alias_qepsilon0__unit_rom;
10836 
10837   static const alias_identificateur alias_identificateur_qme__unit_rom={0,0,"_qme_",0,0};
10838   const identificateur & _IDNT_id_qme__unit_rom=* (const identificateur *) &alias_identificateur_qme__unit_rom;
10839   const alias_ref_identificateur ref_qme__unit_rom={-1,0,0,"_qme_",0,0};
10840   const define_alias_gen(alias_qme__unit_rom,_IDNT,0,&ref_qme__unit_rom);
10841   const gen & qme__unit_rom_IDNT_e = * (gen *) & alias_qme__unit_rom;
10842 
10843   static const alias_identificateur alias_identificateur_qt_unit_rom={0,0,"_qt",0,0};
10844   const identificateur & _IDNT_id_qt_unit_rom=* (const identificateur *) &alias_identificateur_qt_unit_rom;
10845   const alias_ref_identificateur ref_qt_unit_rom={-1,0,0,"_qt",0,0};
10846   const define_alias_gen(alias_qt_unit_rom,_IDNT,0,&ref_qt_unit_rom);
10847   const gen & qt_unit_rom_IDNT_e = * (gen *) & alias_qt_unit_rom;
10848 
10849   static const alias_identificateur alias_identificateur_rad_unit_rom={0,0,"_rad",0,0};
10850   const identificateur & _IDNT_id_rad_unit_rom=* (const identificateur *) &alias_identificateur_rad_unit_rom;
10851   const alias_ref_identificateur ref_rad_unit_rom={-1,0,0,"_rad",0,0};
10852   const define_alias_gen(alias_rad_unit_rom,_IDNT,0,&ref_rad_unit_rom);
10853   const gen & rad_unit_rom_IDNT_e = * (gen *) & alias_rad_unit_rom;
10854 
10855   static const alias_identificateur alias_identificateur_rd_unit_rom={0,0,"_rd",0,0};
10856   const identificateur & _IDNT_id_rd_unit_rom=* (const identificateur *) &alias_identificateur_rd_unit_rom;
10857   const alias_ref_identificateur ref_rd_unit_rom={-1,0,0,"_rd",0,0};
10858   const define_alias_gen(alias_rd_unit_rom,_IDNT,0,&ref_rd_unit_rom);
10859   const gen & rd_unit_rom_IDNT_e = * (gen *) & alias_rd_unit_rom;
10860 
10861   static const alias_identificateur alias_identificateur_rem_unit_rom={0,0,"_rem",0,0};
10862   const identificateur & _IDNT_id_rem_unit_rom=* (const identificateur *) &alias_identificateur_rem_unit_rom;
10863   const alias_ref_identificateur ref_rem_unit_rom={-1,0,0,"_rem",0,0};
10864   const define_alias_gen(alias_rem_unit_rom,_IDNT,0,&ref_rem_unit_rom);
10865   const gen & rem_unit_rom_IDNT_e = * (gen *) & alias_rem_unit_rom;
10866 
10867   static const alias_identificateur alias_identificateur_rev_unit_rom={0,0,"_rev",0,0};
10868   const identificateur & _IDNT_id_rev_unit_rom=* (const identificateur *) &alias_identificateur_rev_unit_rom;
10869   const alias_ref_identificateur ref_rev_unit_rom={-1,0,0,"_rev",0,0};
10870   const define_alias_gen(alias_rev_unit_rom,_IDNT,0,&ref_rev_unit_rom);
10871   const gen & rev_unit_rom_IDNT_e = * (gen *) & alias_rev_unit_rom;
10872 
10873   static const alias_identificateur alias_identificateur_rod_unit_rom={0,0,"_rod",0,0};
10874   const identificateur & _IDNT_id_rod_unit_rom=* (const identificateur *) &alias_identificateur_rod_unit_rom;
10875   const alias_ref_identificateur ref_rod_unit_rom={-1,0,0,"_rod",0,0};
10876   const define_alias_gen(alias_rod_unit_rom,_IDNT,0,&ref_rod_unit_rom);
10877   const gen & rod_unit_rom_IDNT_e = * (gen *) & alias_rod_unit_rom;
10878 
10879   static const alias_identificateur alias_identificateur_rpm_unit_rom={0,0,"_rpm",0,0};
10880   const identificateur & _IDNT_id_rpm_unit_rom=* (const identificateur *) &alias_identificateur_rpm_unit_rom;
10881   const alias_ref_identificateur ref_rpm_unit_rom={-1,0,0,"_rpm",0,0};
10882   const define_alias_gen(alias_rpm_unit_rom,_IDNT,0,&ref_rpm_unit_rom);
10883   const gen & rpm_unit_rom_IDNT_e = * (gen *) & alias_rpm_unit_rom;
10884 
10885   static const alias_identificateur alias_identificateur_s_unit_rom={0,0,"_s",0,0};
10886   const identificateur & _IDNT_id_s_unit_rom=* (const identificateur *) &alias_identificateur_s_unit_rom;
10887   const alias_ref_identificateur ref_s_unit_rom={-1,0,0,"_s",0,0};
10888   const define_alias_gen(alias_s_unit_rom,_IDNT,0,&ref_s_unit_rom);
10889   const gen & s_unit_rom_IDNT_e = * (gen *) & alias_s_unit_rom;
10890 
10891   static const alias_identificateur alias_identificateur_sb_unit_rom={0,0,"_sb",0,0};
10892   const identificateur & _IDNT_id_sb_unit_rom=* (const identificateur *) &alias_identificateur_sb_unit_rom;
10893   const alias_ref_identificateur ref_sb_unit_rom={-1,0,0,"_sb",0,0};
10894   const define_alias_gen(alias_sb_unit_rom,_IDNT,0,&ref_sb_unit_rom);
10895   const gen & sb_unit_rom_IDNT_e = * (gen *) & alias_sb_unit_rom;
10896 
10897   static const alias_identificateur alias_identificateur_sd_unit_rom={0,0,"_sd",0,0};
10898   const identificateur & _IDNT_id_sd_unit_rom=* (const identificateur *) &alias_identificateur_sd_unit_rom;
10899   const alias_ref_identificateur ref_sd_unit_rom={-1,0,0,"_sd",0,0};
10900   const define_alias_gen(alias_sd_unit_rom,_IDNT,0,&ref_sd_unit_rom);
10901   const gen & sd_unit_rom_IDNT_e = * (gen *) & alias_sd_unit_rom;
10902 
10903   static const alias_identificateur alias_identificateur_sigma_unit_rom={0,0,"_sigma",0,0};
10904   const identificateur & _IDNT_id_sigma_unit_rom=* (const identificateur *) &alias_identificateur_sigma_unit_rom;
10905   const alias_ref_identificateur ref_sigma_unit_rom={-1,0,0,"_sigma",0,0};
10906   const define_alias_gen(alias_sigma_unit_rom,_IDNT,0,&ref_sigma_unit_rom);
10907   const gen & sigma_unit_rom_IDNT_e = * (gen *) & alias_sigma_unit_rom;
10908 
10909   static const alias_identificateur alias_identificateur_slug_unit_rom={0,0,"_slug",0,0};
10910   const identificateur & _IDNT_id_slug_unit_rom=* (const identificateur *) &alias_identificateur_slug_unit_rom;
10911   const alias_ref_identificateur ref_slug_unit_rom={-1,0,0,"_slug",0,0};
10912   const define_alias_gen(alias_slug_unit_rom,_IDNT,0,&ref_slug_unit_rom);
10913   const gen & slug_unit_rom_IDNT_e = * (gen *) & alias_slug_unit_rom;
10914 
10915   static const alias_identificateur alias_identificateur_st_unit_rom={0,0,"_st",0,0};
10916   const identificateur & _IDNT_id_st_unit_rom=* (const identificateur *) &alias_identificateur_st_unit_rom;
10917   const alias_ref_identificateur ref_st_unit_rom={-1,0,0,"_st",0,0};
10918   const define_alias_gen(alias_st_unit_rom,_IDNT,0,&ref_st_unit_rom);
10919   const gen & st_unit_rom_IDNT_e = * (gen *) & alias_st_unit_rom;
10920 
10921   static const alias_identificateur alias_identificateur_syr__unit_rom={0,0,"_syr_",0,0};
10922   const identificateur & _IDNT_id_syr__unit_rom=* (const identificateur *) &alias_identificateur_syr__unit_rom;
10923   const alias_ref_identificateur ref_syr__unit_rom={-1,0,0,"_syr_",0,0};
10924   const define_alias_gen(alias_syr__unit_rom,_IDNT,0,&ref_syr__unit_rom);
10925   const gen & syr__unit_rom_IDNT_e = * (gen *) & alias_syr__unit_rom;
10926 
10927   static const alias_identificateur alias_identificateur_t_unit_rom={0,0,"_t",0,0};
10928   const identificateur & _IDNT_id_t_unit_rom=* (const identificateur *) &alias_identificateur_t_unit_rom;
10929   const alias_ref_identificateur ref_t_unit_rom={-1,0,0,"_t",0,0};
10930   const define_alias_gen(alias_t_unit_rom,_IDNT,0,&ref_t_unit_rom);
10931   const gen & t_unit_rom_IDNT_e = * (gen *) & alias_t_unit_rom;
10932 
10933   static const alias_identificateur alias_identificateur_tbsp_unit_rom={0,0,"_tbsp",0,0};
10934   const identificateur & _IDNT_id_tbsp_unit_rom=* (const identificateur *) &alias_identificateur_tbsp_unit_rom;
10935   const alias_ref_identificateur ref_tbsp_unit_rom={-1,0,0,"_tbsp",0,0};
10936   const define_alias_gen(alias_tbsp_unit_rom,_IDNT,0,&ref_tbsp_unit_rom);
10937   const gen & tbsp_unit_rom_IDNT_e = * (gen *) & alias_tbsp_unit_rom;
10938 
10939   static const alias_identificateur alias_identificateur_tec_unit_rom={0,0,"_tec",0,0};
10940   const identificateur & _IDNT_id_tec_unit_rom=* (const identificateur *) &alias_identificateur_tec_unit_rom;
10941   const alias_ref_identificateur ref_tec_unit_rom={-1,0,0,"_tec",0,0};
10942   const define_alias_gen(alias_tec_unit_rom,_IDNT,0,&ref_tec_unit_rom);
10943   const gen & tec_unit_rom_IDNT_e = * (gen *) & alias_tec_unit_rom;
10944 
10945   static const alias_identificateur alias_identificateur_tep_unit_rom={0,0,"_tep",0,0};
10946   const identificateur & _IDNT_id_tep_unit_rom=* (const identificateur *) &alias_identificateur_tep_unit_rom;
10947   const alias_ref_identificateur ref_tep_unit_rom={-1,0,0,"_tep",0,0};
10948   const define_alias_gen(alias_tep_unit_rom,_IDNT,0,&ref_tep_unit_rom);
10949   const gen & tep_unit_rom_IDNT_e = * (gen *) & alias_tep_unit_rom;
10950 
10951   static const alias_identificateur alias_identificateur_tepC_unit_rom={0,0,"_tepC",0,0};
10952   const identificateur & _IDNT_id_tepC_unit_rom=* (const identificateur *) &alias_identificateur_tepC_unit_rom;
10953   const alias_ref_identificateur ref_tepC_unit_rom={-1,0,0,"_tepC",0,0};
10954   const define_alias_gen(alias_tepC_unit_rom,_IDNT,0,&ref_tepC_unit_rom);
10955   const gen & tepC_unit_rom_IDNT_e = * (gen *) & alias_tepC_unit_rom;
10956 
10957   static const alias_identificateur alias_identificateur_tepcC_unit_rom={0,0,"_tepcC",0,0};
10958   const identificateur & _IDNT_id_tepcC_unit_rom=* (const identificateur *) &alias_identificateur_tepcC_unit_rom;
10959   const alias_ref_identificateur ref_tepcC_unit_rom={-1,0,0,"_tepcC",0,0};
10960   const define_alias_gen(alias_tepcC_unit_rom,_IDNT,0,&ref_tepcC_unit_rom);
10961   const gen & tepcC_unit_rom_IDNT_e = * (gen *) & alias_tepcC_unit_rom;
10962 
10963   static const alias_identificateur alias_identificateur_tepgC_unit_rom={0,0,"_tepgC",0,0};
10964   const identificateur & _IDNT_id_tepgC_unit_rom=* (const identificateur *) &alias_identificateur_tepgC_unit_rom;
10965   const alias_ref_identificateur ref_tepgC_unit_rom={-1,0,0,"_tepgC",0,0};
10966   const define_alias_gen(alias_tepgC_unit_rom,_IDNT,0,&ref_tepgC_unit_rom);
10967   const gen & tepgC_unit_rom_IDNT_e = * (gen *) & alias_tepgC_unit_rom;
10968 
10969   static const alias_identificateur alias_identificateur_tex_unit_rom={0,0,"_tex",0,0};
10970   const identificateur & _IDNT_id_tex_unit_rom=* (const identificateur *) &alias_identificateur_tex_unit_rom;
10971   const alias_ref_identificateur ref_tex_unit_rom={-1,0,0,"_tex",0,0};
10972   const define_alias_gen(alias_tex_unit_rom,_IDNT,0,&ref_tex_unit_rom);
10973   const gen & tex_unit_rom_IDNT_e = * (gen *) & alias_tex_unit_rom;
10974 
10975   static const alias_identificateur alias_identificateur_therm_unit_rom={0,0,"_therm",0,0};
10976   const identificateur & _IDNT_id_therm_unit_rom=* (const identificateur *) &alias_identificateur_therm_unit_rom;
10977   const alias_ref_identificateur ref_therm_unit_rom={-1,0,0,"_therm",0,0};
10978   const define_alias_gen(alias_therm_unit_rom,_IDNT,0,&ref_therm_unit_rom);
10979   const gen & therm_unit_rom_IDNT_e = * (gen *) & alias_therm_unit_rom;
10980 
10981   static const alias_identificateur alias_identificateur_toe_unit_rom={0,0,"_toe",0,0};
10982   const identificateur & _IDNT_id_toe_unit_rom=* (const identificateur *) &alias_identificateur_toe_unit_rom;
10983   const alias_ref_identificateur ref_toe_unit_rom={-1,0,0,"_toe",0,0};
10984   const define_alias_gen(alias_toe_unit_rom,_IDNT,0,&ref_toe_unit_rom);
10985   const gen & toe_unit_rom_IDNT_e = * (gen *) & alias_toe_unit_rom;
10986 
10987   static const alias_identificateur alias_identificateur_ton_unit_rom={0,0,"_ton",0,0};
10988   const identificateur & _IDNT_id_ton_unit_rom=* (const identificateur *) &alias_identificateur_ton_unit_rom;
10989   const alias_ref_identificateur ref_ton_unit_rom={-1,0,0,"_ton",0,0};
10990   const define_alias_gen(alias_ton_unit_rom,_IDNT,0,&ref_ton_unit_rom);
10991   const gen & ton_unit_rom_IDNT_e = * (gen *) & alias_ton_unit_rom;
10992 
10993   static const alias_identificateur alias_identificateur_tonUK_unit_rom={0,0,"_tonUK",0,0};
10994   const identificateur & _IDNT_id_tonUK_unit_rom=* (const identificateur *) &alias_identificateur_tonUK_unit_rom;
10995   const alias_ref_identificateur ref_tonUK_unit_rom={-1,0,0,"_tonUK",0,0};
10996   const define_alias_gen(alias_tonUK_unit_rom,_IDNT,0,&ref_tonUK_unit_rom);
10997   const gen & tonUK_unit_rom_IDNT_e = * (gen *) & alias_tonUK_unit_rom;
10998 
10999   static const alias_identificateur alias_identificateur_tr_unit_rom={0,0,"_tr",0,0};
11000   const identificateur & _IDNT_id_tr_unit_rom=* (const identificateur *) &alias_identificateur_tr_unit_rom;
11001   const alias_ref_identificateur ref_tr_unit_rom={-1,0,0,"_tr",0,0};
11002   const define_alias_gen(alias_tr_unit_rom,_IDNT,0,&ref_tr_unit_rom);
11003   const gen & tr_unit_rom_IDNT_e = * (gen *) & alias_tr_unit_rom;
11004 
11005   static const alias_identificateur alias_identificateur_tsp_unit_rom={0,0,"_tsp",0,0};
11006   const identificateur & _IDNT_id_tsp_unit_rom=* (const identificateur *) &alias_identificateur_tsp_unit_rom;
11007   const alias_ref_identificateur ref_tsp_unit_rom={-1,0,0,"_tsp",0,0};
11008   const define_alias_gen(alias_tsp_unit_rom,_IDNT,0,&ref_tsp_unit_rom);
11009   const gen & tsp_unit_rom_IDNT_e = * (gen *) & alias_tsp_unit_rom;
11010 
11011   static const alias_identificateur alias_identificateur_u_unit_rom={0,0,"_u",0,0};
11012   const identificateur & _IDNT_id_u_unit_rom=* (const identificateur *) &alias_identificateur_u_unit_rom;
11013   const alias_ref_identificateur ref_u_unit_rom={-1,0,0,"_u",0,0};
11014   const define_alias_gen(alias_u_unit_rom,_IDNT,0,&ref_u_unit_rom);
11015   const gen & u_unit_rom_IDNT_e = * (gen *) & alias_u_unit_rom;
11016 
11017   static const alias_identificateur alias_identificateur_E_unit_rom={0,0,"_E",0,0};
11018   const identificateur & _IDNT_id_E_unit_rom=* (const identificateur *) &alias_identificateur_E_unit_rom;
11019   const alias_ref_identificateur ref_E_unit_rom={-1,0,0,"_E",0,0};
11020   const define_alias_gen(alias_E_unit_rom,_IDNT,0,&ref_E_unit_rom);
11021   const gen & E_unit_rom_IDNT_e = * (gen *) & alias_E_unit_rom;
11022 
11023   static const alias_identificateur alias_identificateur_Curie_unit_rom={0,0,"_Curie",0,0};
11024   const identificateur & _IDNT_id_Curie_unit_rom=* (const identificateur *) &alias_identificateur_Curie_unit_rom;
11025   const alias_ref_identificateur ref_Curie_unit_rom={-1,0,0,"_Curie",0,0};
11026   const define_alias_gen(alias_Curie_unit_rom,_IDNT,0,&ref_Curie_unit_rom);
11027   const gen & Curie_unit_rom_IDNT_e = * (gen *) & alias_Curie_unit_rom;
11028 
11029   static const alias_identificateur alias_identificateur_C_unit_rom={0,0,"_C",0,0};
11030   const identificateur & _IDNT_id_C_unit_rom=* (const identificateur *) &alias_identificateur_C_unit_rom;
11031   const alias_ref_identificateur ref_C_unit_rom={-1,0,0,"_C",0,0};
11032   const define_alias_gen(alias_C_unit_rom,_IDNT,0,&ref_C_unit_rom);
11033   const gen & C_unit_rom_IDNT_e = * (gen *) & alias_C_unit_rom;
11034 
11035   static const alias_identificateur alias_identificateur_kg_unit_rom={0,0,"_kg",0,0};
11036   const identificateur & _IDNT_id_kg_unit_rom=* (const identificateur *) &alias_identificateur_kg_unit_rom;
11037   const alias_ref_identificateur ref_kg_unit_rom={-1,0,0,"_kg",0,0};
11038   const define_alias_gen(alias_kg_unit_rom,_IDNT,0,&ref_kg_unit_rom);
11039   const gen & kg_unit_rom_IDNT_e = * (gen *) & alias_kg_unit_rom;
11040   // const gen & _kg_unit = * (gen *) & alias_kg_unit_rom;
11041 
11042 
11043 #else
11044   identificateur m_unit_rom_IDNT("_m");
11045   gen m_unit_rom_IDNT_e(m_unit_rom_IDNT);
11046   identificateur A_unit_rom_IDNT("_A");
11047   gen A_unit_rom_IDNT_e(A_unit_rom_IDNT);
11048   identificateur Bq_unit_rom_IDNT("_Bq");
11049   gen Bq_unit_rom_IDNT_e(Bq_unit_rom_IDNT);
11050   identificateur yd_unit_rom_IDNT("_yd");
11051   gen yd_unit_rom_IDNT_e(yd_unit_rom_IDNT);
11052   identificateur yr_unit_rom_IDNT("_yr");
11053   gen yr_unit_rom_IDNT_e(yr_unit_rom_IDNT);
11054   identificateur Btu_unit_rom_IDNT("_Btu");
11055   gen Btu_unit_rom_IDNT_e(Btu_unit_rom_IDNT);
11056   identificateur R__unit_rom_IDNT("_R_");
11057   gen R__unit_rom_IDNT_e(R__unit_rom_IDNT);
11058   identificateur epsilon0__unit_rom_IDNT("_epsilon0_");
11059   gen epsilon0__unit_rom_IDNT_e(epsilon0__unit_rom_IDNT);
11060   identificateur a0__unit_rom_IDNT("_a0_");
11061   gen a0__unit_rom_IDNT_e(a0__unit_rom_IDNT);
11062   identificateur RSun__unit_rom_IDNT("_RSun_");
11063   gen RSun__unit_rom_IDNT_e(RSun__unit_rom_IDNT);
11064   identificateur REarth__unit_rom_IDNT("_REarth_");
11065   gen REarth__unit_rom_IDNT_e(REarth__unit_rom_IDNT);
11066   identificateur Fdy_unit_rom_IDNT("_Fdy");
11067   gen Fdy_unit_rom_IDNT_e(Fdy_unit_rom_IDNT);
11068   identificateur F_unit_rom_IDNT("_F");
11069   gen F_unit_rom_IDNT_e(F_unit_rom_IDNT);
11070   identificateur FF_unit_rom_IDNT("_FF");
11071   gen FF_unit_rom_IDNT_e(FF_unit_rom_IDNT);
11072   identificateur Faraday__unit_rom_IDNT("_Faraday_");
11073   gen Faraday__unit_rom_IDNT_e(Faraday__unit_rom_IDNT);
11074   identificateur G__unit_rom_IDNT("_G_");
11075   gen G__unit_rom_IDNT_e(G__unit_rom_IDNT);
11076   identificateur Gal_unit_rom_IDNT("_Gal");
11077   gen Gal_unit_rom_IDNT_e(Gal_unit_rom_IDNT);
11078   identificateur Gy_unit_rom_IDNT("_Gy");
11079   gen Gy_unit_rom_IDNT_e(Gy_unit_rom_IDNT);
11080   identificateur H_unit_rom_IDNT("_H");
11081   gen H_unit_rom_IDNT_e(H_unit_rom_IDNT);
11082   identificateur HFCC_unit_rom_IDNT("_HFCC");
11083   gen HFCC_unit_rom_IDNT_e(HFCC_unit_rom_IDNT);
11084   identificateur Hz_unit_rom_IDNT("_Hz");
11085   gen Hz_unit_rom_IDNT_e(Hz_unit_rom_IDNT);
11086   identificateur IO__unit_rom_IDNT("_IO_");
11087   gen IO__unit_rom_IDNT_e(IO__unit_rom_IDNT);
11088   identificateur J_unit_rom_IDNT("_J");
11089   gen J_unit_rom_IDNT_e(J_unit_rom_IDNT);
11090   identificateur K_unit_rom_IDNT("_K");
11091   gen K_unit_rom_IDNT_e(K_unit_rom_IDNT);
11092   identificateur L_unit_rom_IDNT("_L");
11093   gen L_unit_rom_IDNT_e(L_unit_rom_IDNT);
11094   identificateur N_unit_rom_IDNT("_N");
11095   gen N_unit_rom_IDNT_e(N_unit_rom_IDNT);
11096   identificateur NA__unit_rom_IDNT("_NA_");
11097   gen NA__unit_rom_IDNT_e(NA__unit_rom_IDNT);
11098   identificateur Ohm_unit_rom_IDNT("_Ohm");
11099   gen Ohm_unit_rom_IDNT_e(Ohm_unit_rom_IDNT);
11100   identificateur P_unit_rom_IDNT("_P");
11101   gen P_unit_rom_IDNT_e(P_unit_rom_IDNT);
11102   identificateur PSun__unit_rom_IDNT("_PSun_");
11103   gen PSun__unit_rom_IDNT_e(PSun__unit_rom_IDNT);
11104   identificateur Pa_unit_rom_IDNT("_Pa");
11105   gen Pa_unit_rom_IDNT_e(Pa_unit_rom_IDNT);
11106   identificateur R_unit_rom_IDNT("_R");
11107   gen R_unit_rom_IDNT_e(R_unit_rom_IDNT);
11108   identificateur Rankine_unit_rom_IDNT("_Rankine");
11109   gen Rankine_unit_rom_IDNT_e(Rankine_unit_rom_IDNT);
11110   identificateur Rinfinity__unit_rom_IDNT("_Rinfinity_");
11111   gen Rinfinity__unit_rom_IDNT_e(Rinfinity__unit_rom_IDNT);
11112   identificateur S_unit_rom_IDNT("_S");
11113   gen S_unit_rom_IDNT_e(S_unit_rom_IDNT);
11114   identificateur St_unit_rom_IDNT("_St");
11115   gen St_unit_rom_IDNT_e(St_unit_rom_IDNT);
11116   identificateur StdP__unit_rom_IDNT("_StdP_");
11117   gen StdP__unit_rom_IDNT_e(StdP__unit_rom_IDNT);
11118   identificateur StdT__unit_rom_IDNT("_StdT_");
11119   gen StdT__unit_rom_IDNT_e(StdT__unit_rom_IDNT);
11120   identificateur Sv_unit_rom_IDNT("_Sv");
11121   gen Sv_unit_rom_IDNT_e(Sv_unit_rom_IDNT);
11122   identificateur T_unit_rom_IDNT("_T");
11123   gen T_unit_rom_IDNT_e(T_unit_rom_IDNT);
11124   identificateur Torr_unit_rom_IDNT("_Torr");
11125   gen Torr_unit_rom_IDNT_e(Torr_unit_rom_IDNT);
11126   identificateur V_unit_rom_IDNT("_V");
11127   gen V_unit_rom_IDNT_e(V_unit_rom_IDNT);
11128   identificateur Vm__unit_rom_IDNT("_Vm_");
11129   gen Vm__unit_rom_IDNT_e(Vm__unit_rom_IDNT);
11130   identificateur W_unit_rom_IDNT("_W");
11131   gen W_unit_rom_IDNT_e(W_unit_rom_IDNT);
11132   identificateur Wb_unit_rom_IDNT("_Wb");
11133   gen Wb_unit_rom_IDNT_e(Wb_unit_rom_IDNT);
11134   identificateur Wh_unit_rom_IDNT("_Wh");
11135   gen Wh_unit_rom_IDNT_e(Wh_unit_rom_IDNT);
11136   identificateur a_unit_rom_IDNT("_a");
11137   gen a_unit_rom_IDNT_e(a_unit_rom_IDNT);
11138   identificateur acre_unit_rom_IDNT("_acre");
11139   gen acre_unit_rom_IDNT_e(acre_unit_rom_IDNT);
11140   identificateur alpha__unit_rom_IDNT("_alpha_");
11141   gen alpha__unit_rom_IDNT_e(alpha__unit_rom_IDNT);
11142   identificateur arcmin_unit_rom_IDNT("_arcmin");
11143   gen arcmin_unit_rom_IDNT_e(arcmin_unit_rom_IDNT);
11144   identificateur arcs_unit_rom_IDNT("_arcs");
11145   gen arcs_unit_rom_IDNT_e(arcs_unit_rom_IDNT);
11146   identificateur atm_unit_rom_IDNT("_atm");
11147   gen atm_unit_rom_IDNT_e(atm_unit_rom_IDNT);
11148   identificateur au_unit_rom_IDNT("_au");
11149   gen au_unit_rom_IDNT_e(au_unit_rom_IDNT);
11150   identificateur bar_unit_rom_IDNT("_bar");
11151   gen bar_unit_rom_IDNT_e(bar_unit_rom_IDNT);
11152   identificateur b_unit_rom_IDNT("_b");
11153   gen b_unit_rom_IDNT_e(b_unit_rom_IDNT);
11154   identificateur bbl_unit_rom_IDNT("_bbl");
11155   gen bbl_unit_rom_IDNT_e(bbl_unit_rom_IDNT);
11156   identificateur bblep_unit_rom_IDNT("_bblep");
11157   gen bblep_unit_rom_IDNT_e(bblep_unit_rom_IDNT);
11158   identificateur boe_unit_rom_IDNT("_boe");
11159   gen boe_unit_rom_IDNT_e(boe_unit_rom_IDNT);
11160   identificateur bu_unit_rom_IDNT("_bu");
11161   gen bu_unit_rom_IDNT_e(bu_unit_rom_IDNT);
11162   identificateur buUS_unit_rom_IDNT("_buUS");
11163   gen buUS_unit_rom_IDNT_e(buUS_unit_rom_IDNT);
11164   identificateur c3__unit_rom_IDNT("_c3_");
11165   gen c3__unit_rom_IDNT_e(c3__unit_rom_IDNT);
11166   identificateur c__unit_rom_IDNT("_c_");
11167   gen c__unit_rom_IDNT_e(c__unit_rom_IDNT);
11168   identificateur cal_unit_rom_IDNT("_cal");
11169   gen cal_unit_rom_IDNT_e(cal_unit_rom_IDNT);
11170   identificateur cd_unit_rom_IDNT("_cd");
11171   gen cd_unit_rom_IDNT_e(cd_unit_rom_IDNT);
11172   identificateur cf_unit_rom_IDNT("_cf");
11173   gen cf_unit_rom_IDNT_e(cf_unit_rom_IDNT);
11174   identificateur chain_unit_rom_IDNT("_chain");
11175   gen chain_unit_rom_IDNT_e(chain_unit_rom_IDNT);
11176   identificateur ct_unit_rom_IDNT("_ct");
11177   gen ct_unit_rom_IDNT_e(ct_unit_rom_IDNT);
11178   identificateur cu_unit_rom_IDNT("_cu");
11179   gen cu_unit_rom_IDNT_e(cu_unit_rom_IDNT);
11180   identificateur d_unit_rom_IDNT("_d");
11181   gen d_unit_rom_IDNT_e(d_unit_rom_IDNT);
11182   identificateur dB_unit_rom_IDNT("_dB");
11183   gen dB_unit_rom_IDNT_e(dB_unit_rom_IDNT);
11184   identificateur deg_unit_rom_IDNT("_deg");
11185   gen deg_unit_rom_IDNT_e(deg_unit_rom_IDNT);
11186   identificateur dyn_unit_rom_IDNT("_dyn");
11187   gen dyn_unit_rom_IDNT_e(dyn_unit_rom_IDNT);
11188   identificateur eV_unit_rom_IDNT("_eV");
11189   gen eV_unit_rom_IDNT_e(eV_unit_rom_IDNT);
11190   identificateur epsilon0q__unit_rom_IDNT("_epsilon0q_");
11191   gen epsilon0q__unit_rom_IDNT_e(epsilon0q__unit_rom_IDNT);
11192   identificateur epsilonox__unit_rom_IDNT("_epsilonox_");
11193   gen epsilonox__unit_rom_IDNT_e(epsilonox__unit_rom_IDNT);
11194   identificateur epsilonsi__unit_rom_IDNT("_epsilonsi_");
11195   gen epsilonsi__unit_rom_IDNT_e(epsilonsi__unit_rom_IDNT);
11196   identificateur erg_unit_rom_IDNT("_erg");
11197   gen erg_unit_rom_IDNT_e(erg_unit_rom_IDNT);
11198   identificateur f0__unit_rom_IDNT("_f0_");
11199   gen f0__unit_rom_IDNT_e(f0__unit_rom_IDNT);
11200   identificateur fath_unit_rom_IDNT("_fath");
11201   gen fath_unit_rom_IDNT_e(fath_unit_rom_IDNT);
11202   identificateur fbm_unit_rom_IDNT("_fbm");
11203   gen fbm_unit_rom_IDNT_e(fbm_unit_rom_IDNT);
11204   identificateur fc_unit_rom_IDNT("_fc");
11205   gen fc_unit_rom_IDNT_e(fc_unit_rom_IDNT);
11206   identificateur fermi_unit_rom_IDNT("_fermi");
11207   gen fermi_unit_rom_IDNT_e(fermi_unit_rom_IDNT);
11208   identificateur flam_unit_rom_IDNT("_flam");
11209   gen flam_unit_rom_IDNT_e(flam_unit_rom_IDNT);
11210   identificateur fm_unit_rom_IDNT("_fm");
11211   gen fm_unit_rom_IDNT_e(fm_unit_rom_IDNT);
11212   identificateur ft_unit_rom_IDNT("_ft");
11213   gen ft_unit_rom_IDNT_e(ft_unit_rom_IDNT);
11214   identificateur ftUS_unit_rom_IDNT("_ftUS");
11215   gen ftUS_unit_rom_IDNT_e(ftUS_unit_rom_IDNT);
11216   identificateur g_unit_rom_IDNT("_g");
11217   gen g_unit_rom_IDNT_e(g_unit_rom_IDNT);
11218   identificateur g__unit_rom_IDNT("_g_");
11219   gen g__unit_rom_IDNT_e(g__unit_rom_IDNT);
11220   identificateur galC_unit_rom_IDNT("_galC");
11221   gen galC_unit_rom_IDNT_e(galC_unit_rom_IDNT);
11222   identificateur galUK_unit_rom_IDNT("_galUK");
11223   gen galUK_unit_rom_IDNT_e(galUK_unit_rom_IDNT);
11224   identificateur galUS_unit_rom_IDNT("_galUS");
11225   gen galUS_unit_rom_IDNT_e(galUS_unit_rom_IDNT);
11226   identificateur gf_unit_rom_IDNT("_gf");
11227   gen gf_unit_rom_IDNT_e(gf_unit_rom_IDNT);
11228   identificateur gmol_unit_rom_IDNT("_gmol");
11229   gen gmol_unit_rom_IDNT_e(gmol_unit_rom_IDNT);
11230   identificateur gon_unit_rom_IDNT("_gon");
11231   gen gon_unit_rom_IDNT_e(gon_unit_rom_IDNT);
11232   identificateur grad_unit_rom_IDNT("_grad");
11233   gen grad_unit_rom_IDNT_e(grad_unit_rom_IDNT);
11234   identificateur grain_unit_rom_IDNT("_grain");
11235   gen grain_unit_rom_IDNT_e(grain_unit_rom_IDNT);
11236   identificateur h_unit_rom_IDNT("_h");
11237   gen h_unit_rom_IDNT_e(h_unit_rom_IDNT);
11238   identificateur h__unit_rom_IDNT("_h_");
11239   gen h__unit_rom_IDNT_e(h__unit_rom_IDNT);
11240   identificateur ha_unit_rom_IDNT("_ha");
11241   gen ha_unit_rom_IDNT_e(ha_unit_rom_IDNT);
11242   identificateur hbar__unit_rom_IDNT("_hbar_");
11243   gen hbar__unit_rom_IDNT_e(hbar__unit_rom_IDNT);
11244   identificateur hp_unit_rom_IDNT("_hp");
11245   gen hp_unit_rom_IDNT_e(hp_unit_rom_IDNT);
11246   identificateur inH2O_unit_rom_IDNT("_inH2O");
11247   gen inH2O_unit_rom_IDNT_e(inH2O_unit_rom_IDNT);
11248   identificateur inHg_unit_rom_IDNT("_inHg");
11249   gen inHg_unit_rom_IDNT_e(inHg_unit_rom_IDNT);
11250   identificateur inch_unit_rom_IDNT("_inch");
11251   gen inch_unit_rom_IDNT_e(inch_unit_rom_IDNT);
11252   identificateur j_unit_rom_IDNT("_j");
11253   gen j_unit_rom_IDNT_e(j_unit_rom_IDNT);
11254   identificateur k__unit_rom_IDNT("_k_");
11255   gen k__unit_rom_IDNT_e(k__unit_rom_IDNT);
11256   identificateur kip_unit_rom_IDNT("_kip");
11257   gen kip_unit_rom_IDNT_e(kip_unit_rom_IDNT);
11258   identificateur knot_unit_rom_IDNT("_knot");
11259   gen knot_unit_rom_IDNT_e(knot_unit_rom_IDNT);
11260   identificateur kph_unit_rom_IDNT("_kph");
11261   gen kph_unit_rom_IDNT_e(kph_unit_rom_IDNT);
11262   identificateur kq__unit_rom_IDNT("_kq_");
11263   gen kq__unit_rom_IDNT_e(kq__unit_rom_IDNT);
11264   identificateur l_unit_rom_IDNT("_l");
11265   gen l_unit_rom_IDNT_e(l_unit_rom_IDNT);
11266   identificateur lam_unit_rom_IDNT("_lam");
11267   gen lam_unit_rom_IDNT_e(lam_unit_rom_IDNT);
11268   identificateur lambda0_unit_rom_IDNT("_lambda0");
11269   gen lambda0_unit_rom_IDNT_e(lambda0_unit_rom_IDNT);
11270   identificateur lambdac__unit_rom_IDNT("_lambdac_");
11271   gen lambdac__unit_rom_IDNT_e(lambdac__unit_rom_IDNT);
11272   identificateur lb_unit_rom_IDNT("_lb");
11273   gen lb_unit_rom_IDNT_e(lb_unit_rom_IDNT);
11274   identificateur lbf_unit_rom_IDNT("_lbf");
11275   gen lbf_unit_rom_IDNT_e(lbf_unit_rom_IDNT);
11276   identificateur lbmol_unit_rom_IDNT("_lbmol");
11277   gen lbmol_unit_rom_IDNT_e(lbmol_unit_rom_IDNT);
11278   identificateur lbt_unit_rom_IDNT("_lbt");
11279   gen lbt_unit_rom_IDNT_e(lbt_unit_rom_IDNT);
11280   identificateur lep_unit_rom_IDNT("_lep");
11281   gen lep_unit_rom_IDNT_e(lep_unit_rom_IDNT);
11282   identificateur liqpt_unit_rom_IDNT("_liqpt");
11283   gen liqpt_unit_rom_IDNT_e(liqpt_unit_rom_IDNT);
11284   identificateur lyr_unit_rom_IDNT("_lyr");
11285   gen lyr_unit_rom_IDNT_e(lyr_unit_rom_IDNT);
11286   identificateur mEarth__unit_rom_IDNT("_mEarth_");
11287   gen mEarth__unit_rom_IDNT_e(mEarth__unit_rom_IDNT);
11288   identificateur mSun__unit_rom_IDNT("_mSun_");
11289   gen mSun__unit_rom_IDNT_e(mSun__unit_rom_IDNT);
11290   identificateur me__unit_rom_IDNT("_me_");
11291   gen me__unit_rom_IDNT_e(me__unit_rom_IDNT);
11292   identificateur mho_unit_rom_IDNT("_mho");
11293   gen mho_unit_rom_IDNT_e(mho_unit_rom_IDNT);
11294   identificateur mi_unit_rom_IDNT("_mi");
11295   gen mi_unit_rom_IDNT_e(mi_unit_rom_IDNT);
11296   identificateur miUS_unit_rom_IDNT("_miUS");
11297   gen miUS_unit_rom_IDNT_e(miUS_unit_rom_IDNT);
11298   identificateur mil_unit_rom_IDNT("_mil");
11299   gen mil_unit_rom_IDNT_e(mil_unit_rom_IDNT);
11300   identificateur mile_unit_rom_IDNT("_mile");
11301   gen mile_unit_rom_IDNT_e(mile_unit_rom_IDNT);
11302   identificateur mille_unit_rom_IDNT("_mille");
11303   gen mille_unit_rom_IDNT_e(mille_unit_rom_IDNT);
11304   identificateur min_unit_rom_IDNT("_min");
11305   gen min_unit_rom_IDNT_e(min_unit_rom_IDNT);
11306   identificateur mmHg_unit_rom_IDNT("_mmHg");
11307   gen mmHg_unit_rom_IDNT_e(mmHg_unit_rom_IDNT);
11308   identificateur mn_unit_rom_IDNT("_mn");
11309   gen mn_unit_rom_IDNT_e(mn_unit_rom_IDNT);
11310   identificateur mol_unit_rom_IDNT("_mol");
11311   gen mol_unit_rom_IDNT_e(mol_unit_rom_IDNT);
11312   identificateur molK_unit_rom_IDNT("_molK");
11313   gen molK_unit_rom_IDNT_e(molK_unit_rom_IDNT);
11314   identificateur mp__unit_rom_IDNT("_mp_");
11315   gen mp__unit_rom_IDNT_e(mp__unit_rom_IDNT);
11316   identificateur mph_unit_rom_IDNT("_mph");
11317   gen mph_unit_rom_IDNT_e(mph_unit_rom_IDNT);
11318   identificateur mpme__unit_rom_IDNT("_mpme_");
11319   gen mpme__unit_rom_IDNT_e(mpme__unit_rom_IDNT);
11320   identificateur mu0__unit_rom_IDNT("_mu0_");
11321   gen mu0__unit_rom_IDNT_e(mu0__unit_rom_IDNT);
11322   identificateur muB__unit_rom_IDNT("_muB_");
11323   gen muB__unit_rom_IDNT_e(muB__unit_rom_IDNT);
11324   identificateur muN__unit_rom_IDNT("_muN_");
11325   gen muN__unit_rom_IDNT_e(muN__unit_rom_IDNT);
11326   identificateur nmi_unit_rom_IDNT("_nmi");
11327   gen nmi_unit_rom_IDNT_e(nmi_unit_rom_IDNT);
11328   identificateur oz_unit_rom_IDNT("_oz");
11329   gen oz_unit_rom_IDNT_e(oz_unit_rom_IDNT);
11330   identificateur ozUK_unit_rom_IDNT("_ozUK");
11331   gen ozUK_unit_rom_IDNT_e(ozUK_unit_rom_IDNT);
11332   identificateur ozfl_unit_rom_IDNT("_ozfl");
11333   gen ozfl_unit_rom_IDNT_e(ozfl_unit_rom_IDNT);
11334   identificateur ozt_unit_rom_IDNT("_ozt");
11335   gen ozt_unit_rom_IDNT_e(ozt_unit_rom_IDNT);
11336   identificateur pc_unit_rom_IDNT("_pc");
11337   gen pc_unit_rom_IDNT_e(pc_unit_rom_IDNT);
11338   identificateur pdl_unit_rom_IDNT("_pdl");
11339   gen pdl_unit_rom_IDNT_e(pdl_unit_rom_IDNT);
11340   identificateur phi__unit_rom_IDNT("_phi_");
11341   gen phi__unit_rom_IDNT_e(phi__unit_rom_IDNT);
11342   identificateur pk_unit_rom_IDNT("_pk");
11343   gen pk_unit_rom_IDNT_e(pk_unit_rom_IDNT);
11344   identificateur psi_unit_rom_IDNT("_psi");
11345   gen psi_unit_rom_IDNT_e(psi_unit_rom_IDNT);
11346   identificateur pt_unit_rom_IDNT("_pt");
11347   gen pt_unit_rom_IDNT_e(pt_unit_rom_IDNT);
11348   identificateur ptUK_unit_rom_IDNT("_ptUK");
11349   gen ptUK_unit_rom_IDNT_e(ptUK_unit_rom_IDNT);
11350   identificateur qe_unit_rom_IDNT("_qe");
11351   gen qe_unit_rom_IDNT_e(qe_unit_rom_IDNT);
11352   identificateur qepsilon0__unit_rom_IDNT("_qepsilon0_");
11353   gen qepsilon0__unit_rom_IDNT_e(qepsilon0__unit_rom_IDNT);
11354   identificateur qme__unit_rom_IDNT("_qme_");
11355   gen qme__unit_rom_IDNT_e(qme__unit_rom_IDNT);
11356   identificateur qt_unit_rom_IDNT("_qt");
11357   gen qt_unit_rom_IDNT_e(qt_unit_rom_IDNT);
11358   identificateur rad_unit_rom_IDNT("_rad");
11359   gen rad_unit_rom_IDNT_e(rad_unit_rom_IDNT);
11360   identificateur rd_unit_rom_IDNT("_rd");
11361   gen rd_unit_rom_IDNT_e(rd_unit_rom_IDNT);
11362   identificateur rem_unit_rom_IDNT("_rem");
11363   gen rem_unit_rom_IDNT_e(rem_unit_rom_IDNT);
11364   identificateur rev_unit_rom_IDNT("_rev");
11365   gen rev_unit_rom_IDNT_e(rev_unit_rom_IDNT);
11366   identificateur rod_unit_rom_IDNT("_rod");
11367   gen rod_unit_rom_IDNT_e(rod_unit_rom_IDNT);
11368   identificateur rpm_unit_rom_IDNT("_rpm");
11369   gen rpm_unit_rom_IDNT_e(rpm_unit_rom_IDNT);
11370   identificateur s_unit_rom_IDNT("_s");
11371   gen s_unit_rom_IDNT_e(s_unit_rom_IDNT);
11372   identificateur sb_unit_rom_IDNT("_sb");
11373   gen sb_unit_rom_IDNT_e(sb_unit_rom_IDNT);
11374   identificateur sd_unit_rom_IDNT("_sd");
11375   gen sd_unit_rom_IDNT_e(sd_unit_rom_IDNT);
11376   identificateur sigma_unit_rom_IDNT("_sigma");
11377   gen sigma_unit_rom_IDNT_e(sigma_unit_rom_IDNT);
11378   identificateur slug_unit_rom_IDNT("_slug");
11379   gen slug_unit_rom_IDNT_e(slug_unit_rom_IDNT);
11380   identificateur st_unit_rom_IDNT("_st");
11381   gen st_unit_rom_IDNT_e(st_unit_rom_IDNT);
11382   identificateur syr__unit_rom_IDNT("_syr_");
11383   gen syr__unit_rom_IDNT_e(syr__unit_rom_IDNT);
11384   identificateur t_unit_rom_IDNT("_t");
11385   gen t_unit_rom_IDNT_e(t_unit_rom_IDNT);
11386   identificateur tbsp_unit_rom_IDNT("_tbsp");
11387   gen tbsp_unit_rom_IDNT_e(tbsp_unit_rom_IDNT);
11388   identificateur tec_unit_rom_IDNT("_tec");
11389   gen tec_unit_rom_IDNT_e(tec_unit_rom_IDNT);
11390   identificateur tep_unit_rom_IDNT("_tep");
11391   gen tep_unit_rom_IDNT_e(tep_unit_rom_IDNT);
11392   identificateur tepC_unit_rom_IDNT("_tepC");
11393   gen tepC_unit_rom_IDNT_e(tepC_unit_rom_IDNT);
11394   identificateur tepcC_unit_rom_IDNT("_tepcC");
11395   gen tepcC_unit_rom_IDNT_e(tepcC_unit_rom_IDNT);
11396   identificateur tepgC_unit_rom_IDNT("_tepgC");
11397   gen tepgC_unit_rom_IDNT_e(tepgC_unit_rom_IDNT);
11398   identificateur tex_unit_rom_IDNT("_tex");
11399   gen tex_unit_rom_IDNT_e(tex_unit_rom_IDNT);
11400   identificateur therm_unit_rom_IDNT("_therm");
11401   gen therm_unit_rom_IDNT_e(therm_unit_rom_IDNT);
11402   identificateur toe_unit_rom_IDNT("_toe");
11403   gen toe_unit_rom_IDNT_e(toe_unit_rom_IDNT);
11404   identificateur ton_unit_rom_IDNT("_ton");
11405   gen ton_unit_rom_IDNT_e(ton_unit_rom_IDNT);
11406   identificateur tonUK_unit_rom_IDNT("_tonUK");
11407   gen tonUK_unit_rom_IDNT_e(tonUK_unit_rom_IDNT);
11408   identificateur tr_unit_rom_IDNT("_tr");
11409   gen tr_unit_rom_IDNT_e(tr_unit_rom_IDNT);
11410   identificateur tsp_unit_rom_IDNT("_tsp");
11411   gen tsp_unit_rom_IDNT_e(tsp_unit_rom_IDNT);
11412   identificateur u_unit_rom_IDNT("_u");
11413   gen u_unit_rom_IDNT_e(u_unit_rom_IDNT);
11414   identificateur E_unit_rom_IDNT("_E");
11415   gen E_unit_rom_IDNT_e(E_unit_rom_IDNT);
11416   identificateur Curie_unit_rom_IDNT("_Curie");
11417   gen Curie_unit_rom_IDNT_e(Curie_unit_rom_IDNT);
11418   identificateur C_unit_rom_IDNT("_C");
11419   gen C_unit_rom_IDNT_e(C_unit_rom_IDNT);
11420   identificateur kg_unit_rom_IDNT("_kg");
11421   gen kg_unit_rom_IDNT_e(kg_unit_rom_IDNT);
11422   // gen _kg_unit(kg_unit_rom_IDNT);
11423   identificateur Angstrom_unit_rom_IDNT("_Angstrom");
11424   gen Angstrom_unit_rom_IDNT_e(Angstrom_unit_rom_IDNT);
11425 #endif
11426   const gen * const tab_unit_rom[]={
11427     &A_unit_rom_IDNT_e,
11428     &Angstrom_unit_rom_IDNT_e,
11429     &Bq_unit_rom_IDNT_e,
11430     &Btu_unit_rom_IDNT_e,
11431     &C_unit_rom_IDNT_e,
11432     &Curie_unit_rom_IDNT_e,
11433     &E_unit_rom_IDNT_e,
11434     &F_unit_rom_IDNT_e,
11435     &FF_unit_rom_IDNT_e,
11436     &Faraday__unit_rom_IDNT_e,
11437     &Fdy_unit_rom_IDNT_e,
11438     &G__unit_rom_IDNT_e,
11439     &Gal_unit_rom_IDNT_e,
11440     &Gy_unit_rom_IDNT_e,
11441     &H_unit_rom_IDNT_e,
11442     &HFCC_unit_rom_IDNT_e,
11443     &Hz_unit_rom_IDNT_e,
11444     &IO__unit_rom_IDNT_e,
11445     &J_unit_rom_IDNT_e,
11446     &K_unit_rom_IDNT_e,
11447     &L_unit_rom_IDNT_e,
11448     &N_unit_rom_IDNT_e,
11449     &NA__unit_rom_IDNT_e,
11450     &Ohm_unit_rom_IDNT_e,
11451     &P_unit_rom_IDNT_e,
11452     &PSun__unit_rom_IDNT_e,
11453     &Pa_unit_rom_IDNT_e,
11454     &R_unit_rom_IDNT_e,
11455     &REarth__unit_rom_IDNT_e,
11456     &RSun__unit_rom_IDNT_e,
11457     &R__unit_rom_IDNT_e,
11458     &Rankine_unit_rom_IDNT_e,
11459     &Rinfinity__unit_rom_IDNT_e,
11460     &S_unit_rom_IDNT_e,
11461     &St_unit_rom_IDNT_e,
11462     &StdP__unit_rom_IDNT_e,
11463     &StdT__unit_rom_IDNT_e,
11464     &Sv_unit_rom_IDNT_e,
11465     &T_unit_rom_IDNT_e,
11466     &Torr_unit_rom_IDNT_e,
11467     &V_unit_rom_IDNT_e,
11468     &Vm__unit_rom_IDNT_e,
11469     &W_unit_rom_IDNT_e,
11470     &Wb_unit_rom_IDNT_e,
11471     &Wh_unit_rom_IDNT_e,
11472     &a_unit_rom_IDNT_e,
11473     &a0__unit_rom_IDNT_e,
11474     &acre_unit_rom_IDNT_e,
11475     &alpha__unit_rom_IDNT_e,
11476     &arcmin_unit_rom_IDNT_e,
11477     &arcs_unit_rom_IDNT_e,
11478     &atm_unit_rom_IDNT_e,
11479     &au_unit_rom_IDNT_e,
11480     &b_unit_rom_IDNT_e,
11481     &bar_unit_rom_IDNT_e,
11482     &bbl_unit_rom_IDNT_e,
11483     &bblep_unit_rom_IDNT_e,
11484     &boe_unit_rom_IDNT_e,
11485     &bu_unit_rom_IDNT_e,
11486     &buUS_unit_rom_IDNT_e,
11487     &c3__unit_rom_IDNT_e,
11488     &c__unit_rom_IDNT_e,
11489     &cal_unit_rom_IDNT_e,
11490     &cd_unit_rom_IDNT_e,
11491     &cf_unit_rom_IDNT_e,
11492     &chain_unit_rom_IDNT_e,
11493     &ct_unit_rom_IDNT_e,
11494     &cu_unit_rom_IDNT_e,
11495     &d_unit_rom_IDNT_e,
11496     &dB_unit_rom_IDNT_e,
11497     &deg_unit_rom_IDNT_e,
11498     &dyn_unit_rom_IDNT_e,
11499     &eV_unit_rom_IDNT_e,
11500     &epsilon0__unit_rom_IDNT_e,
11501     &epsilon0q__unit_rom_IDNT_e,
11502     &epsilonox__unit_rom_IDNT_e,
11503     &epsilonsi__unit_rom_IDNT_e,
11504     &erg_unit_rom_IDNT_e,
11505     &f0__unit_rom_IDNT_e,
11506     &fath_unit_rom_IDNT_e,
11507     &fbm_unit_rom_IDNT_e,
11508     &fc_unit_rom_IDNT_e,
11509     &fermi_unit_rom_IDNT_e,
11510     &flam_unit_rom_IDNT_e,
11511     &fm_unit_rom_IDNT_e,
11512     &ft_unit_rom_IDNT_e,
11513     &ftUS_unit_rom_IDNT_e,
11514     &g_unit_rom_IDNT_e,
11515     &g__unit_rom_IDNT_e,
11516     &galC_unit_rom_IDNT_e,
11517     &galUK_unit_rom_IDNT_e,
11518     &galUS_unit_rom_IDNT_e,
11519     &gf_unit_rom_IDNT_e,
11520     &gmol_unit_rom_IDNT_e,
11521     &gon_unit_rom_IDNT_e,
11522     &grad_unit_rom_IDNT_e,
11523     &grain_unit_rom_IDNT_e,
11524     &h_unit_rom_IDNT_e,
11525     &h__unit_rom_IDNT_e,
11526     &ha_unit_rom_IDNT_e,
11527     &hbar__unit_rom_IDNT_e,
11528     &hp_unit_rom_IDNT_e,
11529     &inH2O_unit_rom_IDNT_e,
11530     &inHg_unit_rom_IDNT_e,
11531     &inch_unit_rom_IDNT_e,
11532     &j_unit_rom_IDNT_e,
11533     &k__unit_rom_IDNT_e,
11534     &kg_unit_rom_IDNT_e,
11535     &kip_unit_rom_IDNT_e,
11536     &knot_unit_rom_IDNT_e,
11537     &kph_unit_rom_IDNT_e,
11538     &kq__unit_rom_IDNT_e,
11539     &l_unit_rom_IDNT_e,
11540     &lam_unit_rom_IDNT_e,
11541     &lambda0_unit_rom_IDNT_e,
11542     &lambdac__unit_rom_IDNT_e,
11543     &lb_unit_rom_IDNT_e,
11544     &lbf_unit_rom_IDNT_e,
11545     &lbmol_unit_rom_IDNT_e,
11546     &lbt_unit_rom_IDNT_e,
11547     &lep_unit_rom_IDNT_e,
11548     &liqpt_unit_rom_IDNT_e,
11549     &lyr_unit_rom_IDNT_e,
11550     &m_unit_rom_IDNT_e,
11551     &mEarth__unit_rom_IDNT_e,
11552     &mSun__unit_rom_IDNT_e,
11553     &me__unit_rom_IDNT_e,
11554     &mho_unit_rom_IDNT_e,
11555     &mi_unit_rom_IDNT_e,
11556     &miUS_unit_rom_IDNT_e,
11557     &mil_unit_rom_IDNT_e,
11558     &mile_unit_rom_IDNT_e,
11559     &mille_unit_rom_IDNT_e,
11560     &min_unit_rom_IDNT_e,
11561     &mmHg_unit_rom_IDNT_e,
11562     &mn_unit_rom_IDNT_e,
11563     &mol_unit_rom_IDNT_e,
11564     &molK_unit_rom_IDNT_e,
11565     &mp__unit_rom_IDNT_e,
11566     &mph_unit_rom_IDNT_e,
11567     &mpme__unit_rom_IDNT_e,
11568     &mu0__unit_rom_IDNT_e,
11569     &muB__unit_rom_IDNT_e,
11570     &muN__unit_rom_IDNT_e,
11571     &nmi_unit_rom_IDNT_e,
11572     &oz_unit_rom_IDNT_e,
11573     &ozUK_unit_rom_IDNT_e,
11574     &ozfl_unit_rom_IDNT_e,
11575     &ozt_unit_rom_IDNT_e,
11576     &pc_unit_rom_IDNT_e,
11577     &pdl_unit_rom_IDNT_e,
11578     &phi__unit_rom_IDNT_e,
11579     &pk_unit_rom_IDNT_e,
11580     &psi_unit_rom_IDNT_e,
11581     &pt_unit_rom_IDNT_e,
11582     &ptUK_unit_rom_IDNT_e,
11583     &qe_unit_rom_IDNT_e,
11584     &qepsilon0__unit_rom_IDNT_e,
11585     &qme__unit_rom_IDNT_e,
11586     &qt_unit_rom_IDNT_e,
11587     &rad_unit_rom_IDNT_e,
11588     &rd_unit_rom_IDNT_e,
11589     &rem_unit_rom_IDNT_e,
11590     &rev_unit_rom_IDNT_e,
11591     &rod_unit_rom_IDNT_e,
11592     &rpm_unit_rom_IDNT_e,
11593     &s_unit_rom_IDNT_e,
11594     &sb_unit_rom_IDNT_e,
11595     &sd_unit_rom_IDNT_e,
11596     &sigma_unit_rom_IDNT_e,
11597     &slug_unit_rom_IDNT_e,
11598     &st_unit_rom_IDNT_e,
11599     &syr__unit_rom_IDNT_e,
11600     &t_unit_rom_IDNT_e,
11601     &tbsp_unit_rom_IDNT_e,
11602     &tec_unit_rom_IDNT_e,
11603     &tep_unit_rom_IDNT_e,
11604     &tepC_unit_rom_IDNT_e,
11605     &tepcC_unit_rom_IDNT_e,
11606     &tepgC_unit_rom_IDNT_e,
11607     &tex_unit_rom_IDNT_e,
11608     &therm_unit_rom_IDNT_e,
11609     &toe_unit_rom_IDNT_e,
11610     &ton_unit_rom_IDNT_e,
11611     &tonUK_unit_rom_IDNT_e,
11612     &tr_unit_rom_IDNT_e,
11613     &tsp_unit_rom_IDNT_e,
11614     &u_unit_rom_IDNT_e,
11615     &yd_unit_rom_IDNT_e,
11616     &yr_unit_rom_IDNT_e,
11617   };
is_unit_rom(const char * s,gen & res)11618   bool is_unit_rom(const char * s,gen & res){
11619     for (int i=0;i<sizeof(tab_unit_rom)/sizeof(gen *);++i){
11620       if (!strcmp(s,tab_unit_rom[i]->_IDNTptr->id_name)){
11621 	res=*tab_unit_rom[i];
11622 	return true;
11623       }
11624     }
11625     return false;
11626   }
11627 
11628 
mksa_register(const char * s,const mksa_unit * equiv)11629   gen mksa_register(const char * s,const mksa_unit * equiv){
11630 #ifdef USTL
11631     ustl::map<const char *, const mksa_unit *,ltstr>::const_iterator it=unit_conversion_map().find(s+1),itend=unit_conversion_map().end();
11632 #else
11633     std::map<const char *, const mksa_unit *,ltstr>::const_iterator it=unit_conversion_map().find(s+1),itend=unit_conversion_map().end();
11634 #endif
11635     gen res;
11636     lock_syms_mutex();
11637     if (it!=itend)
11638       res=syms()[s];
11639     else {
11640       unit_conversion_map()[s+1]=equiv;
11641       if (is_unit_rom(s,res))
11642 	syms()[s]=res;
11643       else
11644 	res = (syms()[s] = new ref_identificateur(s));
11645     }
11646     unlock_syms_mutex();
11647     return res;
11648   }
mksa_register_unit(const char * s,const mksa_unit * equiv)11649   gen mksa_register_unit(const char * s,const mksa_unit * equiv){
11650     return symbolic(at_unit,makevecteur(1,mksa_register(s,equiv)));
11651   }
11652   const gen * tab_usual_units[]={&C_unit_rom_IDNT_e,&F_unit_rom_IDNT_e,&Gy_unit_rom_IDNT_e,&H_unit_rom_IDNT_e,&Hz_unit_rom_IDNT_e,&J_unit_rom_IDNT_e,&mho_unit_rom_IDNT_e,&N_unit_rom_IDNT_e,&Ohm_unit_rom_IDNT_e,&Pa_unit_rom_IDNT_e,&rad_unit_rom_IDNT_e,&S_unit_rom_IDNT_e,&Sv_unit_rom_IDNT_e,&T_unit_rom_IDNT_e,&V_unit_rom_IDNT_e,&W_unit_rom_IDNT_e,&Wb_unit_rom_IDNT_e};
11653   const mksa_unit __Angstrom_unit={1e-10,1,0,0,0,0,0,0,0};
11654   const mksa_unit __Btu_unit={1055.05585262,2,1,-2,0,0,0,0,0};
11655   const mksa_unit __Curie_unit={3.7e10,0,0,-1,0,0,0,0,0};
11656   const mksa_unit __FF_unit={.152449017237,0,0,0,0,0,0,0,1};
11657   const mksa_unit __Fdy_unit={96485.3365,0,0,1,1,0,0,0,0};
11658   const mksa_unit __Gal={0.01,1,0,-2,0,0,0,0,0};
11659   const mksa_unit __HFCC_unit={1400,1,0,0,0,0,0,0,0};
11660   const mksa_unit __L_unit={0.001,3,0,0,0,0,0,0,0};
11661   const mksa_unit __P_unit={.1,-1,1,-1,0,0,0,0,0};
11662   const mksa_unit __R_unit={0.000258,0,-1,1,1,0,0,0,0};
11663   const mksa_unit __Rankine_unit={5./9,0,0,0,0,1,0,0,0};
11664   const mksa_unit __St_unit={0.0001,2,0,-1,0,0,0,0,0};
11665   const mksa_unit __Wh_unit={3600,2,1,-2,0,0,0,0,0};
11666   const mksa_unit __a_unit={100,2,0,0,0,0,0,0,0};
11667   const mksa_unit __acre_unit={4046.87260987,2,0,0,0,0,0,0,0};
11668   const mksa_unit __arcmin_unit={2.90888208666e-4,0,0,0,0,0,0,0,0};
11669   const mksa_unit __arcs_unit={4.8481368111e-6,0,0,0,0,0,0,0,0};
11670   const mksa_unit __atm_unit={101325.0,-1,1,-2,0,0,0,0,0};
11671   const mksa_unit __au_unit={1.495979e11,1,0,0,0,0,0,0,0};
11672   const mksa_unit __b_unit={1e-28,2,0,0,0,0,0,0,0};
11673   const mksa_unit __bar_unit={1e5,-1,1,-2,0,0,0,0,0};
11674   const mksa_unit __bbl_unit={.158987294928,3,0,0,0,0,0,0,0};
11675   const mksa_unit __bblep_unit={.158987294928*0.857*41.76e9,2,1,-2,0,0,0,0,0};
11676   const mksa_unit __boe_unit={.158987294928*0.857*41.76e9,2,1,-2,0,0,0,0,0};
11677   const mksa_unit __bu={0.036368736,3,0,0,0,0,0,0,0};
11678   const mksa_unit __buUS={0.03523907,3,0,0,0,0,0,0,0};
11679   const mksa_unit __cal_unit={4.184,2,1,-2,0,0,0,0,0};
11680   const mksa_unit __cf_unit={1.08e6,2,1,-2,0,0,0,0,0};
11681   const mksa_unit __chain_unit={20.1168402337,1,0,0,0,0,0,0,0};
11682   const mksa_unit __ct_unit={0.0002,0,1,0,0,0,0,0,0};
11683   const mksa_unit __dB_unit={1,0,0,0,0,0,0,0,0};
11684   const mksa_unit __d_unit={86400,0,0,1,0,0,0,0,0};
11685   const mksa_unit __deg_unit={1.74532925199e-2,0,0,0,0,0,0,0,0};
11686   // const mksa_unit __degreeF_unit={5./9,0,0,0,0,1,0,0,0};
11687   const mksa_unit __dyn_unit={1e-5,1,1,-2,0,0,0,0,0};
11688   const mksa_unit __eV_unit={1.60217733e-19,2,1,-2,0,0,0,0,0};
11689   const mksa_unit __erg_unit={1e-7,2,1,-2,0,0,0,0,0};
11690   const mksa_unit __fath_unit={1.82880365761,1,0,0,0,0,0,0,0};
11691   const mksa_unit __fbm_unit={0.002359737216,3,0,0,0,0,0,0,0};
11692   const mksa_unit __fc_unit={10.7639104167,1,0,0,0,0,0,0,0};
11693   const mksa_unit __fermi_unit={1e-15,1,0,0,0,0,0,0,0};
11694   const mksa_unit __flam_unit={3.42625909964,-2,0,0,0,0,0,1,0};
11695   const mksa_unit __fm_unit={1.82880365761,1,0,0,0,0,0,0,0};
11696   const mksa_unit __ft_unit={0.3048,1,0,0,0,0,0,0,0};
11697   const mksa_unit __ftUS_unit={0.304800609601,1,0,0,0,0,0,0,0};
11698   const mksa_unit __g_unit={1e-3,0,1,0,0,0,0,0,0};
11699   const mksa_unit __galC_unit={0.00454609,3,0,0,0,0,0,0,0};
11700   const mksa_unit __galUK_unit={0.004546092,3,0,0,0,0,0,0,0};
11701   const mksa_unit __galUS_unit={0.003785411784,3,0,0,0,0,0,0,0};
11702   const mksa_unit __cu_unit={0.000236588236373,3,0,0,0,0,0,0,0};
11703   const mksa_unit __gf_unit={0.00980665,1,1,-2,0,0,0,0,0};
11704   const mksa_unit __gmol_unit={1,0,0,0,0,0,1,0,0};
11705   const mksa_unit __gon_unit={1.57079632679e-2,0,0,0,0,0,0,0};
11706   const mksa_unit __grad_unit={1.57079632679e-2,0,0,0,0,0,0,0,0};
11707   const mksa_unit __grain_unit={0.00006479891,0,1,0,0,0,0,0,0};
11708   const mksa_unit __h_unit={3600,0,0,1,0,0,0,0,0};
11709   const mksa_unit __ha_unit={10000,2,0,0,0,0,0,0,0};
11710   const mksa_unit __hp_unit={745.699871582,2,1,-3,0,0,0,0,0};
11711   const mksa_unit __in_unit={0.0254,1,0,0,0,0,0,0,0};
11712   const mksa_unit __inH2O_unit={249.08193551052,-1,1,-2,0,0,0,0,0};
11713   const mksa_unit __inHg_unit={3386.38815789,-1,1,-2,0,0,0,0,0};
11714   const mksa_unit __j_unit={86400,0,0,1,0,0,0,0,0};
11715   const mksa_unit __kip_unit={4448.22161526,1,1,-2,0,0,0,0,0};
11716   const mksa_unit __knot_unit={0.51444444444,1,0,-1,0,0,0,0,0};
11717   const mksa_unit __kph_unit={0.2777777777777,1,0,-1,0,0,0,0,0};
11718   const mksa_unit __l_unit={0.001,3,0,0,0,0,0,0,0};
11719   const mksa_unit __lam_unit={3183.09886184,-2,0,0,0,0,0,1,0};
11720   const mksa_unit __lb_unit={0.45359237,0,1,0,0,0,0,0,0};
11721   const mksa_unit __lbf_unit={4.44922161526,1,1,-2,0,0,0,0,0};
11722   const mksa_unit __lbmol_unit={453.59237,0,0,0,0,0,1,0,0};
11723   const mksa_unit __lbt_unit={0.3732417216,0,1,0,0,0,0,0,0};
11724   const mksa_unit __lep_unit={0.857*41.76e6,2,1,-2,0,0,0,0,0};
11725   const mksa_unit __liqpt_unit={0.000473176473,3,0,0,0,0,0,0,0};
11726   const mksa_unit __lyr_unit={9.46052840488e15,1,0,0,0,0,0,0,0};
11727   const mksa_unit __mi_unit={1609.344,1,0,0,0,0,0,0,0};
11728   const mksa_unit __miUS_unit={1609.34721869,1,0,0,0,0,0,0,0};
11729   const mksa_unit __mil_unit={0.0000254,1,0,0,0,0,0,0,0};
11730   const mksa_unit __mile_unit={1609.344,1,0,0,0,0,0,0,0};
11731   const mksa_unit __mille_unit={1852,1,0,0,0,0,0,0,0};
11732   const mksa_unit __mn_unit={60,0,0,1,0,0,0,0,0};
11733   const mksa_unit __mmHg_unit={133.322387415,-1,1,-2,0,0,0,0,0};
11734   const mksa_unit __molK_unit={1,0,0,0,0,1,1,0,0};
11735   const mksa_unit __mph_unit={0.44704,1,0,-1,0,0,0,0,0};
11736   const mksa_unit __nmi_unit={1852,1,0,0,0,0,0,0,0};
11737   const mksa_unit __oz_unit={0.028349523125,0,1,0,0,0,0,0,0};
11738   const mksa_unit __ozUK_unit={2.84130625e-5,3,0,0,0,0,0,0,0};
11739   const mksa_unit __ozfl_unit={2.95735295625e-5,3,0,0,0,0,0,0,0};
11740   const mksa_unit __ozt_unit={0.0311034768,0,1,0,0,0,0,0,0};
11741   const mksa_unit __pc_unit={3.08567758149137e16,1,0,0,0,0,0,0,0};
11742   const mksa_unit __pdl_unit={0.138254954376,1,1,-2,0,0,0,0,0};
11743   const mksa_unit __pk_unit={0.0088097675,3,0,0,0,0,0,0,0};
11744   const mksa_unit __psi_unit={6894.75729317,-1,1,-2,0,0,0,0,0};
11745   const mksa_unit __pt_unit={0.000473176473,3,0,0,0,0,0,0,0};
11746   const mksa_unit __ptUK_unit={0.0005682615,3,0,0,0,0,0,0,0};
11747   const mksa_unit __qt_unit={0.000946359246,3,0,0,0,0,0,0,0};
11748   const mksa_unit __rd_unit={0.01,2,0,-2,0,0,0,0,0};
11749   const mksa_unit __rem_unit={0.01,2,0,-2,0,0,0,0,0};
11750   const mksa_unit __rod_unit={5.02921005842,1,0,0,0,0,0,0,0};
11751   const mksa_unit __rpm_unit={0.0166666666667,0,0,-1,0,0,0,0,0};
11752   const mksa_unit __sb_unit={10000,-2,0,0,0,0,0,1,0};
11753   const mksa_unit __slug_unit={14.5939029372,0,1,0,0,0,0,0,0};
11754   const mksa_unit __st_unit={1,3,0,0,0,0,0,0,0};
11755   const mksa_unit __t_unit={1000,0,1,0,0,0,0,0,0};
11756   const mksa_unit __tbsp_unit={1.47867647813e-5,3,0,0,0,0,0,0,0};
11757   const mksa_unit __tec_unit={41.76e9/1.5,2,1,-2,0,0,0,0,0};
11758   const mksa_unit __tep_unit={41.76e9,2,1,-2,0,0,0,0,0};
11759   const mksa_unit __tepC_unit={830,1,0,0,0,0,0,0,0};
11760   const mksa_unit __tepcC_unit={1000,1,0,0,0,0,0,0,0};
11761   const mksa_unit __tepgC_unit={650,1,0,0,0,0,0,0,0};
11762   const mksa_unit __tex={1e-6,-1,1,0,0,0,0,0,0};
11763   const mksa_unit __therm_unit={105506000,2,1,-2,0,0,0,0,0};
11764   const mksa_unit __toe_unit={41.76e9,2,1,-2,0,0,0,0,0};
11765   const mksa_unit __ton_unit={907.18474,0,1,0,0,0,0,0,0};
11766   const mksa_unit __tonUK_unit={1016.0469088,0,1,0,0,0,0,0,0};
11767   const mksa_unit __Torr_unit={133.322368421,-1,1,-2,0,0,0,0,0};
11768   const mksa_unit __tr_unit={2*M_PI,0,0,0,0,0,0,0,0};
11769   const mksa_unit __tsp_unit={4.928921614571597e-6,3,0,0,0,0,0,0,0};
11770   const mksa_unit __u_unit={1.6605402e-27,0,1,0,0,0,0,0,0};
11771   const mksa_unit __yd_unit={0.9144,1,0,0,0,0,0,0,0};
11772   const mksa_unit __yr_unit={31556925.9747,0,0,1,0,0,0,0,0};
11773   const mksa_unit __micron_unit={1e-6,1,0,0,0,0,0,0,0};
11774 
11775   const mksa_unit __hbar_unit={1.05457266e-34,2,1,-1,0,0,0,0};
11776   const mksa_unit __c_unit={299792458,1,0,-1,0,0,0,0};
11777   const mksa_unit __g__unit={9.80665,1,0,-2,0,0,0,0};
11778   const mksa_unit __IO_unit={1e-12,0,1,-3,0,0,0,0};
11779   const mksa_unit __epsilonox_unit={3.9,0,0,0,0,0,0,0};
11780   const mksa_unit __epsilonsi_unit={11.9,0,0,0,0,0,0,0,0};
11781   const mksa_unit __qepsilon0_unit={1.4185979e-30,-3,-1,5,3,0,0,0};
11782   const mksa_unit __epsilon0q_unit={55263469.6,-3,-1,3,1,0,0,0};
11783   const mksa_unit __kq_unit={8.617386e-5,2,1,-3,-1,-1,0,0};
11784   const mksa_unit __c3_unit={.002897756,1,0,0,0,1,0,0};
11785   const mksa_unit __lambdac_unit={ 0.00242631058e-9,1,0,0,0,0,0,0,0};
11786   const mksa_unit __f0_unit={2.4179883e14,0,0,-1,0,0,0,0};
11787   const mksa_unit __lambda0_unit={1239.8425e-9,1,0,0,0,0,0,0};
11788   const mksa_unit __muN_unit={5.0507866e-27,2,0,0,1,0,0,0};
11789   const mksa_unit __muB_unit={ 9.2740154e-24,2,0,0,1,0,0,0};
11790   const mksa_unit __a0_unit={.0529177249e-9,1,0,0,0,0,0,0};
11791   const mksa_unit __Rinfinity_unit={10973731.534,-1,0,0,0,0,0,0};
11792   const mksa_unit __Faraday_unit={96485.309,0,0,1,1,0,-1,0};
11793   const mksa_unit __phi_unit={2.06783461e-15,2,1,-2,-1,0,0,0};
11794   const mksa_unit __alpha_unit={7.29735308e-3,0,0,0,0,0,0,0};
11795   const mksa_unit __mpme_unit={1836.152701,0,0,0,0,0,0,0};
11796   const mksa_unit __mp_unit={1.6726231e-27,0,1,0,0,0,0,0};
11797   const mksa_unit __qme_unit={1.75881962e11,0,-1,1,1,0,0,0};
11798   const mksa_unit __me_unit={9.1093897e-31,0,1,0,0,0,0,0};
11799   const mksa_unit __qe_unit={1.60217733e-19,0,0,1,1,0,0,0};
11800   const mksa_unit __h__unit={6.6260755e-34,2,1,-1,0,0,0,0};
11801   const mksa_unit __G_unit={6.67408e-11,3,-1,-2,0,0,0,0};
11802   const mksa_unit __mu0_unit={1.25663706144e-6,1,1,-2,-2,0,0,0};
11803   const mksa_unit __epsilon0_unit={8.85418781761e-12,-3,-1,4,2,0,0,0};
11804   const mksa_unit __sigma_unit={ 5.67051e-8,0,1,-3,0,-4,0,0};
11805   const mksa_unit __StdP_unit={101325.0,-1,1,-2,0,0,0,0};
11806   const mksa_unit __StdT_unit={273.15,0,0,0,0,1,0,0};
11807   const mksa_unit __R__unit={8.31451,2,1,-2,0,-1,-1,0};
11808   const mksa_unit __Vm_unit={22.4141e-3,3,0,0,0,0,-1,0};
11809   const mksa_unit __k_unit={1.380658e-23,2,1,-2,0,-1,0,0};
11810   const mksa_unit __NA_unit={6.0221367e23,0,0,0,0,0,-1,0};
11811   const mksa_unit __mSun_unit={1.989e30,0,1,0,0,0,0,0};
11812   const mksa_unit __RSun_unit={6.955e8,1,0,0,0,0,0,0};
11813   const mksa_unit __PSun_unit={3.846e26,2,1,-3,0,0,0,0};
11814   const mksa_unit __mEarth_unit={5.9736e24,0,1,0,0,0,0,0};
11815   const mksa_unit __REarth_unit={6.371e6,1,0,0,0,0,0,0};
11816   const mksa_unit __sd_unit={8.61640905e4,0,0,1,0,0,0,0};
11817   const mksa_unit __syr_unit={3.15581498e7,0,0,1,0,0,0,0};
11818 
11819   // table of alpha-sorted units
11820   const mksa_unit * const unitptr_tab[]={
11821     &__A_unit,
11822     &__Angstrom_unit,
11823     &__Bq_unit,
11824     &__Btu_unit,
11825     &__C_unit,
11826     &__Curie_unit,
11827     &__E_unit,
11828     &__F_unit,
11829     &__FF_unit,
11830     &__Faraday_unit,
11831     &__Fdy_unit,
11832     &__G_unit,
11833     &__Gal,
11834     &__Gy_unit,
11835     &__H_unit,
11836     &__HFCC_unit,
11837     &__Hz_unit,
11838     &__IO_unit,
11839     &__J_unit,
11840     &__K_unit,
11841     &__L_unit,
11842     &__N_unit,
11843     &__NA_unit,
11844     &__Ohm_unit,
11845     &__P_unit,
11846     &__PSun_unit,
11847     &__Pa_unit,
11848     &__R_unit,
11849     &__REarth_unit,
11850     &__RSun_unit,
11851     &__R__unit,
11852     &__Rankine_unit,
11853     &__Rinfinity_unit,
11854     &__S_unit,
11855     &__St_unit,
11856     &__StdP_unit,
11857     &__StdT_unit,
11858     &__Sv_unit,
11859     &__T_unit,
11860     &__Torr_unit,
11861     &__V_unit,
11862     &__Vm_unit,
11863     &__W_unit,
11864     &__Wb_unit,
11865     &__Wh_unit,
11866     &__a_unit,
11867     &__a0_unit,
11868     &__acre_unit,
11869     &__alpha_unit,
11870     &__arcmin_unit,
11871     &__arcs_unit,
11872     &__atm_unit,
11873     &__au_unit,
11874     &__b_unit,
11875     &__bar_unit,
11876     &__bbl_unit,
11877     &__bblep_unit,
11878     &__boe_unit,
11879     &__bu,
11880     &__buUS,
11881     &__c3_unit,
11882     &__c_unit,
11883     &__cal_unit,
11884     &__cd_unit,
11885     &__cf_unit,
11886     &__chain_unit,
11887     &__ct_unit,
11888     &__cu_unit,
11889     &__d_unit,
11890     &__dB_unit,
11891     &__deg_unit,
11892     // &__degreeF_unit,
11893     &__dyn_unit,
11894     &__eV_unit,
11895     &__epsilon0_unit,
11896     &__epsilon0q_unit,
11897     &__epsilonox_unit,
11898     &__epsilonsi_unit,
11899     &__erg_unit,
11900     &__f0_unit,
11901     &__fath_unit,
11902     &__fbm_unit,
11903     &__fc_unit,
11904     &__fermi_unit,
11905     &__flam_unit,
11906     &__fm_unit,
11907     &__ft_unit,
11908     &__ftUS_unit,
11909     &__g_unit,
11910     &__g__unit,
11911     &__galC_unit,
11912     &__galUK_unit,
11913     &__galUS_unit,
11914     &__gf_unit,
11915     &__gmol_unit,
11916     &__gon_unit,
11917     &__grad_unit,
11918     &__grain_unit,
11919     &__h_unit,
11920     &__h__unit,
11921     &__ha_unit,
11922     &__hbar_unit,
11923     &__hp_unit,
11924     &__inH2O_unit,
11925     &__inHg_unit,
11926     &__in_unit,
11927     &__j_unit,
11928     &__k_unit,
11929     &__kg_unit,
11930     &__kip_unit,
11931     &__knot_unit,
11932     &__kph_unit,
11933     &__kq_unit,
11934     &__l_unit,
11935     &__lam_unit,
11936     &__lambda0_unit,
11937     &__lambdac_unit,
11938     &__lb_unit,
11939     &__lbf_unit,
11940     &__lbmol_unit,
11941     &__lbt_unit,
11942     &__lep_unit,
11943     &__liqpt_unit,
11944     &__lyr_unit,
11945     &__m_unit,
11946     &__mEarth_unit,
11947     &__mSun_unit,
11948     &__me_unit,
11949     &__mho_unit,
11950     &__mi_unit,
11951     &__miUS_unit,
11952     &__mil_unit,
11953     &__mile_unit,
11954     &__mille_unit,
11955     &__mn_unit,
11956     &__mmHg_unit,
11957     &__mn_unit,
11958     &__mol_unit,
11959     &__molK_unit,
11960     &__mp_unit,
11961     &__mph_unit,
11962     &__mpme_unit,
11963     &__mu0_unit,
11964     &__muB_unit,
11965     &__muN_unit,
11966     &__nmi_unit,
11967     &__oz_unit,
11968     &__ozUK_unit,
11969     &__ozfl_unit,
11970     &__ozt_unit,
11971     &__pc_unit,
11972     &__pdl_unit,
11973     &__phi_unit,
11974     &__pk_unit,
11975     &__psi_unit,
11976     &__pt_unit,
11977     &__ptUK_unit,
11978     &__qe_unit,
11979     &__qepsilon0_unit,
11980     &__qme_unit,
11981     &__qt_unit,
11982     &__rad_unit,
11983     &__rd_unit,
11984     &__rem_unit,
11985     &__tr_unit,
11986     &__rod_unit,
11987     &__rpm_unit,
11988     &__s_unit,
11989     &__sb_unit,
11990     &__sd_unit,
11991     &__sigma_unit,
11992     &__slug_unit,
11993     &__st_unit,
11994     &__syr_unit,
11995     &__t_unit,
11996     &__tbsp_unit,
11997     &__tec_unit,
11998     &__tep_unit,
11999     &__tepC_unit,
12000     &__tepcC_unit,
12001     &__tepgC_unit,
12002     &__tex,
12003     &__therm_unit,
12004     &__toe_unit,
12005     &__tonUK_unit,
12006     &__ton_unit,
12007     &__tr_unit,
12008     &__tsp_unit,
12009     &__u_unit,
12010     &__yd_unit,
12011     &__yr_unit,
12012 #ifndef VISUALC
12013     &__micron_unit
12014 #endif
12015   };
12016   const unsigned unitptr_tab_length=sizeof(unitptr_tab)/sizeof(mksa_unit *);
12017   const char * const unitname_tab[]={
12018     "_A",
12019     "_Angstrom",
12020     "_Bq",
12021     "_Btu",
12022     "_C",
12023     "_Curie",
12024     "_E",
12025     "_F",
12026     "_FF",
12027     "_Faraday_",
12028     "_Fdy",
12029     "_G_",
12030     "_Gal",
12031     "_Gy",
12032     "_H",
12033     "_HFCC",
12034     "_Hz",
12035     "_IO_",
12036     "_J",
12037     "_K",
12038     "_L",
12039     "_N",
12040     "_NA_",
12041     "_Ohm",
12042     "_P",
12043     "_PSun_",
12044     "_Pa",
12045     "_R",
12046     "_REarth_",
12047     "_RSun_",
12048     "_R_",
12049     "_Rankine",
12050     "_Rinfinity_",
12051     "_S",
12052     "_St",
12053     "_StdP_",
12054     "_StdT_",
12055     "_Sv",
12056     "_T",
12057     "_Torr",
12058     "_V",
12059     "_Vm_",
12060     "_W",
12061     "_Wb",
12062     "_Wh",
12063     "_a",
12064     "_a0_",
12065     "_acre",
12066     "_alpha_",
12067     "_arcmin",
12068     "_arcs",
12069     "_atm",
12070     "_au",
12071     "_b",
12072     "_bar",
12073     "_bbl",
12074     "_bblep",
12075     "_boe",
12076     "_bu",
12077     "_buUS",
12078     "_c3_",
12079     "_c_",
12080     "_cal",
12081     "_cd",
12082     "_cf",
12083     "_chain",
12084     "_ct",
12085     "_cu",
12086     "_d",
12087     "_dB",
12088     "_deg",
12089     // "_degreeF",
12090     "_dyn",
12091     "_eV",
12092     "_epsilon0_",
12093     "_epsilon0q_",
12094     "_epsilonox_",
12095     "_epsilonsi_",
12096     "_erg",
12097     "_f0_",
12098     "_fath",
12099     "_fbm",
12100     "_fc",
12101     "_fermi",
12102     "_flam",
12103     "_fm",
12104     "_ft",
12105     "_ftUS",
12106     "_g",
12107     "_g_",
12108     "_galC",
12109     "_galUK",
12110     "_galUS",
12111     "_gf",
12112     "_gmol",
12113     "_gon",
12114     "_grad",
12115     "_grain",
12116     "_h",
12117     "_h_",
12118     "_ha",
12119     "_hbar_",
12120     "_hp",
12121     "_inH2O",
12122     "_inHg",
12123     "_inch"       ,
12124     "_j",
12125     "_k_",
12126     "_kg",
12127     "_kip",
12128     "_knot",
12129     "_kph",
12130     "_kq_",
12131     "_l",
12132     "_lam",
12133     "_lambda0_",
12134     "_lambdac_",
12135     "_lb",
12136     "_lbf",
12137     "_lbmol",
12138     "_lbt",
12139     "_lep",
12140     "_liqpt",
12141     "_lyr",
12142     "_m",
12143     "_mEarth_",
12144     "_mSun_",
12145     "_me_",
12146     "_mho",
12147     "_mi",
12148     "_miUS",
12149     "_mil",
12150     "_mile",
12151     "_mille",
12152     "_min",
12153     "_mmHg",
12154     "_mn",
12155     "_mol",
12156     "_molK",
12157     "_mp_",
12158     "_mph",
12159     "_mpme_",
12160     "_mu0_",
12161     "_muB_",
12162     "_muN_",
12163     "_nmi",
12164     "_oz",
12165     "_ozUK",
12166     "_ozfl",
12167     "_ozt",
12168     "_pc",
12169     "_pdl",
12170     "_phi_",
12171     "_pk",
12172     "_psi",
12173     "_pt",
12174     "_ptUK",
12175     "_qe_",
12176     "_qepsilon0_",
12177     "_qme_",
12178     "_qt",
12179     "_rad",
12180     "_rd",
12181     "_rem",
12182     "_rev",
12183     "_rod",
12184     "_rpm",
12185     "_s",
12186     "_sb",
12187     "_sd_",
12188     "_sigma_",
12189     "_slug",
12190     "_st",
12191     "_syr_",
12192     "_t",
12193     "_tbsp",
12194     "_tec",
12195     "_tep",
12196     "_tepC",
12197     "_tepcC",
12198     "_tepgC",
12199     "_tex",
12200     "_therm",
12201     "_toe",
12202     "_ton",
12203     "_tonUK",
12204     "_tr",
12205     "_tsp",
12206     "_u",
12207     "_yd",
12208     "_yr",
12209 #ifndef VISUALC
12210     "_\u03BC"
12211     // "_µ"
12212 #endif
12213   };
12214 
12215   const char * const * const unitname_tab_end=unitname_tab+unitptr_tab_length;
12216 #ifndef NO_PHYSICAL_CONSTANTS
12217   gen _kg_unit(mksa_register("_kg",&__kg_unit));
12218   gen _m_unit(mksa_register("_m",&__m_unit));
12219   gen _s_unit(mksa_register("_s",&__s_unit));
12220   gen _A_unit(mksa_register("_A",&__A_unit));
12221   gen _K_unit(mksa_register("_K",&__K_unit)); // Kelvin
12222   gen _mol_unit(mksa_register("_mol",&__mol_unit)); // mol
12223   gen _cd_unit(mksa_register("_cd",&__cd_unit)); // candela
12224   gen _E_unit(mksa_register("_E",&__E_unit)); // euro
12225 
12226 #ifndef STATIC_BUILTIN_LEXER_FUNCTIONS
12227   gen _C_unit(mksa_register("_C",&__C_unit));
12228   gen _F_unit(mksa_register("_F",&__F_unit));
12229   gen _Gy_unit(mksa_register("_Gy",&__Gy_unit));
12230   gen _H_unit(mksa_register("_H",&__H_unit));
12231   gen _Hz_unit(mksa_register("_Hz",&__Hz_unit));
12232   gen _J_unit(mksa_register("_J",&__J_unit));
12233   gen _mho_unit(mksa_register("_mho",&__mho_unit));
12234   gen _N_unit(mksa_register("_N",&__N_unit));
12235   gen _Ohm_unit(mksa_register("_Ohm",&__Ohm_unit));
12236   gen _Pa_unit(mksa_register("_Pa",&__Pa_unit));
12237   gen _rad_unit(mksa_register("_rad",&__rad_unit)); // radian
12238   gen _S_unit(mksa_register("_S",&__S_unit));
12239   gen _Sv_unit(mksa_register("_Sv",&__Sv_unit));
12240   gen _T_unit(mksa_register("_T",&__T_unit));
12241   gen _V_unit(mksa_register("_V",&__V_unit));
12242   gen _W_unit(mksa_register("_W",&__W_unit));
12243   gen _Wb_unit(mksa_register("_Wb",&__Wb_unit));
12244   gen _l_unit(mksa_register("_l",&__l_unit));
12245   gen _molK_unit(mksa_register("_molK",&__molK_unit));
12246 
12247   gen _Bq_unit(mksa_register("_Bq",&__Bq_unit));
12248   gen _L_unit(mksa_register("_L",&__L_unit));
12249   // other metric units in m,kg,s,A
12250   gen _st_unit(mksa_register("_st",&__st_unit));
12251   // useful non metric units
12252   gen _a_unit(mksa_register("_a",&__a_unit));
12253   gen _acre_unit(mksa_register("_acre",&__acre_unit));
12254   gen _arcmin_unit(mksa_register("_arcmin",&__arcmin_unit));
12255   gen _arcs_unit(mksa_register("_arcs",&__arcs_unit));
12256   gen _atm_unit(mksa_register("_atm",&__atm_unit));
12257   gen _au_unit(mksa_register("_au",&__au_unit));
12258   gen _Angstrom_unit(mksa_register("_Angstrom",&__Angstrom_unit));
12259   gen _micron_unit(mksa_register("_\u03BC",&__micron_unit));
12260   //gen _micron_unit(mksa_register("_µ",&__micron_unit));
12261   gen _b_unit(mksa_register("_b",&__b_unit));
12262   gen _bar_unit(mksa_register("_bar",&__bar_unit));
12263   gen _bbl_unit(mksa_register("_bbl",&__bbl_unit));
12264   gen _buUS(mksa_register("_buUS",&__buUS));
12265   gen _bu(mksa_register("_bu",&__bu));
12266   gen _Btu_unit(mksa_register("_Btu",&__Btu_unit));
12267   gen _cal_unit(mksa_register("_cal",&__cal_unit));
12268   gen _chain_unit(mksa_register("_chain",&__chain_unit));
12269   gen _Curie_unit(mksa_register("_Curie",&__Curie_unit));
12270   gen _ct_unit(mksa_register("_ct",&__ct_unit));
12271   gen _deg_unit(mksa_register("_deg",&__deg_unit));
12272   gen _d_unit(mksa_register("_d",&__d_unit));
12273   gen _dB_unit(mksa_register("_dB",&__dB_unit));
12274   gen _dyn_unit(mksa_register("_dyn",&__dyn_unit));
12275   gen _erg_unit(mksa_register("_erg",&__erg_unit));
12276   gen _eV_unit(mksa_register("_eV",&__eV_unit));
12277   // gen _degreeF_unit(mksa_register("_degreeF",&__degreeF_unit));
12278   gen _Rankine_unit(mksa_register("_Rankine",&__Rankine_unit));
12279   gen _fath_unit(mksa_register("_fath",&__fath_unit));
12280   gen _fm_unit(mksa_register("_fm",&__fm_unit));
12281   gen _fbm_unit(mksa_register("_fbm",&__fbm_unit));
12282   // gen _fc_unit(mksa_register("_fc",&__fc_unit));
12283   gen _Fdy_unit(mksa_register("_Fdy",&__Fdy_unit));
12284   gen _fermi_unit(mksa_register("_fermi",&__fermi_unit));
12285   gen _flam_unit(mksa_register("_flam",&__flam_unit));
12286   gen _ft_unit(mksa_register("_ft",&__ft_unit));
12287   gen _ftUS_unit(mksa_register("_ftUS",&__ftUS_unit));
12288   gen _Gal(mksa_register("_Gal",&__Gal));
12289   gen _g_unit(mksa_register("_g",&__g_unit));
12290   gen _galUS_unit(mksa_register("_galUS",&__galUS_unit));
12291   gen _galC_unit(mksa_register("_galC",&__galC_unit));
12292   gen _galUK_unit(mksa_register("_galUK",&__galUK_unit));
12293   gen _gf_unit(mksa_register("_gf",&__gf_unit));
12294   gen _gmol_unit(mksa_register("_gmol",&__gmol_unit));
12295   gen _grad_unit(mksa_register("_grad",&__grad_unit));
12296   gen _gon_unit(mksa_register("_gon",&__gon_unit));
12297   gen _grain_unit(mksa_register("_grain",&__grain_unit));
12298   gen _ha_unit(mksa_register("_ha",&__ha_unit));
12299   gen _h_unit(mksa_register("_h",&__h_unit));
12300   gen _hp_unit(mksa_register("_hp",&__hp_unit));
12301   gen _in_unit(mksa_register("_inch",&__in_unit));
12302   gen _inHg_unit(mksa_register("_inHg",&__inHg_unit));
12303   gen _inH2O_unit(mksa_register("_inH2O",&__inH2O_unit));
12304   gen _j_unit(mksa_register("_j",&__j_unit));
12305   gen _FF_unit(mksa_register("_FF",&__FF_unit));
12306   gen _kip_unit(mksa_register("_kip",&__kip_unit));
12307   gen _knot_unit(mksa_register("_knot",&__knot_unit));
12308   gen _kph_unit(mksa_register("_kph",&__kph_unit));
12309   gen _lam_unit(mksa_register("_lam",&__lam_unit));
12310   gen _lb_unit(mksa_register("_lb",&__lb_unit));
12311   gen _lbf_unit(mksa_register("_lbf",&__lbf_unit));
12312   gen _lbmol_unit(mksa_register("_lbmol",&__lbmol_unit));
12313   gen _lbt_unit(mksa_register("_lbt",&__lbt_unit));
12314   gen _lyr_unit(mksa_register("_lyr",&__lyr_unit));
12315   gen _mi_unit(mksa_register("_mi",&__mi_unit));
12316   gen _mil_unit(mksa_register("_mil",&__mil_unit));
12317   gen _mile_unit(mksa_register("_mile",&__mile_unit));
12318   gen _mille_unit(mksa_register("_mille",&__mille_unit));
12319   gen _mn_unit(mksa_register("_mn",&__mn_unit));
12320   gen _miUS_unit(mksa_register("_miUS",&__miUS_unit));
12321   gen _mmHg_unit(mksa_register("_mmHg",&__mmHg_unit));
12322   gen _mph_unit(mksa_register("_mph",&__mph_unit));
12323   gen _nmi_unit(mksa_register("_nmi",&__nmi_unit));
12324   gen _oz_unit(mksa_register("_oz",&__oz_unit));
12325   gen _ozfl_unit(mksa_register("_ozfl",&__ozfl_unit));
12326   gen _ozt_unit(mksa_register("_ozt",&__ozt_unit));
12327   gen _ozUK_unit(mksa_register("_ozUK",&__ozUK_unit));
12328   gen _P_unit(mksa_register("_P",&__P_unit));
12329   gen _pc_unit(mksa_register("_pc",&__pc_unit));
12330   gen _pdl_unit(mksa_register("_pdl",&__pdl_unit));
12331   gen _pk_unit(mksa_register("_pk",&__pk_unit));
12332   gen _psi_unit(mksa_register("_psi",&__psi_unit));
12333   gen _pt_unit(mksa_register("_pt",&__pt_unit));
12334   gen _ptUK_unit(mksa_register("_ptUK",&__ptUK_unit));
12335   gen _liqpt_unit(mksa_register("_liqpt",&__liqpt_unit));
12336   gen _qt_unit(mksa_register("_qt",&__qt_unit));
12337   gen _R_unit(mksa_register("_R",&__R_unit));
12338   gen _rd_unit(mksa_register("_rd",&__rd_unit));
12339   gen _rod_unit(mksa_register("_rod",&__rod_unit));
12340   gen _rem_unit(mksa_register("_rem",&__rem_unit));
12341   gen _rpm_unit(mksa_register("_rpm",&__rpm_unit));
12342   gen _sb_unit(mksa_register("_sb",&__sb_unit));
12343   gen _slug_unit(mksa_register("_slug",&__slug_unit));
12344   gen _St_unit(mksa_register("_St",&__St_unit));
12345   gen _t_unit(mksa_register("_t",&__t_unit));
12346   gen _tbsp_unit(mksa_register("_tbsp",&__tbsp_unit));
12347   gen _tex(mksa_register("_tex",&__tex));
12348   gen _therm_unit(mksa_register("_therm",&__therm_unit));
12349   gen _ton_unit(mksa_register("_ton",&__ton_unit));
12350   gen _tonUK_unit(mksa_register("_tonUK",&__tonUK_unit));
12351   gen _Torr_unit(mksa_register("_Torr",&__Torr_unit));
12352   gen _tr_unit(mksa_register("_tr",&__tr_unit)); // radian
12353   gen _u_unit(mksa_register("_u",&__u_unit));
12354   gen _yd_unit(mksa_register("_yd",&__yd_unit));
12355   gen _yr_unit(mksa_register("_yr",&__yr_unit));
12356 
12357   // Some hydrocarbur energy equivalent
12358   // tep=tonne equivalent petrole, lep litre equivalent petrole
12359   // toe=(metric) ton of oil equivalent
12360   // bblep = baril equivalent petrole, boe=baril of oil equivalent
12361   gen _tep_unit(mksa_register("_tep",&__tep_unit));
12362   gen _toe_unit(mksa_register("_toe",&__toe_unit));
12363   gen _cf_unit(mksa_register("_cf",&__cf_unit));
12364   gen _tec_unit(mksa_register("_tec",&__tec_unit));
12365   gen _lep_unit(mksa_register("_lep",&__lep_unit));
12366   gen _bblep_unit(mksa_register("_bblep",&__bblep_unit));
12367   gen _boe_unit(mksa_register("_boe",&__boe_unit));
12368   gen _Wh_unit(mksa_register("_Wh",&__Wh_unit));
12369   // Equivalent Carbon for 1 tep, oil, gas, coal
12370   gen _tepC_unit(mksa_register("_tepC",&__tepC_unit));
12371   gen _tepgC_unit(mksa_register("_tepgC",&__tepgC_unit));
12372   gen _tepcC_unit(mksa_register("_tepcC",&__tepcC_unit));
12373   // mean PRG for HFC in kg C unit
12374   gen _HFCC_unit(mksa_register("_HFCC",&__HFCC_unit));
12375 #endif // ndef STATIC_BUILTIN_LEXER_FUNCTIONS
12376 #endif
12377 
mksa_unit2vecteur(const mksa_unit * tmp)12378   static vecteur mksa_unit2vecteur(const mksa_unit * tmp){
12379     vecteur v;
12380     if (tmp->K==0 && tmp->mol==0 && tmp->cd==0){
12381       if (tmp->m==0 && tmp->kg==0 && tmp->s==0 && tmp->A==0 && tmp->E==0){
12382 	v.push_back(tmp->coeff);
12383       }
12384       else {
12385 	v.reserve(5);
12386 	v.push_back(tmp->coeff);
12387 	v.push_back(tmp->m);
12388 	v.push_back(tmp->kg);
12389 	v.push_back(tmp->s);
12390 	v.push_back(tmp->A);
12391       }
12392     }
12393     else {
12394       v.reserve(9);
12395       v.push_back(tmp->coeff);
12396       v.push_back(tmp->m);
12397       v.push_back(tmp->kg);
12398       v.push_back(tmp->s);
12399       v.push_back(tmp->A);
12400       v.push_back(tmp->K);
12401       v.push_back(tmp->mol);
12402       v.push_back(tmp->cd);
12403       v.push_back(tmp->E);
12404     }
12405     return v;
12406   }
12407 
mksa_unit2vecteur(const string & s)12408   static vecteur mksa_unit2vecteur(const string & s){
12409     for (int i=0;i<sizeof(tab_unit_rom)/sizeof(gen *);++i){
12410       if (!strcmp(s.c_str(),tab_unit_rom[i]->_IDNTptr->id_name))
12411 	return mksa_unit2vecteur(unitptr_tab[i]);
12412     }
12413     return mksa_unit2vecteur(unit_conversion_map()[s.substr(1,s.size()-1).c_str()]);
12414   }
12415 
12416   struct mksa_tri3 {
mksa_tri3giac::mksa_tri312417     mksa_tri3() {}
operator ()giac::mksa_tri312418     bool operator ()(const char * a,const char * b){
12419       return strcmp(a,b)<0;
12420     }
12421   };
12422 
12423   // return a vector of powers in MKSA system
mksa_convert(const identificateur & g,GIAC_CONTEXT)12424   vecteur mksa_convert(const identificateur & g,GIAC_CONTEXT){
12425     string s=g.print(contextptr);
12426     // Find prefix in unit
12427     int exposant=0;
12428     int l=int(s.size());
12429 #ifdef USTL
12430     ustl::pair<const char * const * const,const char * const * const> pp=ustl::equal_range(unitname_tab,unitname_tab_end,s.c_str(),mksa_tri3());
12431 #else
12432     std::pair<const char * const * const,const char * const * const> pp=equal_range(unitname_tab,unitname_tab_end,s.c_str(),mksa_tri3());
12433 #endif
12434     if (pp.first!=pp.second && pp.second!=unitname_tab_end)
12435       mksa_register_unit(*pp.first,unitptr_tab[pp.first-unitname_tab]);
12436     if (l>1 && s[0]=='_'){
12437       --l;
12438       s=s.substr(1,l);
12439     }
12440     else
12441       return makevecteur(g);
12442     gen res=plus_one;
12443 #ifdef USTL
12444     ustl::map<const char *, const mksa_unit *,ltstr>::const_iterator it=unit_conversion_map().find(s.c_str()),itend=unit_conversion_map().end();
12445 #else
12446     std::map<const char *, const mksa_unit *,ltstr>::const_iterator it=unit_conversion_map().find(s.c_str()),itend=unit_conversion_map().end();
12447 #endif
12448     int nchar=1;
12449     if (it==itend && l>1){
12450       switch (s[0]){
12451       case 'Y':
12452 	exposant=24;
12453 	break;
12454       case 'Z':
12455 	exposant=21;
12456 	break;
12457       case 'E':
12458 	exposant=18;
12459 	break;
12460       case 'P':
12461 	exposant=15;
12462 	break;
12463       case 'T':
12464 	exposant=12;
12465 	break;
12466       case 'G':
12467 	exposant=9;
12468 	break;
12469       case 'M':
12470 	exposant=6;
12471 	break;
12472       case 'K': case 'k':
12473 	exposant=3;
12474 	break;
12475       case 'H': case 'h':
12476 	exposant=2;
12477 	break;
12478       case 'D':
12479 	exposant=1;
12480 	break;
12481       case 'd':
12482 	exposant=-1;
12483 	break;
12484       case 'c':
12485 	exposant=-2;
12486 	break;
12487       case 'm':
12488 	exposant=-3;
12489 	break;
12490       case char(0xc2): // micro
12491 	if (l>2 && s[1]==char(0xB5)) {
12492 	  nchar=2;
12493 	  exposant=-6;
12494 	}
12495 	break;
12496       case 'n':
12497 	exposant=-9;
12498 	break;
12499       case 'p':
12500 	exposant=-12;
12501 	break;
12502       case 'f':
12503 	exposant=-15;
12504 	break;
12505       case 'a':
12506 	exposant=-18;
12507 	break;
12508       case 'z':
12509 	exposant=-21;
12510 	break;
12511       case 'y':
12512 	exposant=-24;
12513 	break;
12514       }
12515     }
12516     if (exposant!=0){
12517       s=s.substr(nchar,l-nchar);
12518       res=std::pow(10.0,double(exposant));
12519 #ifdef USTL
12520       ustl::pair<const char * const * const,const char * const * const> pp=ustl::equal_range(unitname_tab,unitname_tab_end,("_"+s).c_str(),mksa_tri3());
12521 #else
12522       std::pair<const char * const * const,const char * const * const> pp=equal_range(unitname_tab,unitname_tab_end,("_"+s).c_str(),mksa_tri3());
12523 #endif
12524       if (pp.first!=pp.second && pp.second!=unitname_tab_end)
12525 	mksa_register_unit(*pp.first,unitptr_tab[pp.first-unitname_tab]);
12526       it=unit_conversion_map().find(s.c_str());
12527     }
12528     if (it==itend)
12529       return makevecteur(operator_times(res,find_or_make_symbol("_"+s,false,contextptr),contextptr));
12530     vecteur v=mksa_unit2vecteur(it->second);
12531     v[0]=operator_times(res,v[0],contextptr);
12532     return v;
12533   }
12534 
mksa_convert(const gen & g,GIAC_CONTEXT)12535   vecteur mksa_convert(const gen & g,GIAC_CONTEXT){
12536     if (g.type==_IDNT)
12537       return mksa_convert(*g._IDNTptr,contextptr);
12538     if (g.type!=_SYMB)
12539       return makevecteur(g);
12540     if (g.is_symb_of_sommet(at_unit)){
12541       vecteur & v=*g._SYMBptr->feuille._VECTptr;
12542       vecteur res0=mksa_convert(v[1],contextptr);
12543       vecteur res1=mksa_convert(v[0],contextptr);
12544       vecteur res=addvecteur(res0,res1);
12545       res.front()=operator_times(res0.front(),res1.front(),contextptr);
12546       return res;
12547     }
12548     if (g._SYMBptr->sommet==at_inv){
12549       vecteur res(mksa_convert(g._SYMBptr->feuille,contextptr));
12550       res[0]=inv(res[0],contextptr);
12551       int s=int(res.size());
12552       for (int i=1;i<s;++i)
12553 	res[i]=-res[i];
12554       return res;
12555     }
12556     if (g._SYMBptr->sommet==at_pow){
12557       gen & f=g._SYMBptr->feuille;
12558       if (f.type!=_VECT||f._VECTptr->size()!=2)
12559 	return vecteur(1,gensizeerr(contextptr));
12560       vecteur res(mksa_convert(f._VECTptr->front(),contextptr));
12561       gen e=f._VECTptr->back();
12562       res[0]=pow(res[0],e,contextptr);
12563       int s=int(res.size());
12564       for (int i=1;i<s;++i)
12565 	res[i]=operator_times(e,res[i],contextptr);
12566       return res;
12567     }
12568     if (g._SYMBptr->sommet==at_prod){
12569       gen & f=g._SYMBptr->feuille;
12570       if (f.type!=_VECT)
12571 	return mksa_convert(f,contextptr);
12572       vecteur & v=*f._VECTptr;
12573       vecteur res(makevecteur(plus_one));
12574       const_iterateur it=v.begin(),itend=v.end();
12575       for (;it!=itend;++it){
12576 	vecteur tmp(mksa_convert(*it,contextptr));
12577 	res[0]=operator_times(res[0],tmp[0],contextptr);
12578 	iterateur it=res.begin()+1,itend=res.end(),jt=tmp.begin()+1,jtend=tmp.end();
12579 	for (;it!=itend && jt!=jtend;++it,++jt)
12580 	  *it=*it+*jt;
12581 	for (;jt!=jtend;++jt)
12582 	  res.push_back(*jt);
12583       }
12584       return res;
12585     }
12586     return makevecteur(g);
12587   }
12588 
unitpow(const gen & g,const gen & exponent_)12589   gen unitpow(const gen & g,const gen & exponent_){
12590     gen exponent=evalf_double(exponent_,1,context0);
12591     if (exponent.type!=_DOUBLE_)
12592       return gensizeerr(gettext("Invalid unit exponent")+exponent.print());
12593     if (absdouble(exponent._DOUBLE_val)<1e-6)
12594       return plus_one;
12595     if (is_one(exponent))
12596       return g;
12597     return symbolic(at_pow,gen(makevecteur(g,exponent),_SEQ__VECT));
12598   }
mksa_reduce(const gen & g,GIAC_CONTEXT)12599   gen mksa_reduce(const gen & g,GIAC_CONTEXT){
12600     if (g.type==_VECT)
12601       return apply(g,mksa_reduce,contextptr);
12602     vecteur v(mksa_convert(g,contextptr));
12603     if (is_undef(v)) return v;
12604     gen res1=v[0];
12605     gen res=plus_one;
12606     int s=int(v.size());
12607     if (s>2)
12608       res = res *unitpow(_kg_unit,v[2]);
12609     if (s>1)
12610       res = res *unitpow(_m_unit,v[1]);
12611     if (s>3)
12612       res = res *unitpow(_s_unit,v[3]);
12613     if (s>4)
12614       res = res * unitpow(_A_unit,v[4]);
12615     if (s>5)
12616       res = res * unitpow(_K_unit,v[5]);
12617     if (s>6)
12618       res = res * unitpow(_mol_unit,v[6]);
12619     if (s>7)
12620       res = res * unitpow(_cd_unit,v[7]);
12621     if (s>8)
12622       res = res * unitpow(_E_unit,v[8]);
12623     if (is_one(res))
12624       return res1;
12625     else
12626       return symbolic(at_unit,makevecteur(res1,res));
12627   }
12628   static const char _mksa_s []="mksa";
12629   static define_unary_function_eval (__mksa,&mksa_reduce,_mksa_s);
12630   define_unary_function_ptr5( at_mksa ,alias_at_mksa,&__mksa,0,true);
12631 
_ufactor(const gen & g,GIAC_CONTEXT)12632   gen _ufactor(const gen & g,GIAC_CONTEXT){
12633     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
12634     if (g.type==_VECT && g.subtype==_SEQ__VECT && g._VECTptr->size()==2){
12635       vecteur & v=*g._VECTptr;
12636       return v.back()*mksa_reduce(v.front()/v.back(),contextptr);
12637     }
12638     return gensizeerr(contextptr);
12639   }
12640   static const char _ufactor_s []="ufactor";
12641   static define_unary_function_eval (__ufactor,&_ufactor,_ufactor_s);
12642   define_unary_function_ptr5( at_ufactor ,alias_at_ufactor,&__ufactor,0,true);
12643 
_usimplify(const gen & g,GIAC_CONTEXT)12644   gen _usimplify(const gen & g,GIAC_CONTEXT){
12645     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
12646     if (g.type==_VECT)
12647       return apply(g,_usimplify,contextptr);
12648     if (!g.is_symb_of_sommet(at_unit))
12649       return g;
12650     vecteur v=mksa_convert(g,contextptr);
12651     if (is_undef(v)) return v;
12652     gen res1=v[0];
12653     int s=int(v.size());
12654     for (int i=s;i<5;++i)
12655       v.push_back(zero);
12656     for (;s>0;--s){
12657       if (!is_zero(v[s-1]))
12658 	break;
12659     }
12660     if (s>5)
12661       return g;
12662     // look first if it's a mksa
12663     int pos=0;
12664     for (int i=1;i<5;++i){
12665       if (v[i]==zero)
12666 	continue;
12667       if (pos){
12668 	pos=0;
12669 	break;
12670       }
12671       pos=i;
12672     }
12673     if (pos)
12674       return mksa_reduce(g,contextptr);
12675     v[0]=plus_one;
12676     const gen ** it=tab_usual_units,**itend=it+sizeof(tab_usual_units)/sizeof(const gen *);
12677     // const_iterateur it=usual_units().begin(),itend=usual_units().end();
12678     for (;it!=itend;++it){
12679       string s=(*it)->print(contextptr);
12680       vecteur tmp=mksa_unit2vecteur(s);
12681       for (int i=tmp.size();i<5;++i)
12682 	tmp.push_back(zero);
12683       if (tmp==v)
12684 	return _ufactor(gen(makevecteur(g,symbolic(at_unit,makevecteur(1,**it))),_SEQ__VECT),contextptr);
12685     }
12686     // count non-zero in v, if ==2 return mksa
12687     int count=0;
12688     const_iterateur jt=v.begin()+1,jtend=v.end();
12689     for (;jt!=jtend;++jt){
12690       if (!is_zero(*jt))
12691 	++count;
12692     }
12693     if (count<=2)
12694       return mksa_reduce(g,contextptr);
12695     // it=usual_units().begin(); itend=usual_units().end();
12696     it=tab_usual_units;
12697     for (;it!=itend;++it){
12698       string s=(*it)->print(contextptr);
12699       gen tmp=mksa_unit2vecteur(s);
12700       vecteur w(*tmp._VECTptr);
12701       for (int j=0;j<2;j++){
12702 	vecteur vw;
12703 	if (j)
12704 	  vw=addvecteur(v,w);
12705 	else
12706 	  vw=subvecteur(v,w);
12707 	for (int i=1;i<5;++i){
12708 	  if (is_greater(1e-6,abs(vw[i],contextptr),contextptr))
12709 	    continue;
12710 	  if (pos){
12711 	    pos=0;
12712 	    break;
12713 	  }
12714 	  pos=i;
12715 	}
12716 	if (pos){
12717 	  if (j)
12718 	    return _ufactor(gen(makevecteur(g,symbolic(at_unit,makevecteur(1,unitpow(**it,-1)))),_SEQ__VECT),contextptr);
12719 	  else
12720 	    return _ufactor(gen(makevecteur(g,symbolic(at_unit,makevecteur(1,**it))),_SEQ__VECT),contextptr);
12721 	}
12722       }
12723     }
12724     return g;
12725   }
12726   static const char _usimplify_s []="usimplify";
12727   static define_unary_function_eval (__usimplify,&_usimplify,_usimplify_s);
12728   define_unary_function_ptr5( at_usimplify ,alias_at_usimplify,&__usimplify,0,true);
12729 
symb_unit(const gen & a,const gen & b,GIAC_CONTEXT)12730   gen symb_unit(const gen & a,const gen & b,GIAC_CONTEXT){
12731     if (b==at_min)
12732       return symb_unit(a,gen("mn",contextptr),contextptr);
12733     // Add a _ to all identifiers in b
12734     if (!lop(b,at_of).empty())
12735       return gensizeerr(contextptr);
12736     vecteur v(lidnt(b)); // was lvar(b), changed because 1_(km/s) did not work
12737     for (unsigned i=0;i<v.size();++i){
12738       if (v[i].type!=_IDNT)
12739 	return gensizeerr(contextptr); // bad unit
12740     }
12741     vecteur w(v);
12742     iterateur it=w.begin(),itend=w.end();
12743     for (;it!=itend;++it){
12744       find_or_make_symbol("_"+it->print(contextptr),*it,0,false,contextptr);
12745     }
12746     return symbolic(at_unit,makevecteur(a,subst(b,v,w,true,contextptr)));
12747   }
printasunit(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)12748   string printasunit(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
12749     if (feuille.type!=_VECT || feuille._VECTptr->size()!=2)
12750       return gettext("printasunit error");
12751     vecteur & v=*feuille._VECTptr;
12752     vecteur v1(lidnt(v[1]));
12753     vecteur w(v1);
12754     iterateur it=w.begin(),itend=w.end();
12755     for (;it!=itend;++it){
12756       string s;
12757       s=it->print(contextptr);
12758       if (!s.empty() && s[0]=='_')
12759 	s=s.substr(1,s.size()-1);
12760       *it=identificateur(s);//find_or_make_symbol(s,*it,0,false,contextptr);
12761     }
12762     string tmp(subst(v[1],v1,w,true,contextptr).print(contextptr));
12763     if (tmp[0]=='c' || (v[1].type==_SYMB
12764 			// && !v[1].is_symb_of_sommet(at_pow)
12765 			) )
12766       tmp="_("+tmp+")";
12767     else
12768       tmp="_"+tmp;
12769     if (v[0].type<_POLY || v[0].type==_FLOAT_)
12770       return v[0].print(contextptr)+tmp;
12771     else
12772       return "("+v[0].print(contextptr)+")"+tmp;
12773   }
unit(const gen & g,GIAC_CONTEXT)12774   static gen unit(const gen & g,GIAC_CONTEXT){
12775     if (g.type!=_VECT || g._VECTptr->size()!=2)
12776       return gensizeerr(contextptr);
12777     return symbolic(at_unit,g);
12778   }
12779   static const char _unit_s []="_";
12780   static define_unary_function_eval2_index (112,__unit,&unit,_unit_s,&printasunit);
12781   define_unary_function_ptr( at_unit ,alias_at_unit ,&__unit);
12782 
12783 #ifndef FXCG
binary_op_tab()12784   const unary_function_ptr * binary_op_tab(){
12785     static const unary_function_ptr binary_op_tab_ptr []={*at_plus,*at_prod,*at_pow,*at_and,*at_ou,*at_xor,*at_different,*at_same,*at_equal,*at_unit,*at_compose,*at_composepow,*at_deuxpoints,*at_tilocal,*at_pointprod,*at_pointdivision,*at_pointpow,*at_division,*at_normalmod,*at_minus,*at_intersect,*at_union,*at_interval,*at_inferieur_egal,*at_inferieur_strict,*at_superieur_egal,*at_superieur_strict,*at_equal2,0};
12786     return binary_op_tab_ptr;
12787   }
12788   // unary_function_ptr binary_op_tab[]={at_and,at_ou,at_different,at_same,0};
12789 #endif
12790 
12791   // Physical constants -> in input_lexer.ll
12792 #if 0 //ndef NO_PHYSICAL_CONSTANTS
12793   identificateur _cst_hbar("_hbar_",symbolic(at_unit,makevecteur(1.05457266e-34,_J_unit*_s_unit)));
12794   gen cst_hbar(_cst_hbar);
12795   identificateur _cst_clightspeed("_c_",symbolic(at_unit,makevecteur(299792458,_m_unit/_s_unit)));
12796   gen cst_clightspeed(_cst_clightspeed);
12797   identificateur _cst_ga("_g_",symbolic(at_unit,makevecteur(9.80665,_m_unit*unitpow(_s_unit,-2))));
12798   gen cst_ga(_cst_ga);
12799   identificateur _cst_IO("_IO_",symbolic(at_unit,makevecteur(1e-12,_W_unit*unitpow(_m_unit,-2))));
12800   gen cst_IO(_cst_IO);
12801   // gen cst_IO("_io",context0); //  IO 1e-12W/m^2
12802   identificateur _cst_epsilonox("_epsilonox_",3.9);
12803   gen cst_epsilonox(_cst_epsilonox); // 3.9
12804   identificateur _cst_epsilonsi("_epsilonsi_",11.9);
12805   gen cst_epsilonsi(_cst_epsilonsi); // 11.9
12806   identificateur _cst_qepsilon0("_qepsilon0_",symbolic(at_unit,makevecteur(1.4185979e-30,_F_unit*_C_unit/_m_unit)));
12807   gen cst_qepsilon0(_cst_qepsilon0); // qeps0 1.4185979e-30 F*C/m
12808   identificateur _cst_epsilon0q("_epsilon0q_",symbolic(at_unit,makevecteur(55263469.6,_F_unit/(_m_unit*_C_unit))));
12809   gen cst_epsilon0q(_cst_epsilon0q); // eps0q 55263469.6 F/(m*C)
12810   identificateur _cst_kq("_kq_",symbolic(at_unit,makevecteur(8.617386e-5,_J_unit/(_K_unit*_C_unit))));
12811   gen cst_kq(_cst_kq); // kq 8.617386e-5 J/(K*C)
12812   identificateur _cst_c3("_c3_",symbolic(at_unit,makevecteur(.002897756,_m_unit*_K_unit)));
12813   gen cst_c3(_cst_c3); // c3 .002897756m*K
12814   identificateur _cst_lambdac("_lambdac_",symbolic(at_unit,makevecteur( 0.00242631058e-9,_m_unit)));
12815   gen cst_lambdac(_cst_lambdac); // lambdac 0.00242631058 nm
12816   identificateur _cst_f0("_f0_",symbolic(at_unit,makevecteur(2.4179883e14,_Hz_unit)));
12817   gen cst_f0(_cst_f0); //  f0 2.4179883e14Hz
12818   identificateur _cst_lambda0("_lambda0_",symbolic(at_unit,makevecteur(1239.8425e-9,_m_unit)));
12819   gen cst_lambda0(_cst_lambda0); // lambda0 1239.8425_nm
12820   identificateur _cst_muN("_muN_",symbolic(at_unit,makevecteur(5.0507866e-27,_J_unit/_T_unit)));
12821   gen cst_muN(_cst_muN); // muN 5.0507866e-27_J/T
12822   identificateur _cst_muB("_muB_",symbolic(at_unit,makevecteur( 9.2740154e-24,_J_unit/_T_unit)));
12823   gen cst_muB(_cst_muB); // muB 9.2740154e-24 J/T
12824   identificateur _cst_a0("_a0_",symbolic(at_unit,makevecteur(.0529177249e-9,_m_unit)));
12825   gen cst_a0(_cst_a0); // a0 .0529177249_nm
12826   identificateur _cst_Rinfinity("_Rinfinity_",symbolic(at_unit,makevecteur(10973731.534,unitpow(_m_unit,-1))));
12827   gen cst_Rinfinity(_cst_Rinfinity); // Rinf 10973731.534 m^-1
12828   identificateur _cst_Faraday("_Faraday_",symbolic(at_unit,makevecteur(96485.309,_C_unit/_mol_unit)));
12829   gen cst_Faraday(_cst_Faraday); // F 96485.309 C/gmol
12830   identificateur _cst_phi("_phi_",symbolic(at_unit,makevecteur(2.06783461e-15,_Wb_unit)));
12831   gen cst_phi(_cst_phi); // phi 2.06783461e-15 Wb
12832   identificateur _cst_alpha("_alpha_",7.29735308e-3);
12833   gen cst_alpha(_cst_alpha); // alpha 7.29735308e-3
12834   identificateur _cst_mpme("_mpme_",1836.152701);
12835   gen cst_mpme(_cst_mpme); // mpme 1836.152701
12836   identificateur _cst_mp("_mp_",symbolic(at_unit,makevecteur(1.6726231e-27,_kg_unit)));
12837   gen cst_mp(_cst_mp); // mp 1.6726231e-27 kg
12838   identificateur _cst_qme("_qme_",symbolic(at_unit,makevecteur(1.75881962e11,_C_unit/_kg_unit)));
12839   gen cst_qme(_cst_qme); // qme 175881962000 C/kg
12840   identificateur _cst_me("_me_",symbolic(at_unit,makevecteur(9.1093897e-31,_kg_unit)));
12841   gen cst_me(_cst_me); // me 9.1093897e-31 kg
12842   identificateur _cst_qe("_qe_",symbolic(at_unit,makevecteur(1.60217733e-19,_C_unit)));
12843   gen cst_qe(_cst_qe); // q 1.60217733e-19 C
12844   identificateur _cst_hPlanck("_h_",symbolic(at_unit,makevecteur(6.6260755e-34,_J_unit*_s_unit)));
12845   gen cst_hPlanck(_cst_hPlanck); //  h 6.6260755e-34 Js
12846   identificateur _cst_G("_G_",symbolic(at_unit,makevecteur(6.67408e-11,unitpow(_m_unit,3)*unitpow(_s_unit,-2)*unitpow(_kg_unit,-1))));
12847   gen cst_G(_cst_G); // G 6.67408e-11m^3/s^2kg
12848   identificateur _cst_mu0("_mu0_",symbolic(at_unit,makevecteur(1.25663706144e-6,_H_unit/_m_unit)));
12849   gen cst_mu0(_cst_mu0); // mu0 1.25663706144e-6 H/m
12850   identificateur _cst_epsilon0("_epsilon0_",symbolic(at_unit,makevecteur(8.85418781761e-12,_F_unit/_m_unit)));
12851   gen cst_epsilon0(_cst_epsilon0); // eps0 8.85418781761e-12 F/m
12852   identificateur _cst_sigma("_sigma_",symbolic(at_unit,makevecteur( 5.67051e-8,_W_unit*unitpow(_m_unit,-2)*unitpow(_K_unit,-4))));
12853   gen cst_sigma(_cst_sigma); // sigma 5.67051e-8 W/m^2*K^4
12854   identificateur _cst_StdP("_StdP_",symbolic(at_unit,makevecteur(101325.0,_Pa_unit)));
12855   gen cst_StdP(_cst_StdP); // StdP 101.325_kPa
12856   identificateur _cst_StdT("_StdT_",symbolic(at_unit,makevecteur(273.15,_K_unit)));
12857   gen cst_StdT(_cst_StdT); // StdT 273.15_K
12858   identificateur _cst_Rydberg("_R_",symbolic(at_unit,makevecteur(8.31451,_J_unit/_molK_unit)));
12859   gen cst_Rydberg(_cst_Rydberg); // Rydberg 8.31451_J/(gmol*K)
12860   identificateur _cst_Vm("_Vm_",symbolic(at_unit,makevecteur(22.4141,_l_unit/_mol_unit)));
12861   gen cst_Vm(_cst_Vm); // Vm 22.4141_l/gmol
12862   identificateur _cst_kBoltzmann("_k_",symbolic(at_unit,makevecteur(1.380658e-23,_J_unit/_K_unit)));
12863   gen cst_kBoltzmann(_cst_kBoltzmann); // k 1.380658e-23 J/K
12864   identificateur _cst_NA("_NA_",symbolic(at_unit,makevecteur(6.0221367e23,unitpow(_mol_unit,-1))));
12865   gen cst_NA(_cst_NA); // NA 6.0221367e23 1/gmol
12866 #endif // NO_PHYSICAL_CONSTANTS
12867 
maple_root(const gen & g,GIAC_CONTEXT)12868   gen maple_root(const gen & g,GIAC_CONTEXT){
12869     if (g.type!=_VECT || g._VECTptr->size()!=2)
12870       return symbolic(at_maple_root,g);
12871     vecteur & v=*g._VECTptr;
12872 #ifdef KHICAS
12873     return pow(v[0],inv(v[1],contextptr),contextptr);
12874 #else
12875     return pow(v[1],inv(v[0],contextptr),contextptr);
12876 #endif
12877   }
12878   static const char _maple_root_s []="root";
12879 #if defined RTOS_THREADX || defined NSPIRE
12880   static define_unary_function_eval(__maple_root,&maple_root,_maple_root_s);
12881 #else
12882   static const unary_function_eval __maple_root(0,&maple_root,_maple_root_s);
12883 #endif
12884   define_unary_function_ptr( at_maple_root ,alias_at_maple_root ,&__maple_root);
12885 
symb_interrogation(const gen & e1,const gen & e3)12886   gen symb_interrogation(const gen & e1,const gen & e3){
12887     if (e3.is_symb_of_sommet(at_deuxpoints)){
12888       gen & f =e3._SYMBptr->feuille;
12889       if (f.type==_VECT && f._VECTptr->size()==2)
12890 	return symb_when(e1,f._VECTptr->front(),f._VECTptr->back());
12891     }
12892     return symb_when(e1,e3,undef);
12893   }
12894 
first_ascend_sort(const gen & a,const gen & b)12895   bool first_ascend_sort(const gen & a,const gen & b){
12896     gen g=inferieur_strict(a[0],b[0],context0);
12897     if (g.type!=_INT_)
12898       return a[0].islesscomplexthan(b[0]);
12899     return g.val==1;
12900   }
first_descend_sort(const gen & a,const gen & b)12901   bool first_descend_sort(const gen & a,const gen & b){
12902     gen g=superieur_strict(a[0],b[0],context0);
12903     if (g.type!=_INT_)
12904       return !a[0].islesscomplexthan(b[0]);
12905     return g.val==1;
12906   }
12907 
12908 #ifdef NO_UNARY_FUNCTION_COMPOSE
user_operator(const gen & g,GIAC_CONTEXT)12909   gen user_operator(const gen & g,GIAC_CONTEXT){
12910     return gensizeerr(gettext("User operator not available on this architecture"));
12911   }
12912 
12913 #else
12914   // Create an operator with a given syntax
12915   vector<unary_function_ptr> user_operator_list;   // GLOBAL VAR
user_operator(const gen & g,GIAC_CONTEXT)12916   gen user_operator(const gen & g,GIAC_CONTEXT){
12917     if (g.type!=_VECT || g._VECTptr->size()<3)
12918       return gensizeerr(contextptr);
12919     vecteur & v=*g._VECTptr;
12920     // int s=signed(v.size());
12921     if (v[0].type!=_STRNG)
12922       return string2gen(gettext("Operator name must be of type string"),false);
12923     string & ss=*v[0]._STRNGptr;
12924     vector<unary_function_ptr>::iterator it=user_operator_list.begin(),itend=user_operator_list.end();
12925     for (;it!=itend;++it){
12926       if (it->ptr()->s==ss){
12927 	break;
12928       }
12929     }
12930     if (it!=itend){
12931       const unary_function_abstract * ptr0=it->ptr();
12932       const unary_function_user * ptr=dynamic_cast<const unary_function_user *>(ptr0);
12933       if (!ptr)
12934 	return zero;
12935       if (ptr->f==v[1]){
12936 	// if (v[2].type==_INT_ && v[2].subtype==_INT_MUPADOPERATOR && v[2].val==_DELETE_OPERATOR) user_operator_list.erase(it); // does not work...
12937 	return plus_one;
12938       }
12939       return zero;
12940     }
12941     if (v[2].type==_INT_){
12942       int token_value=v[2].val;
12943       unary_function_user * uf;
12944       if (v[2].subtype==_INT_MUPADOPERATOR){
12945 	switch (v[2].val){
12946 	case _POSTFIX_OPERATOR:
12947 	  uf= new unary_function_user (0,v[1],ss,0,0,0);
12948 	  token_value=T_FACTORIAL; // like factorial
12949 	  break;
12950 	case _PREFIX_OPERATOR:
12951 	  uf=new unary_function_user(0,v[1],ss,0,0,0);
12952 	  token_value=T_NOT; // like not
12953 	  break;
12954 	case _BINARY_OPERATOR:
12955 	  uf = new unary_function_user (0,v[1],ss);
12956 	  token_value=T_FOIS; // like *
12957 	  break;
12958 	default:
12959 	  return zero;
12960 	}
12961       }
12962       else
12963 	// non mupad syntax, v[2] is input_parser.yy token value
12964 	uf = new unary_function_user(0,v[1],ss);
12965       unary_function_ptr u(uf);
12966       // cout << symbolic(u,makevecteur(1,2)) << '\n';
12967       user_operator_list.push_back(u);
12968       bool res=lexer_functions_register(u,ss.c_str(),token_value);
12969       if (res){
12970 #ifdef HAVE_SIGNAL_H_OLD
12971 	if (!child_id)
12972 	  _signal(symb_quote(symbolic(at_user_operator,g)),contextptr);
12973 #endif
12974 	return plus_one;
12975       }
12976       user_operator_list.pop_back();
12977       delete uf;
12978     }
12979     return zero;
12980   }
12981 #endif // NO_UNARY_FUNCTION_COMPOSE
12982   static const char _user_operator_s []="user_operator";
12983   static define_unary_function_eval (__user_operator,&user_operator,_user_operator_s);
12984   define_unary_function_ptr( at_user_operator ,alias_at_user_operator ,&__user_operator);
12985 
12986   gen current_folder_name;
12987 
getfold(const gen & g)12988   gen getfold(const gen & g){
12989     if (is_zero(g))
12990       return string2gen("main",false);
12991     return g;
12992   }
12993 
_SetFold(const gen & g,GIAC_CONTEXT)12994   gen _SetFold(const gen & g,GIAC_CONTEXT){
12995     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
12996     if (!is_zero(g) && g.type!=_IDNT)
12997       return gensizeerr(contextptr);
12998     bool ok=is_zero(g);
12999     if (g.type==_IDNT && g._IDNTptr->value && g._IDNTptr->value->type==_VECT && g._IDNTptr->value->subtype==_FOLDER__VECT)
13000       ok=true;
13001     if ( ok || (g.type==_IDNT && g._IDNTptr->id_name && (strcmp(g._IDNTptr->id_name,"main")==0|| strcmp(g._IDNTptr->id_name,"home")) ) ){
13002       gen res=current_folder_name;
13003       current_folder_name=g;
13004 #ifdef HAVE_SIGNAL_H_OLD
13005       if (!child_id)
13006 	_signal(symb_quote(symbolic(at_SetFold,g)),contextptr);
13007 #endif
13008       return getfold(res);
13009     }
13010     return gensizeerr(gettext("Non existent Folder"));
13011   }
13012   static const char _SetFold_s []="SetFold";
13013   static define_unary_function_eval2_quoted (__SetFold,&_SetFold,_SetFold_s,&printastifunction);
13014   define_unary_function_ptr5( at_SetFold ,alias_at_SetFold,&__SetFold,_QUOTE_ARGUMENTS,T_RETURN);
13015 
13016 
printaspiecewise(const gen & feuille,const char * sommetstr,GIAC_CONTEXT)13017   static string printaspiecewise(const gen & feuille,const char * sommetstr,GIAC_CONTEXT){
13018     // if ( feuille.type!=_VECT || feuille._VECTptr->empty() || abs_calc_mode(contextptr)!=38)
13019       return string(sommetstr)+('('+feuille.print(contextptr)+')');
13020 #if 0
13021     vecteur & v = *feuille._VECTptr;
13022     string res("CASE");
13023     int s=int(v.size());
13024     for (int i=0;i<s/2;i++){
13025       res += " IF ";
13026       res += v[2*i].print(contextptr);
13027       res += " THEN ";
13028       res += printasinnerbloc(v[2*i+1],contextptr);
13029       res += " END";
13030     }
13031     if (s%2){
13032       res += " DEFAULT ";
13033       res += printasinnerbloc(v[s-1],contextptr);
13034     }
13035     return res+" END";
13036 #endif
13037   }
_piecewise(const gen & g,GIAC_CONTEXT)13038   gen _piecewise(const gen & g,GIAC_CONTEXT){
13039     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
13040     // evaluate couples of condition/expression, like in a case
13041     if (g.type!=_VECT)
13042       return g;
13043     vecteur & v =*g._VECTptr;
13044     int s=int(v.size());
13045     gen test;
13046     for (int i=0;i<s/2;++i){
13047       test=v[2*i];
13048       test=equaltosame(test.eval(eval_level(contextptr),contextptr)).eval(eval_level(contextptr),contextptr);
13049       test=test.evalf_double(eval_level(contextptr),contextptr);
13050       if ( (test.type!=_DOUBLE_) && (test.type!=_CPLX) )
13051 	return symbolic(at_piecewise,g.eval(eval_level(contextptr),contextptr));
13052       if (is_zero(test))
13053 	continue;
13054       return v[2*i+1].eval(eval_level(contextptr),contextptr);
13055     }
13056     if (s%2)
13057       return v[s-1].eval(eval_level(contextptr),contextptr);
13058     return undeferr(gettext("No case applies"));
13059   }
13060   static const char _piecewise_s []="piecewise";
13061   static define_unary_function_eval2_quoted (__piecewise,&_piecewise,_piecewise_s,&printaspiecewise);
13062   define_unary_function_ptr5( at_piecewise ,alias_at_piecewise,&__piecewise,_QUOTE_ARGUMENTS,true);
13063 
13064   static const char _PIECEWISE_s []="PIECEWISE";
13065   static define_unary_function_eval2_quoted (__PIECEWISE,&_piecewise,_PIECEWISE_s,&printaspiecewise);
13066   define_unary_function_ptr5( at_PIECEWISE ,alias_at_PIECEWISE,&__PIECEWISE,_QUOTE_ARGUMENTS,true);
13067 
_geo2d(const gen & g,GIAC_CONTEXT)13068   gen _geo2d(const gen & g,GIAC_CONTEXT){
13069     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
13070     return g;
13071   }
13072   static const char _geo2d_s []="geo2d";
13073   static define_unary_function_eval (__geo2d,&_geo2d,_geo2d_s);
13074   define_unary_function_ptr5( at_geo2d ,alias_at_geo2d,&__geo2d,0,true);
13075 
13076   static const char _geo3d_s []="geo3d";
13077   static define_unary_function_eval (__geo3d,&_geo2d,_geo3d_s);
13078   define_unary_function_ptr5( at_geo3d ,alias_at_geo3d,&__geo3d,0,true);
13079 
13080   static const char _spreadsheet_s []="spreadsheet";
13081   static define_unary_function_eval (__spreadsheet,&_geo2d,_spreadsheet_s);
13082   define_unary_function_ptr5( at_spreadsheet ,alias_at_spreadsheet,&__spreadsheet,0,true);
13083 
print_program_syntax(int maple_mode)13084   std::string print_program_syntax(int maple_mode){
13085     string logs;
13086     switch (maple_mode){
13087     case 0:
13088       logs="xcas";
13089       break;
13090     case 1:
13091       logs="maple";
13092       break;
13093     case 2:
13094       logs="mupad";
13095       break;
13096     case 3:
13097       logs="ti";
13098       break;
13099     default:
13100       logs=print_INT_(maple_mode);
13101     }
13102     return logs;
13103   }
13104 
_threads_allowed(const gen & g,GIAC_CONTEXT)13105   gen _threads_allowed(const gen & g,GIAC_CONTEXT){
13106     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
13107     if (is_zero(g))
13108       threads_allowed=false;
13109     else
13110       threads_allowed=true;
13111     return threads_allowed;
13112   }
13113   static const char _threads_allowed_s []="threads_allowed";
13114   static define_unary_function_eval (__threads_allowed,&_threads_allowed,_threads_allowed_s);
13115   define_unary_function_ptr5( at_threads_allowed ,alias_at_threads_allowed,&__threads_allowed,0,true);
13116 
_mpzclass_allowed(const gen & g,GIAC_CONTEXT)13117   gen _mpzclass_allowed(const gen & g,GIAC_CONTEXT){
13118     if ( g.type==_STRNG &&  g.subtype==-1) return  g;
13119     if (is_zero(g))
13120       mpzclass_allowed=false;
13121     else
13122       mpzclass_allowed=true;
13123     return mpzclass_allowed;
13124   }
13125   static const char _mpzclass_allowed_s []="mpzclass_allowed";
13126   static define_unary_function_eval (__mpzclass_allowed,&_mpzclass_allowed,_mpzclass_allowed_s);
13127   define_unary_function_ptr5( at_mpzclass_allowed ,alias_at_mpzclass_allowed,&__mpzclass_allowed,0,true);
13128 
whentopiecewise(const gen & g,GIAC_CONTEXT)13129   gen whentopiecewise(const gen & g,GIAC_CONTEXT){
13130     return symbolic(at_piecewise,g);
13131   }
13132   const alias_type when_tab_alias[]={(alias_type)&__when,0};
13133   const unary_function_ptr * const when_tab=(const unary_function_ptr * const)when_tab_alias;
13134   const gen_op_context when2piecewise_tab[]={whentopiecewise,0};
when2piecewise(const gen & g,GIAC_CONTEXT)13135   gen when2piecewise(const gen & g,GIAC_CONTEXT){
13136     return subst(g,when_tab,when2piecewise_tab,false,contextptr);
13137     /*
13138     vector< gen_op_context > when2piecewise_v(1,whentopiecewise);
13139     vector< const unary_function_ptr *> when_v(1,at_when);
13140     return subst(g,when_v,when2piecewise_v,false,contextptr);
13141     */
13142   }
13143 
piecewisetowhen(const gen & g,GIAC_CONTEXT)13144   gen piecewisetowhen(const gen & g,GIAC_CONTEXT){
13145     if (g.type!=_VECT)
13146       return g;
13147     vecteur v = *g._VECTptr;
13148     int s=int(v.size());
13149     if (s==1)
13150       return gensizeerr(contextptr);
13151     if (s>=2 && v[0].type==_INT_){
13152       if (v[0].val)
13153 	return v[1];
13154       else
13155 	return s==2?bounded_function(contextptr):piecewisetowhen(vecteur(v.begin()+2,v.end()),contextptr);
13156     }
13157     if (s==2){
13158       v.push_back(0); // undef does not work
13159       return symbolic(at_when,gen(v,_SEQ__VECT));
13160     }
13161     if (s==3)
13162       return symbolic(at_when,g);
13163     gen tmp=piecewisetowhen(vecteur(v.begin()+2,v.end()),contextptr);
13164     return symbolic(at_when,gen(makevecteur(v[0],v[1],tmp),_SEQ__VECT));
13165   }
13166   const alias_type piecewise_tab_alias[]={alias_at_piecewise,0};
13167   const unary_function_ptr * const piecewise_tab=(const unary_function_ptr * const)piecewise_tab_alias;
13168   const gen_op_context piecewise2when_tab[]={piecewisetowhen,0};
piecewise2when(const gen & g,GIAC_CONTEXT)13169   gen piecewise2when(const gen & g,GIAC_CONTEXT){
13170     return subst(g,piecewise_tab,piecewise2when_tab,false,contextptr);
13171     /*
13172     vector< const unary_function_ptr *> piecewise_v(1,at_piecewise);
13173     vector< gen_op_context > piecewise2when_v(1,piecewisetowhen);
13174     return subst(g,piecewise_v,piecewise2when_v,false,contextptr);
13175     */
13176   }
13177 
whentosign(const gen & g,GIAC_CONTEXT)13178   gen whentosign(const gen & g,GIAC_CONTEXT){
13179     if (g.type!=_VECT || g._VECTptr->size()!=3)
13180       return gensizeerr(contextptr);
13181     vecteur v = *g._VECTptr;
13182     if (v[0].is_symb_of_sommet(at_not))
13183       return when2sign(makevecteur(v[0]._SYMBptr->feuille,v[2],v[1]),contextptr);
13184     if (v[0].is_symb_of_sommet(at_and) && v[0]._SYMBptr->feuille.type==_VECT){
13185       vecteur vand=*v[0]._SYMBptr->feuille._VECTptr;
13186       if (vand.size()==2)
13187 	return whentosign(makevecteur(vand[0],whentosign(makevecteur(vand[1],v[1],v[2]),contextptr),v[2]),contextptr);
13188       if (vand.size()>2){
13189 	gen vandlast=vand.back();
13190 	vand.pop_back();
13191 	return whentosign(makevecteur(vandlast,whentosign(makevecteur(symbolic(at_and,vand),v[1],v[2]),contextptr),v[2]),contextptr);
13192       }
13193     }
13194     if (v[0].is_symb_of_sommet(at_ou) && v[0]._SYMBptr->feuille.type==_VECT){
13195       vecteur vor=*v[0]._SYMBptr->feuille._VECTptr;
13196       if (vor.size()==2)
13197 	return whentosign(makevecteur(vor[0],v[1],whentosign(makevecteur(vor[1],v[1],v[2]),contextptr)),contextptr);
13198       if (vor.size()>2){
13199 	gen vorlast=vor.back();
13200 	vor.pop_back();
13201 	return whentosign(makevecteur(vorlast,v[1],whentosign(makevecteur(symbolic(at_and,vor),v[1],v[2]),contextptr)),contextptr);
13202       }
13203     }
13204     if (is_equal(v[0]) || v[0].is_symb_of_sommet(at_same)){
13205       *logptr(contextptr) << gettext("Assuming false condition ") << v[0].print(contextptr) << '\n';
13206       return v[2];
13207     }
13208     if (v[0].is_symb_of_sommet(at_different)){
13209       *logptr(contextptr) << gettext("Assuming true condition ") << v[0].print(contextptr) << '\n';
13210       return v[1];
13211     }
13212     bool ok=false;
13213     if (v[0].is_symb_of_sommet(at_superieur_strict) || v[0].is_symb_of_sommet(at_superieur_egal)){
13214       v[0]=v[0]._SYMBptr->feuille[0]-v[0]._SYMBptr->feuille[1];
13215       ok=true;
13216     }
13217     if (!ok && (v[0].is_symb_of_sommet(at_inferieur_strict) || v[0].is_symb_of_sommet(at_inferieur_egal)) ){
13218       v[0]=v[0]._SYMBptr->feuille[1]-v[0]._SYMBptr->feuille[0];
13219       ok=true;
13220     }
13221     if (!ok)
13222       return gensizeerr(gettext("Unable to handle when condition ")+v[0].print(contextptr));
13223     return symbolic(at_sign,v[0])*(v[1]-v[2])/2+(v[1]+v[2])/2;
13224   }
13225   const gen_op_context when2sign_tab[]={whentosign,0};
when2sign(const gen & g,GIAC_CONTEXT)13226   gen when2sign(const gen & g,GIAC_CONTEXT){
13227     if (equalposcomp(lidnt(g),unsigned_inf))
13228       *logptr(contextptr) << gettext("when2sign does not work properly with infinities. Replace inf by Inf and run limit after.") << '\n';
13229     return subst(g,when_tab,when2sign_tab,false,contextptr);
13230     /*
13231     vector< gen_op_context > when2sign_v(1,whentosign);
13232     vector< const unary_function_ptr *> when_v(1,at_when);
13233     return subst(g,when_v,when2sign_v,false,contextptr);
13234     */
13235   }
13236 
iftetowhen(const gen & g,GIAC_CONTEXT)13237   gen iftetowhen(const gen & g,GIAC_CONTEXT){
13238     return symbolic(at_when,g);
13239   }
13240   const alias_type ifte_tab_alias[]={(alias_type)&__ifte,0};
13241   const unary_function_ptr * const ifte_tab=(const unary_function_ptr * const)ifte_tab_alias;
13242   const gen_op_context ifte2when_tab[]={iftetowhen,0};
ifte2when(const gen & g,GIAC_CONTEXT)13243   gen ifte2when(const gen & g,GIAC_CONTEXT){
13244     return subst(g,ifte_tab,ifte2when_tab,false,contextptr);
13245   }
13246 
13247   // test if m(i) is an array index: that will not be the case if
13248   // i is an _IDNT or a list of _IDNT
13249   //
is_array_index(const gen & m,const gen & i,GIAC_CONTEXT)13250   bool is_array_index(const gen & m,const gen & i,GIAC_CONTEXT){
13251     if (i.type==_VECT){
13252       for (unsigned j=0;j<i._VECTptr->size();++j){
13253 	gen g=(*i._VECTptr)[j];
13254 	if (g.type==_IDNT || g.is_symb_of_sommet(at_equal) || g.is_symb_of_sommet(at_deuxpoints) || g.is_symb_of_sommet(at_sto))
13255 	  continue;
13256 	return true;
13257       }
13258     }
13259     else {
13260       if (i.type!=_IDNT)
13261 	return true;
13262     }
13263     return false;
13264     // commented otherwise is_array_index inside a program would depend on the global
13265     // value of m
13266     //gen mv=eval(m,1,contextptr);
13267     //return mv.type==_VECT;
13268   }
13269 
_autosimplify(const gen & g,GIAC_CONTEXT)13270   gen _autosimplify(const gen & g,GIAC_CONTEXT){
13271     if (is_zero(g) && g.type!=_VECT){
13272       autosimplify("Nop",contextptr);
13273       return 1;
13274     }
13275     if (is_one(g)){
13276       autosimplify("regroup",contextptr);
13277       return 1;
13278     }
13279     if (g==2){
13280       autosimplify("simplify",contextptr);
13281       return 1;
13282     }
13283     if (g.type!=_IDNT && g.type!=_FUNC && g.type!=_SYMB)
13284       return gen(autosimplify(contextptr),contextptr);
13285     autosimplify(g.print(contextptr),contextptr);
13286     return 1;
13287   }
13288   static const char _autosimplify_s []="autosimplify";
13289   static define_unary_function_eval (__autosimplify,&_autosimplify,_autosimplify_s);
13290   define_unary_function_ptr5( at_autosimplify ,alias_at_autosimplify,&__autosimplify,0,true);
13291 
_struct_dot(const gen & g,GIAC_CONTEXT)13292   gen _struct_dot(const gen & g,GIAC_CONTEXT){
13293     if (g.type!=_VECT)
13294       return gensizeerr(contextptr);
13295     vecteur w=*g._VECTptr;
13296     size_t ws=w.size();
13297     if (ws!=2)
13298       return gensizeerr(contextptr);
13299     gen a=w[0],b=w[1],m;
13300     if (b.type==_IDNT)
13301       b=eval(b,1,contextptr);
13302     if (b.type==_SYMB){
13303       unary_function_ptr u=b._SYMBptr->sommet;
13304       const gen & f=b._SYMBptr->feuille;
13305       if (u==at_of && f.type==_VECT && f._VECTptr->size()==2){
13306 	gen s=eval(f._VECTptr->front(),1,contextptr);
13307 	if (s.type==_FUNC)
13308 	  u=*s._FUNCptr;
13309       }
13310       if (equalposcomp(plot_sommets,u) || u==at_show || u==at_clear || u==at_scatterplot || u==at_diagrammebatons)
13311 	return eval(b,1,contextptr);
13312     }
13313     if (b.type==_FUNC)
13314       b=symbolic(*b._FUNCptr,gen(vecteur(0),_SEQ__VECT));
13315     if (a.type==_IDNT){
13316       gen tmp=eval(a,1,contextptr);
13317       if (tmp==a){ // try to eval at global level
13318 	tmp=global_eval(tmp,1);
13319       }
13320       if (tmp.type==_MAP && b.is_symb_of_sommet(at_of)){
13321 	const gen & f =b._SYMBptr->feuille;
13322 	if (f.type==_VECT && f._VECTptr->size()==2){
13323 	  const vecteur & v =*f._VECTptr;
13324 	  if (v.size()==2 && v.front().type==_IDNT && strcmp(v.front()._IDNTptr->id_name,"update")==0){
13325 	    gen m=eval(v.back(),1,contextptr);
13326 	    if (m.type==_MAP){
13327 	      tmp._MAPptr->insert(m._MAPptr->begin(),m._MAPptr->end());
13328 	      return tmp;
13329 	    }
13330 	  }
13331 	}
13332       }
13333       if (tmp.type==_IDNT && (strcmp(tmp._IDNTptr->id_name,"numpy")==0 || strcmp(tmp._IDNTptr->id_name,"pylab")==0 || strcmp(tmp._IDNTptr->id_name,"matplotlib")==0)){
13334 	if (b.type==_SYMB){
13335 	  gen w1=eval(w[1],1,contextptr);
13336 	  // at_equal test added for e.g. matplotlib.xlim(-5,5)
13337 	  if (w1==at_float || w1==at_real || w1.is_symb_of_sommet(at_equal))
13338 	    return w1;
13339 	  tmp=b._SYMBptr->feuille;
13340 	  tmp=eval(tmp,eval_level(contextptr),contextptr);
13341 	  tmp=evalf_double(tmp,1,contextptr);
13342 	  if (b.is_symb_of_sommet(at_dot))
13343 	    return _prod(tmp,contextptr);
13344 	  return b._SYMBptr->sommet(tmp,contextptr);
13345 	}
13346 	gen tmp=eval(b,1,contextptr);
13347 	tmp=evalf_double(tmp,1,contextptr);
13348 	return tmp;
13349       }
13350       if (tmp.type==_IDNT &&
13351 	  (strcmp(tmp._IDNTptr->id_name,"math")==0 ||
13352 	   strcmp(tmp._IDNTptr->id_name,"cmath")==0 ||
13353 	   strcmp(tmp._IDNTptr->id_name,"kandinsky")==0)
13354 	  ){
13355 	if (b.type==_SYMB){
13356 	  tmp=eval(b._SYMBptr->feuille,eval_level(contextptr),contextptr);
13357 	  return b._SYMBptr->sommet(tmp,contextptr);
13358 	}
13359       }
13360       if (ckmatrix(tmp)){
13361 	if (w[1].type==_IDNT){
13362 	  const char * ch =w[1]._IDNTptr->id_name;
13363 	  if (ch){
13364 	    if (ch[0]=='T')
13365 	      return mtran(*tmp._VECTptr);
13366 	    if (ch[0]=='H')
13367 	      return _trn(tmp,contextptr);
13368 	    if (ch[0]=='I')
13369 	      return minv(*tmp._VECTptr,contextptr);
13370 	  }
13371 	}
13372 	if (w[1].is_symb_of_sommet(at_of))
13373 	  m=tmp;
13374       }
13375       else {
13376 	if (tmp.type==_VECT && w[1].type==_IDNT){
13377 	  const char * ch =w[1]._IDNTptr->id_name;
13378 	  if (ch){
13379 	    if (ch[0]=='T')
13380 	      return _tran(tmp,contextptr);
13381 	  }
13382 	}
13383       }
13384       if (tmp.type==_VECT && b.type==_SYMB){
13385 	// check tmp size, workaround for progs with l:=[]; l.append(1);
13386 	// where the code would self modify itself
13387 	// disabled, sto should now do a copy of constant lists
13388 	if (b._SYMBptr->sommet==at_append
13389 	    //&& tmp._VECTptr->size()>=8
13390 	    ){
13391 	  tmp._VECTptr->push_back(eval(b._SYMBptr->feuille,eval_level(contextptr),contextptr));
13392 	  return tmp;
13393 	}
13394 	if ( (b._SYMBptr->sommet==at_suppress || b._SYMBptr->sommet==at_clear) && b._SYMBptr->feuille.type==_VECT && b._SYMBptr->feuille._VECTptr->empty()){
13395 	  tmp._VECTptr->clear();
13396 	  return tmp;
13397 	}
13398       }
13399       if (tmp.type==_FUNC)
13400 	a=tmp;
13401     }
13402     if (b.type!=_SYMB)
13403       return _prod(eval(g,eval_level(contextptr),contextptr),contextptr);
13404     gen f=b;
13405     unary_function_ptr u=b._SYMBptr->sommet;
13406     bool cmd=false;
13407     if (a!=at_random){
13408       f=b._SYMBptr->feuille;
13409       if (u==at_of && f.type==_VECT && f._VECTptr->size()==2){
13410 	gen fn=eval(f._VECTptr->front(),1,contextptr);
13411 	if (fn.type==_FUNC){
13412 	  cmd=true;
13413 	  f=f._VECTptr->back();
13414 	  u=*fn._FUNCptr;
13415 	  b=symbolic(u,f);
13416 	}
13417       }
13418       vecteur v(1,f);
13419       if (f.type==_VECT && f.subtype==_SEQ__VECT)
13420 	v=*f._VECTptr;
13421       if (v.empty())
13422 	f=eval(a,1,contextptr);
13423       else {
13424 	if (u==at_remove)
13425 	  v.push_back(a);
13426 	else {
13427 	  if (!cmd && ckmatrix(m) && v.front().type==_IDNT){ // ex: m.reshape(2,4)
13428 	    b=v.front();
13429 	    v.front()=m;
13430 	    v=makevecteur(b,gen(v,_SEQ__VECT));
13431 	  }
13432 	  else {
13433 	    if (u==at_of && v.size()==2){
13434 	      if (v.back().type==_VECT){
13435 		vecteur w=*v.back()._VECTptr;
13436 		w.insert(w.begin(),a);
13437 		v=makevecteur(v.front(),gen(w,_SEQ__VECT));
13438 	      }
13439 	      else
13440 		v=makevecteur(v.front(),makesequence(a,v.back()));
13441 	    }
13442 	    else
13443 	      v.insert(v.begin(),a);
13444 	  }
13445 	}
13446 	f=gen(v,f.type==_VECT?f.subtype:_SEQ__VECT);
13447       }
13448       f=symbolic(u,f);
13449     }
13450     f=eval(f,eval_level(contextptr),contextptr);
13451     if ((a.type==_IDNT || a.type==_SYMB) && (u==at_revlist || u==at_reverse || u==at_sort || u==at_append || u==at_prepend || u==at_concat || u==at_extend || u==at_rotate || u==at_shift || u==at_suppress || u==at_remove || u==at_insert ))
13452       return sto(f,a,contextptr);
13453     return f;
13454   }
13455   static const char _struct_dot_s []=".";
13456   static define_unary_function_eval4_index (175,__struct_dot,&_struct_dot,_struct_dot_s,&printsommetasoperator,&texprintsommetasoperator);
13457   define_unary_function_ptr5( at_struct_dot ,alias_at_struct_dot,&__struct_dot,_QUOTE_ARGUMENTS,true);
13458 
_giac_assert(const gen & args,GIAC_CONTEXT)13459   gen _giac_assert(const gen & args,GIAC_CONTEXT){
13460     gen test=args;
13461     string msg(gettext("assert failure: ")+args.print(contextptr));
13462     if (args.type==_VECT && args.subtype==_SEQ__VECT && args._VECTptr->size()==2){
13463       test=args._VECTptr->back();
13464       if (test.type==_STRNG) msg=*test._STRNGptr; else msg=test.print(contextptr);
13465       test=args._VECTptr->front();
13466     }
13467     test=equaltosame(test);
13468     int evallevel=eval_level(contextptr);
13469     test=equaltosame(test).eval(evallevel,contextptr);
13470     if (!is_integer(test))
13471       test=test.evalf_double(evallevel,contextptr);
13472     if (!is_integral(test) || test.val!=1)
13473       return gensizeerr(msg);
13474     return 1;
13475   }
13476   static const char _giac_assert_s []="assert";
13477   static define_unary_function_eval_quoted (__giac_assert,&_giac_assert,_giac_assert_s);
13478   define_unary_function_ptr5( at_giac_assert ,alias_at_giac_assert,&__giac_assert,_QUOTE_ARGUMENTS,T_RETURN);
13479 
_index(const gen & args,GIAC_CONTEXT)13480   gen _index(const gen & args,GIAC_CONTEXT){
13481     if (args.type!=_VECT || args._VECTptr->size()!=2)
13482       return gensizeerr(contextptr);
13483     gen l;
13484     if (args._VECTptr->front().type==_STRNG)
13485       l=_find(args,contextptr);
13486     else
13487       l=_find(makesequence(args._VECTptr->back(),args._VECTptr->front()),contextptr);
13488     if (l.type!=_VECT)
13489       return l;
13490     if (l._VECTptr->empty())
13491       return gensizeerr(contextptr);
13492     return l._VECTptr->front();
13493   }
13494   static const char _index_s []="index";
13495   static define_unary_function_eval (__index,&_index,_index_s);
13496   define_unary_function_ptr5( at_index ,alias_at_index,&__index,0,true);
13497 
_giac_bool(const gen & args,GIAC_CONTEXT)13498   gen _giac_bool(const gen & args,GIAC_CONTEXT){
13499     bool b=args.type==_VECT?args._VECTptr->empty():is_exactly_zero(args);
13500     gen r=b?0:1;
13501     r.subtype=_INT_BOOLEAN;
13502     return r;
13503   }
13504   static const char _giac_bool_s []="bool";
13505   static define_unary_function_eval (__giac_bool,&_giac_bool,_giac_bool_s);
13506   define_unary_function_ptr5( at_giac_bool ,alias_at_giac_bool,&__giac_bool,0,true);
13507 
13508 
_heapify(const gen & args,GIAC_CONTEXT)13509   gen _heapify(const gen & args,GIAC_CONTEXT){
13510     if (args.type!=_VECT)
13511       return gensizeerr(contextptr);
13512     iterateur it=args._VECTptr->begin(),itend=args._VECTptr->end();
13513     gen f=at_inferieur_strict_sort;
13514     if (args.type==_SEQ__VECT && itend-it==2 && it->type==_VECT){
13515       f=*it;
13516       it=f._VECTptr->begin();
13517       itend=f._VECTptr->end();
13518       f=args._VECTptr->back();
13519     }
13520     make_heap(it,itend,gen_sort(f,contextptr));
13521     return 1;
13522   }
13523   static const char _heapify_s []="heapify";
13524   static define_unary_function_eval (__heapify,&_heapify,_heapify_s);
13525   define_unary_function_ptr5( at_heapify ,alias_at_heapify,&__heapify,0,true);
13526 
_heappop(const gen & args,GIAC_CONTEXT)13527   gen _heappop(const gen & args,GIAC_CONTEXT){
13528     if (args.type!=_VECT)
13529       return gensizeerr(contextptr);
13530     gen v=args;
13531     iterateur it=args._VECTptr->begin(),itend=args._VECTptr->end();
13532     gen f=at_inferieur_strict_sort;
13533     if (args.type==_SEQ__VECT && itend-it==2 && it->type==_VECT){
13534       v=*it;
13535       it=v._VECTptr->begin();
13536       itend=v._VECTptr->end();
13537       f=args._VECTptr->back();
13538     }
13539     if (itend==it)
13540       return gendimerr(contextptr);
13541     pop_heap(it,itend,gen_sort(f,contextptr));
13542     v._VECTptr->pop_back();
13543     return *itend;
13544   }
13545   static const char _heappop_s []="heappop";
13546   static define_unary_function_eval (__heappop,&_heappop,_heappop_s);
13547   define_unary_function_ptr5( at_heappop ,alias_at_heappop,&__heappop,0,true);
13548 
_heappush(const gen & args,GIAC_CONTEXT)13549   gen _heappush(const gen & args,GIAC_CONTEXT){
13550     if (args.type!=_VECT)
13551       return gensizeerr(contextptr);
13552     gen f=at_inferieur_strict_sort;
13553     if (args.type!=_VECT || args._VECTptr->size()<2)
13554       return gensizeerr(contextptr);
13555     vecteur & v=*args._VECTptr;
13556     if (v.size()==3) f=v[2];
13557     if (v[0].type!=_VECT) return gensizeerr(contextptr);
13558     v[0]._VECTptr->push_back(v[1]);
13559     iterateur it=v[0]._VECTptr->begin(),itend=v[0]._VECTptr->end();
13560     push_heap(it,itend,gen_sort(f,contextptr));
13561     return v[0];
13562   }
13563   static const char _heappush_s []="heappush";
13564   static define_unary_function_eval (__heappush,&_heappush,_heappush_s);
13565   define_unary_function_ptr5( at_heappush ,alias_at_heappush,&__heappush,0,true);
13566 
13567 
13568 #ifndef NO_NAMESPACE_GIAC
13569 } // namespace giac
13570 #endif // ndef NO_NAMESPACE_GIAC
13571