Scicos: fix the "" + [] and 1 + []
[scilab.git] / scilab / modules / scicos / macros / scicos_scicos / c_pass2.sci
1 //  Scicos
2 //
3 //  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 //
19 // See the file ../license.txt
20 //
21
22 function cpr=c_pass2(bllst,connectmat,clkconnect,cor,corinv,flag)
23     // cor    ; correspondence table with initial block ordering
24     //
25     // bllst: list with nblk elts where nblk denotes number of blocks.
26     //        Each element must be a list with 16 elements:
27     //          1- a list containing function name and function type
28     //          2- vector of number of inputs
29     //          3- vector of number of outputs
30     //          4- vector of number of clock inputs
31     //          5- vector of number of clock outputs
32     //          6- vector (column) of continuous initial condition
33     //          7- vector (column) of discrete initial condition
34     //          8- vector (column) of real parameters
35     //          9- vector (column) of integer parameters
36     //          10- string: 'l' for synchro (ifthenelse,eselect) or 'm'
37     //          (memo) or 'x' for blocks that need to be called during
38     //          integration even in the absence of state (only if with workspace)
39     //          11- vector of size <number of clock outputs> including
40     //              preprogrammed event firing times (<0 if no firing)
41     //          12- boolean vector (column): 1:nin entry for dependence on u,
42     //          last on t
43     //          13- block label
44     //          14- number of zero crossings
45     //          15- number of modes
46     //          16- empty list (equation for modelica blocks)
47     //
48     // connectmat: nx4 matrix. Each row contains, in order, the block
49     //             number and the port number of an outgoing scicopath,
50     //             and the block number and the port number of the target
51     //             ingoing scicopath.
52     //
53     // clkconnect: same as connectmat but for clock scicopaths.
54     //
55     // define some constants
56     if argn(2) <6 then flag="verbose",end
57     show_trace=%f
58     if show_trace then mprintf("c_pass1:\t%f\n", timer()),end
59
60     show_pause=%f;
61     show_comment=%f;
62
63     if bllst==list() then
64         messagebox(_("No block can be activated"),"modal","error")
65         cpr=list()
66         ok=%f;
67         return
68     end
69
70     //correction of clkconnect.. Must be done before
71     clkconnect(find(clkconnect(:,2)==0),2)=1;
72
73
74
75
76     if exists("%scicos_solver")==0 then %scicos_solver=0,end
77
78     clkptr=1,cliptr=1,typ_l=[],
79     nblk=size(bllst)
80
81     //take care of the heritage
82     [bllst,inplnk,outlnk,clkptr,cliptr,inpptr,outptr,dep_u,dep_uptr,dep_t,..
83     typ_l,typ_r,typ_m,tblock,typ_cons,typ_zx,ok]=mini_extract_info(bllst,..
84     connectmat,clkconnect)
85     if show_trace then mprintf("c_pass20:\t%f\n", timer()),end
86     if ~ok then
87         cpr=list()
88         return
89     end
90     [outoin,outoinptr]=conn_mat(inpptr,outptr,inplnk,outlnk)
91
92     [critev]=critical_events(connectmat,clkconnect,dep_t,typ_r,..
93     typ_l,typ_zx,outoin,outoinptr,clkptr)
94     [clkconnect,exe_cons]=pak_ersi(connectmat,clkconnect,typ_r,..
95     typ_l,outoin,outoinptr,tblock,typ_cons,clkptr)
96
97
98     [ordclk,ordptr,cord,typ_l,clkconnect,connectmat,bllst,dep_t,dep_u,..
99     dep_uptr,corinv,clkptr,cliptr,critev,ok]=paksazi2(typ_l,clkconnect,..
100     connectmat,bllst,dep_t,dep_u,dep_uptr,corinv,clkptr,cliptr,critev)
101
102     if ~ok then
103         cpr=list()
104         return
105     end
106
107     if show_pause then
108         mprintf("fin de paksazi")
109         pause
110     end
111
112     if show_trace then mprintf("c_pass31:\t%f\n", timer()),end
113
114     //extract various info from bllst
115     [lnksz,lnktyp,inplnk,outlnk,clkptr,cliptr,inpptr,outptr,xptr,zptr,..
116     ozptr,typ_mod,rpptr,ipptr,opptr,xc0,xcd0,xd0,oxd0,rpar,..
117     ipar,opar,typ_z,typ_x,typ_m,funs,funtyp,initexe,labels,uids,..
118     bexe,boptr,blnk,blptr,ok]=extract_info(bllst,connectmat,clkconnect,typ_l);
119     typ_z0=typ_z;
120
121
122
123     if ~ok then
124         messagebox(_("Problem in port size or type."),"modal","error");
125         cpr=list()
126         return,
127     end
128
129     if show_trace then mprintf("c_pass41:\t%f\n", timer()),end
130
131     //form a matrix which gives destinations of each block
132     [outoin,outoinptr]=conn_mat(inpptr,outptr,inplnk,outlnk)
133     [evoutoin,evoutoinptr]=synch_clkconnect(typ_l,clkconnect)
134     //
135     if show_trace then mprintf("c_pass50:\t%f\n", timer()),end
136
137     [execlk_cons]=discard(clkptr,cliptr,clkconnect,exe_cons)
138
139     clkconnect=[];exe_cons=[]
140
141     if show_trace then mprintf("c_pass501:\t%f\n", timer()),end
142
143     // Set execution scheduling tables
144     [ordclk,iord,oord,zord,typ_z,ok]=scheduler(inpptr,outptr,clkptr,execlk_cons,..
145     outoin,outoinptr,evoutoin,evoutoinptr,typ_z,typ_x,typ_l,bexe,boptr,blnk,blptr,..
146     ordclk,ordptr,cord,dep_t,dep_u,dep_uptr);
147
148     if ~ok then
149         cpr=list()
150         return,
151     end
152
153     if show_trace then mprintf("c_pass51:\t%f\n", timer()),end
154     //form scicos arguments
155
156     nb=size(typ_z,"*");
157     zcptr=ones(nb+1,1);
158     modptr=ones(nb+1,1);
159
160     for i=1:nb
161         zcptr(i+1)=zcptr(i)+typ_z(i)
162         modptr(i+1)=modptr(i)+sign(typ_z(i))*typ_mod(i);
163     end
164
165     ztyp=sign(typ_z0)  //completement inutile pour simulation
166     // utiliser pour la generation de code
167
168     if xptr($)==1 & zcptr($)>1 then
169         mess=msprintf(_("No continuous-time state. Thresholds are ignored; this \nmay be OK if you don''t generate external events with them.\nIf you want to reactivate the thresholds, then you need\n\nto include a block with continuous-time state in your diagram.\n   You can for example include DUMMY CLSS block (linear palette)."))
170         messagebox(mess,"modal","error");
171     end
172
173     subscr=[]
174     ncblk=0;nxblk=0;ndblk=0;ndcblk=0;
175     sim=scicos_sim(funs=funs,xptr=xptr,zptr=zptr,ozptr=ozptr,..
176     zcptr=zcptr,inpptr=inpptr,outptr=outptr,..
177     inplnk=inplnk,outlnk=outlnk,rpar=rpar,rpptr=rpptr,..
178     ipar=ipar,ipptr=ipptr,opar=opar,opptr=opptr,..
179     clkptr=clkptr,ordptr=ordptr,execlk=ordclk,..
180     ordclk=ordclk,cord=cord,oord=oord,zord=zord,..
181     critev=critev(:),nb=nb,ztyp=ztyp,nblk=nblk,..
182     ndcblk=ndcblk,subscr=subscr,funtyp=funtyp,..
183     iord=iord,labels=labels,uids=uids,modptr=modptr);
184
185     //initialize agenda
186     [tevts,evtspt,pointi]=init_agenda(initexe,clkptr)
187     if show_trace then mprintf("c_pass61:\t%f\n", timer()),end
188
189     //mod=0*ones(modptr($)-1,1)
190
191     outtb=list();
192     outtb=buildouttb(lnksz,lnktyp);
193
194     iz0=zeros(nb,1);
195
196     if max(funtyp)>10000 &%scicos_solver==0 then
197         warning(_("Diagram contains implicit blocks, compiling for implicit Solver."))
198         %scicos_solver=100
199     end
200     if or(%scicos_solver==[100, 101, 102]) then xc0=[xc0;xcd0],end
201     state=scicos_state()
202     state.x=xc0
203     state.z=xd0
204     state.oz=oxd0
205     state.iz=iz0
206     state.tevts=tevts
207     state.evtspt=evtspt
208     state.pointi=pointi
209     state.outtb=outtb
210     //  state.mod=mod
211
212     cpr=scicos_cpr(state=state,sim=sim,cor=cor,corinv=corinv);
213
214     if show_trace then mprintf("c_pass71:\t%f\n", timer()),end
215
216 endfunction
217
218
219 //donne les sources d'activation du sch�ma
220 function [vec_clk]=get_clocks(clkconnect,clkptr)
221     vec_clk=[]
222     if (find(clkconnect(:,1)==0) ~=[]) then
223         //activation continue
224         vec_clk=[vec_clk;0 0];
225     end
226     for blk=1:size(clkptr,1)-1
227         if ~typ_l(blk) then
228             for port=1:clkptr(blk+1)-clkptr(blk)
229                 vec_clk=[vec_clk; blk port];
230             end
231         end
232     end
233 endfunction
234
235
236
237 //insere le vecteur primary dans vec_clk apr�s la ligne comptenant le bloc i
238 function vec_clk0=set_primary_clk(vec_clk,primary,i)
239
240     if vec_clk~=[] then
241         n_vc0=find(vec_clk==i)
242         n_vc0=n_vc0($)
243         vec_clk0=vec_clk(1:n_vc0)
244         vec_clk1=vec_clk(n_vc0+1:size(vec_clk,1))
245         for k=1:size(primary,1)
246             if find(primary(k)==vec_clk0)==[] then
247                 vec_clk0($+1)=primary(k)
248             end
249         end
250         for k=1:size(vec_clk1,1)
251             if find(vec_clk1(k)==vec_clk0)==[] then
252                 vec_clk0($+1)=vec_clk1(k)
253             end
254         end
255     else
256         vec_clk0=primary
257     end
258
259 endfunction
260
261 //insere la sous-matrice primary dans vec_clk apr�s la ligne k
262 function vec_clk0=set_primary_clkport(vec_clk,primary,i)
263
264     if vec_clk~=[] then
265         vec_clk0=vec_clk(1:i,:)
266         vec_clk1=vec_clk(i+1:size(vec_clk,1),:)
267         for k=1:size(primary,1)
268             f=find(primary(k,1)==vec_clk0(:,1))
269             if f==[] then
270                 vec_clk0=[vec_clk0;primary(k,:)]
271             end
272         end
273         n_vc1=size(vec_clk1,1)
274         if n_vc1>0 then
275             for k=1:n_vc1
276                 f=find(vec_clk1(k,1)==vec_clk0(:,1))
277                 if f==[] then
278                     vec_clk0=[vec_clk0;vec_clk1(k,:)]
279                 end
280             end
281         end
282     else
283         vec_clk0=primary
284     end
285
286 endfunction
287
288 //insere la sous-matrice ordoclk0 dans ordclk apr�s le block k
289 function [ordptr,ordclk,blocs_traites]=set_ordclk(ordclk,..
290     ordoclk0,k,j,ordptr,blocs_traites)
291     if ordoclk0~=[] then
292         if ordclk==[] then
293             ordclk=[ordclk;ordoclk0];
294             ordptr($+1)=ordptr($)+size(ordoclk0,1);
295             blocs_traites=[blocs_traites;k] //k
296         else
297             m=max(find(blocs_traites==k))
298             if j>1 & m~=[] then
299                 ordclk=[ordclk(1:ordptr(m+1)-1,:);ordoclk0;ordclk(ordptr(m+1):$,:)]
300                 ordptr=[ordptr(1:m+1);ordptr(m+1:$)+size(ordoclk0,1)]
301                 blocs_traites=[blocs_traites(1:m);k;blocs_traites(m+1:$)]
302             else
303                 ind=find(blocs_traites <k)
304                 m=max(ind)
305                 if m==size(blocs_traites,1) then
306                     ordclk=[ordclk;ordoclk0]
307                     ordptr($+1)=ordptr($)+size(ordoclk0,1);
308                     blocs_traites=[blocs_traites;k]
309                 else
310                     if m~=[] then
311                         ordclk=[ordclk(1:ordptr(m+1)-1,:);ordoclk0;ordclk(ordptr(m+1):$,:)]
312                         ordptr=[ordptr(1:m+1);ordptr(m+1:$)+size(ordoclk0,1)]
313                         blocs_traites=[blocs_traites(1:m);k;blocs_traites(m+1:$)]
314                     else
315                         ordclk=[ordoclk0;ordclk]
316                         ordptr=[1;ordptr+size(ordoclk0,1)]
317                         blocs_traites=[k;blocs_traites]
318                     end
319                 end
320             end
321         end
322     else
323         if j>1 & find((blocs_traites==k))~=[] then
324             m=max(find(blocs_traites==k))
325             ordptr=[ordptr(1:m+1);ordptr(m+1:$)+size(ordoclk0,1)]
326             blocs_traites=[blocs_traites(1:m);k;blocs_traites(m+1:$)]
327         else
328             ind=find(blocs_traites <k)
329             m=max(ind)
330             if m==size(blocs_traites,1) then
331                 ordptr($+1)=ordptr($)+size(ordoclk0,1);
332                 blocs_traites=[blocs_traites;k]
333             else
334                 if m~=[] then
335                     ordptr=[ordptr(1:m+1);ordptr(m+1:$)+size(ordoclk0,1)]
336                     blocs_traites=[blocs_traites(1:m);k;blocs_traites(m+1:$)]
337                 else
338                     ordptr=[1;ordptr+size(ordoclk0,1)]
339                     blocs_traites=[k;blocs_traites]
340                 end
341             end
342         end
343     end
344 endfunction
345
346
347 //donne les blocs activant blk
348 function [parents]=get_parents(parents,blk)
349     f=find(clkconnect(:,3)==blk)
350     n_f=size(f,2)
351     if n_f>0 then
352         for i=1:n_f
353             clki1=clkconnect(f(i),1)
354             clki2=clkconnect(f(i),2)
355             g=find(clki1==parents(:,1))
356             if g==[] | (g~=[] & parents(g,2)~=clki2) then
357                 parents=[parents;clki1,clki2]
358             end
359         end
360     end
361 endfunction
362
363
364 function [blks,blksptr]=depend_on(connectmat,dep_u,dep_uptr)
365     // returns the blocks on which depend directly  a block
366     blks=[];blksptr=1
367     for i=1:size(dep_uptr,"*")-1
368         indport=find(dep_u(dep_uptr(i):dep_uptr(i+1)-1));
369         f=[]
370         for j=indport
371             f=[f,find(connectmat(:,3)==i&connectmat(:,4)==j)]
372         end
373         blkis=unique(connectmat(f,1))
374         blks=[blks;blkis]
375         blksptr=[blksptr;blksptr($)+size(blkis,"*")]
376     end
377 endfunction
378
379 function [eblks,eblksptr]=update_event_depend_on(eblks,eblksptr,clkconnect,cliptr,bls)
380     // updates the blocks activating a block
381     nb1=size(cliptr,"*")
382     eblksptr($:nb1)=eblksptr($)
383     for i=bls
384         f=find(clkconnect(:,3)==i)
385         blkis=unique(clkconnect(f,1))
386         dblkis=size(blkis,"*")-(eblksptr(i+1)-eblksptr(i))
387         Ibef=eblksptr(1):eblksptr(i)-1;
388         Iaft=eblksptr(i+1):eblksptr($)-1;
389         eblks=[eblks(Ibef);blkis;eblks(Iaft)]
390         eblksptr(i+1:$)=eblksptr(i+1:$)+dblkis
391     end
392 endfunction
393
394
395 function [fblks,fblksptr]=update_event_activates(fblks,fblksptr,clkconnect,clkptr,bls)
396     // returns the blocks activated by a block (assumed typ_l)
397     nb1=size(cliptr,"*")
398     fblksptr($:nb1)=fblksptr($)
399     for i=bls
400         f=find(clkconnect(:,1)==i)
401         blkis=unique(clkconnect(f,3))
402         dblkis=size(blkis,"*")-(fblksptr(i+1)-fblksptr(i))
403         Ibef=fblksptr(1):fblksptr(i)-1;
404         Iaft=fblksptr(i+1):fblksptr($)-1;
405         fblks=[fblks(Ibef);blkis;fblks(Iaft)]
406         fblksptr(i+1:$)=fblksptr(i+1:$)+dblkis
407     end
408 endfunction
409
410
411 function [eblks,eblksptr]=event_depend_on(clkconnect,cliptr)
412     // returns the blocks activating a block
413     eblks=[];eblksptr=1
414     for i=1:size(cliptr,"*")-1
415         f=find(clkconnect(:,3)==i)
416         blkis=unique(clkconnect(f,1))
417         eblks=[eblks;blkis]
418         eblksptr=[eblksptr;eblksptr($)+size(blkis,"*")]
419     end
420 endfunction
421
422
423 function [fblks,fblksptr]=event_activates(clkconnect,clkptr)
424     // returns the blocks activated by a block of type typ_l
425     fblks=[];fblksptr=1
426     for i=1:size(typ_l,"*")
427         if typ_l(i) then
428             f=find(clkconnect(:,1)==i)
429             blkis=unique(clkconnect(f,3))
430             fblks=[fblks;blkis]
431         else
432             blkis=[]
433         end
434         fblksptr=[fblksptr;fblksptr($)+size(blkis,"*")]
435     end
436 endfunction
437
438
439 function uni=merge_mat(m1,m2)
440     // for  m1 and m2 with two columns containing >=0 values
441     if isempty(m1) & isempty(m2) then
442         uni=[];
443         return;
444     end
445     uni=[m1;m2]
446     n=max(uni(:,2))+1;
447     [j,ind]=unique(uni(:,1)*n+uni(:,2))
448     uni=uni(-gsort(-ind),:)
449 endfunction
450
451 function [typ_l,clkconnect,connectmat,vbllst,dep_t,dep_u,dep_uptr,..
452     corinv,clkptr,cliptr,critev]=duplicate_block(bl,typ_l,clkconnect,..
453     connectmat,vbllst,dep_t,dep_u,dep_uptr,corinv,clkptr,cliptr,critev)
454
455     nblock=size(typ_l,1)+1
456     g=find(clkconnect(:,1)==bl)
457     if g<> [] then
458         xx=clkconnect(g,:)
459         xx(:,1)=nblock
460         clkconnect=[clkconnect;xx]
461     end
462
463     g=find(connectmat(:,3)==bl)
464     xx=connectmat(g,:)
465     xx(:,3)=nblock*ones(size(xx,1),1)
466     connectmat=[connectmat;xx]
467
468     typ_l($+1)=%t
469     critev=[critev;critev(clkptr(bl):clkptr(bl+1)-1)]
470     vbllst(nblock)=vbllst(bl)
471     dep_t(nblock)=dep_t(bl)
472     dep_u=[dep_u;dep_u(dep_uptr(bl))]
473     dep_uptr($+1)=dep_uptr($)+1
474
475     corinv(nblock)=corinv(bl)
476     clkptr(nblock+1)=clkptr(nblock)+clkptr(bl+1)-clkptr(bl)
477     cliptr(nblock+1)=cliptr(nblock)+cliptr(bl+1)-cliptr(bl)
478
479 endfunction
480
481 function [childs]=get_allchilds(primary,fblks,fblksptr,typ_l)
482
483     oldtaille=0
484     childs=primary(:)'
485     taille=size(childs,"*")
486
487     while oldtaille<>taille
488         oldtaille=taille
489         for i=childs(typ_l(childs))
490             bb=fblks(fblksptr(i):fblksptr(i+1)-1)
491             childs=union(childs,bb)
492         end
493         taille=size(childs,"*")
494     end
495 endfunction
496
497
498 function ok=is_alg_event_loop(typ_l,clkconnect)
499     clkconnect(find(clkconnect(:,1)==0),:)=[]
500     lclkconnect=clkconnect(typ_l(clkconnect(:,1))&typ_l(clkconnect(:,3)),[1,3])
501     n=size(typ_l,"*")
502     oldvec=zeros(n,1)
503     vec(lclkconnect(:,1))=1
504     i=0
505     ok=%f
506     while i<=n
507         i=i+1
508         oldvec=vec  // not optimal to use large v
509         if isempty(vec(lclkconnect(:,1))) then
510             vec(lclkconnect(:,2))=1
511         else
512             vec(lclkconnect(:,2))=vec(lclkconnect(:,1))+1
513         end
514         if and(vec==oldvec) then
515             ok=%t
516             return
517         end
518     end
519 endfunction
520
521 function [ordclk,ordptr,cord,typ_l,clkconnect,connectmat,bllst,dep_t,dep_u,dep_uptr,corinv,clkptr,cliptr,critev,ok]=paksazi2(typ_l,clkconnect,connectmat,bllst,dep_t,dep_u,dep_uptr,corinv,clkptr,cliptr,critev)
522
523     ordclk=[];ordptr=1;cord=[];
524     lordclk=list()
525
526     vbllst=1:length(bllst)
527
528     zz=get_clocks(clkconnect,clkptr)
529     //testing event algebraic loops
530     ok=is_alg_event_loop(typ_l,clkconnect)
531     if ~ok then
532         disp(msprintf("%s: alg_event_loop failed", "c_pass2"));
533         messagebox(_("Algebraic loop on events."),"modal","error");
534         return
535     end
536
537
538     ok=%t
539     [fblks,fblksptr]=event_activates(clkconnect,clkptr)
540     [blks,blksptr]=depend_on(connectmat,dep_u,dep_uptr)
541     [eblks,eblksptr]=event_depend_on(clkconnect,cliptr)
542
543
544     for i=1:size(zz,1)
545
546         nblock=size(typ_l,1);  // number of blocks in diagram
547
548         todo=zz(i,:)
549         while todo<>[]
550
551             blk=todo(1,1);port=todo(1,2);
552             if blk==0 |find(definedfields(lordclk)==clkptr(blk)+port-1)==[] then
553
554                 f=find(clkconnect(:,1)==blk&clkconnect(:,2)==port);
555                 if f<>[] then
556                     primary0=clkconnect(f,3);prt0=clkconnect(f,4)
557                 else
558                     primary0=[]
559                 end
560
561                 if  show_comment then mprintf("Processing blk " + string(blk) + " port "+...
562                 + string(port) + "\n"),end
563
564                 if primary0<>[] then  // delete redundant links
565                     [jj,k]=unique(primary0*(1+max(prt0))+prt0)
566                     index=setdiff(1:size(primary0,1),k)
567                     clkconnect(f(index),:)=[]  // does not affect e(f)blks
568
569                     primary=unique(primary0)
570
571                     [balg,vec]=ini_ordo3(primary)
572                     if balg then
573                         disp(msprintf("%s: ini_ordo (3) failed", "c_pass2"));
574                         messagebox(_("Algebraic loop."),"modal","error"),
575                         ok=%f
576                         return
577                     end
578
579                     pvec=vec(primary)+.5*typ_l(primary) // same order typ_l to the right
580                     [mi,In]=gsort(-pvec)
581                     primary=primary(In)
582                     lp=find(typ_l(primary))
583                     lprimary=primary(lp)
584
585                     bouclalg=%f
586                     lp_backw=lp($:-1:1)
587                     for i=lp_backw
588                         for J=primary(i+1:$)'
589                             if intersect(get_allchilds(primary(i)),get_allchilds(J))<>[] then
590                                 bouclalg=%t
591                                 break
592                             end
593                         end
594                         if bouclalg then break,end
595                     end
596
597                     if show_comment&bouclalg then mprintf("found intersect \n"),end
598
599                     if ~bouclalg then
600                         [bouclalg,Vec,typ_l,clkconnect,connectmat,bllst,dep_t,dep_u,..
601                         dep_uptr,corinv,clkptr,cliptr,critev]=ini_ordo2(primary,..
602                         clkconnect,connectmat,bllst,typ_l,dep_t,dep_u,dep_uptr,..
603                         corinv,clkptr,cliptr,critev)
604                         if bouclalg then
605                             if show_comment then mprintf("found non convergence\n"),pause,end
606                             i=lp(1)  // first typ_l
607                             if i==[] then
608                                 disp(msprintf("%s: ini_ordo (2) failed", "c_pass2"));
609                                 messagebox(_("Algebraic loop."),"modal","error")
610                                 ok=%f
611                                 return
612                             end
613                             J=primary(i+1:$)
614                         end
615                     end
616
617                     if bouclalg then
618                         modif=%f
619                         bl=primary(i)
620
621                         nout=clkptr(bl+1)-clkptr(bl)
622                         //duplicate bl if it receives other links
623                         f=find(clkconnect(:,1)==blk&clkconnect(:,2)==port&clkconnect(:,3)==bl)
624                         h=find(clkconnect(:,3)==bl)  // this is always one
625                         if size(f,2)<>size(h,2) then
626                             nblock=nblock+1
627                             clkconnect(f,3)=nblock
628                             if  show_comment then
629                                 mprintf("duplicating pivot"+string(bl)+" to obtain "+string(nblock) + "\n"),
630                             end
631                             [typ_l,clkconnect,connectmat,vbllst,dep_t,dep_u,dep_uptr,..
632                             corinv,clkptr,cliptr,critev]=duplicate_block(bl,typ_l,clkconnect,..
633                             connectmat,vbllst,dep_t,dep_u,dep_uptr,corinv,clkptr,cliptr,critev)
634                             vec(nblock)=vec(bl)
635                             //update pointer
636                             blks_bl=blks(blksptr(bl):blksptr(bl+1)-1)
637                             blks=[blks;blks_bl]
638                             blksptr($+1)=blksptr($)+size(blks_bl,"*")
639                             //
640                             bls=[bl,nblock,fblks(fblksptr(bl):fblksptr(bl+1)-1)']
641                             [eblks,eblksptr]=..
642                             update_event_depend_on(eblks,eblksptr,clkconnect,cliptr,bls)
643                             bl=nblock  // use new block as pivot
644                             lprimary(i)=bl
645                         end
646
647                         for bli=J(:)'
648                             modif=%t
649                             f=find(clkconnect(:,1)==blk&clkconnect(:,2)==port&clkconnect(:,3)==bli)
650                             clkconnect(f,1)=bl
651                             clkconnect(f,2)=1
652                             xx= clkconnect(f,:)
653                             for jj=2:nout
654                                 if  show_comment then
655                                     mprintf("No block duplication but link between "+string(blk)+..
656                                     " and "+string(bli)+" replaced with links from "+..
657                                     string(bl)+" to "+string(bli) + "\n"),
658                                 end
659                                 xx(:,2)=jj;
660                                 clkconnect=[clkconnect;xx]
661                             end
662                         end
663
664                         [eblks,eblksptr]=update_event_depend_on(eblks,eblksptr,clkconnect,cliptr,J(:)')
665                         bls=[blk,bl];bls(find(bls==0))=[];bls=bls(typ_l(bls)); //exclude non typ_l and 0
666                         [fblks,fblksptr]=update_event_activates(fblks,fblksptr,clkconnect,clkptr,bls)
667
668                         // can (must) be done outside the for loop
669                         //  [fblks2,fblksptr2]=event_activates(clkconnect,clkptr)
670                         //  [eblks2,eblksptr2]=event_depend_on(clkconnect,cliptr)
671                         //but then it must be updated
672                         //  if norm(eblksptr-eblksptr2)>0 then mprintf('roro2');pause,end
673                         //  if norm(fblksptr-fblksptr2)>0 then mprintf('soso2');pause,end
674                         //  if norm(eblks-eblks2)>0 then mprintf('roro');pause,end
675                         //  if norm(fblks-fblks2)>0 then mprintf('soso');pause,end
676
677
678                         if ~modif then messagebox(_("Algebraic loop."),"modal","error"),ok=%f,return,end
679                     else
680                         primary0=primary0(k);
681                         prt0=prt0(k)
682                         [primary0,prt0]=aggregate(primary0,prt0)
683                         [mi,In]=gsort(-Vec(primary0))
684                         if blk<>0 then
685                             lordclk(clkptr(blk)+port-1)=[primary0(In),prt0(In)]
686
687                             if  show_comment then
688                                 mprintf("for blk port "+string(blk)+" "+string(port)+..
689                                 " ordclk is :\n"), disp(lordclk(clkptr(blk)+port-1)),
690                             end
691                         else
692                             cord=[primary0(In),prt0(In)]
693                         end
694
695                         todo(1,:)=[]
696                         L=[];
697                         for Bi=lprimary'
698                             C=[1:clkptr(Bi+1)-clkptr(Bi)]'
699                             L=[L;Bi*ones(C),C]
700                         end
701                         todo=merge_mat(todo,L)
702                     end
703                 else
704                     if blk<>0 then
705                         J=clkptr(blk)+port-1
706                         lordclk(J)=[]
707                         if  show_comment then
708                             mprintf("for blk port "+string(blk)+" "+string(port)+..
709                             " ordclk is"), mprintf(lordclk(J) + "\n"),
710                         end
711                     else
712                         cord=[]
713                     end
714
715                     todo(1,:)=[]
716                 end
717             else
718                 todo(1,:)=[]
719             end
720         end
721     end
722
723     for J=1:clkptr($)-1
724         ordclk=[ordclk;lordclk(J)]
725         ordptr=[ordptr;ordptr($)+size(lordclk(J),1)]
726     end
727
728     bllst=list(bllst(vbllst))
729
730 endfunction
731
732 function  [primary0,port0]=aggregate(primary0,port0)
733     primary=discardprimary([primary0,port0]) // must rewrite
734     primary0=primary(:,1);port0=primary(:,2)
735 endfunction
736
737
738 function [parents]=get_parents2(parents,blk,port)
739     k=size(parents,1)+1;
740     f=find(clkconnect(:,3)==blk)
741     n_f=size(f,2)
742     if n_f>0 then
743         for i=1:n_f
744             if clkconnect(f(i),4)==port then
745                 clki1=clkconnect(f(i),1)
746                 clki2=clkconnect(f(i),2)
747                 g=find(clki1==parents(:,1))
748                 if g==[] | (g~=[] & parents(g,2)~=clki2) then
749                     parents(k,1)=clki1
750                     parents(k,2)=clki2
751                     k=k+1
752                 end
753             end
754         end
755     end
756 endfunction
757
758 //suppression des liens inutiles
759 function [clkconnect,amaj]=find_del_inutile(clkconnect,vec_plus,typ_l)
760     amaj=[]
761     for i=1:size(vec_plus,1)
762         blk=vec_plus(i,1)
763         port=vec_plus(i,2)
764         parents=get_parents2([],blk,port)
765         j=1
766         done=%f
767         n_p=size(parents,1)
768         while j<=n_p & ~done
769             par1=parents(j,1)
770             if par1~=0 & typ_l(par1) then
771                 n_out=clkptr(par1+1)-clkptr(par1)
772                 f=find(par1==parents(:,1))
773                 if size(f,2)==n_out then
774                     if show_comment then
775                         mprintf("find_del_inutile:")
776                         mprintf("link between blocks "+string(par1)+" and "+string(blk)+..
777                         " are deleted\n")
778                         pause
779                     end
780                     [clkconnect]=del_inutile(clkconnect,par1,n_out,blk,port)
781                     done=%t
782                     amaj=[amaj;par1;blk]
783                 end
784             end
785             j=j+1
786         end
787     end
788 endfunction
789
790 function [clkconnect]=del_inutile(clkconnect,blk0,n_out,blk,port)
791     f=find(clkconnect(:,1)==blk0)
792     del=[]
793     for i=1:size(f,2)
794         if clkconnect(f(i),3)==blk & clkconnect(f(i),4)==port then
795             del=[del;f(i)]
796         end
797     end
798     clkconnect(del,:)=[]
799     p=get_parents([],blk0)
800     n_p=size(p,1)
801     for i=1:n_p
802         clkconnect($+1,:)=[p(i,1),p(i,2),blk,port]
803     end
804 endfunction
805
806
807 function  blk0=get_father(blk1,vectmp)
808     gg=find(clkconnect(:,3)==blk1) // parents of blk1
809     del=find(clkconnect(gg,1)==0)
810     gg(del)=[]  // remove continuous-time source
811     // it is inactive
812     hh=find(vectmp(clkconnect(gg,1))>0) // keep active ones
813     blk0=unique(clkconnect(gg(hh),1)) // active parent(s)
814     blk0=blk0(typ_l(blk0)) // can be a vector
815 endfunction
816
817 function [bouclalg,vec,typ_l,clkconnect,connectmat,bllst,dep_t,dep_u,..
818     dep_uptr,corinv,clkptr,cliptr,critev]=ini_ordo2(primary,..
819     clkconnect,connectmat,bllst,typ_l,dep_t,dep_u,dep_uptr,corinv,clkptr,..
820     cliptr,critev)
821
822     n_p=size(primary,1)
823
824     nblock=size(typ_l,1);
825     //initialisation de vec
826     //on initialise vec � -1
827     vec=-ones(nblock,1)
828     vec(primary(:,1))=1
829
830     bouclalg=%f
831     fromfixe=%f
832     oldvec2=[]
833     counter2=0
834
835     [wprim,wprimptr,g0prim,g0primptr,gprim,gprimptr]=prim_calc(primary)
836
837     while ~fromfixe
838         vec=update_vec3(vec,wprim,wprimptr,g0prim,g0primptr,gprim,gprimptr)
839         //
840         if and(vec==oldvec2) then
841             fromfixe=%t
842         else
843             oldvec2=vec
844         end
845         counter2=counter2+1
846         if (counter2>n_p+1) then
847             bouclalg=%t
848             //      mprintf('Algebraic Loop detection.')
849             break
850         end
851     end
852 endfunction
853
854 function [bouclalg,vec]=ini_ordo3(primary)
855
856     n_p=size(primary,1)
857
858     nblock=size(typ_l,1);
859     //initialisation de vec
860     //on initialise vec � -1
861     vec=-ones(nblock,1)
862     vec(primary(:,1))=0
863
864     bouclalg=%f
865     fromfixe=%f
866     oldvec2=[]
867     counter2=0
868
869     [wprim,wprimptr,g0prim,g0primptr,gprim,gprimptr]=prim_calc(primary)
870
871     while ~fromfixe
872         vec=update_vec4(vec,wprim,wprimptr,g0prim,g0primptr,gprim,gprimptr)
873
874         if and(vec==oldvec2) then
875             fromfixe=%t
876         else
877             oldvec2=vec
878         end
879         counter2=counter2+1
880         if (counter2>n_p+1) then
881             bouclalg=%t
882             //      mprintf('Algebraic Loop detection.')
883             break
884         end
885     end
886 endfunction
887
888
889 function  vec=update_vec3(vec,wprim,wprimptr,g0prim,g0primptr,gprim,gprimptr)
890     for i=1:size(wprimptr,"*")-1
891         w=wprim(wprimptr(i):wprimptr(i+1)-1)
892         g0=g0prim(g0primptr(i):g0primptr(i+1)-1)
893         g=gprim(gprimptr(i):gprimptr(i+1)-1)
894         // detecting algebraic loops within a single cluster
895         //mprintf([px,py,size(blks,'*')])
896         vec(w)=max(vec(w))
897         if (g0 ~= []) then
898             vec(w(1))=max(vec(w(1)),max(vec(g0))+1)
899         end
900         //g=g(find(vec(g)>-1))  //not optimal  test max(vec(g))
901         if g~=[] then
902             vec(w)=vec(w)-1
903             vec(w)=max(vec(w),max(vec(g)))+1
904         end
905     end
906 endfunction
907
908 function  vec=update_vec4(vec,wprim,wprimptr,g0prim,g0primptr,gprim,gprimptr)
909     for i=1:size(wprimptr,"*")-1
910         w=wprim(wprimptr(i):wprimptr(i+1)-1)
911         g0=g0prim(g0primptr(i):g0primptr(i+1)-1)
912         if g0<>[] then vec(w(1))=max(vec(w(1)),max(vec(g0))), end
913         vec(w(2:$))=vec(w(1))+1
914     end
915 endfunction
916
917 function [wprim,wprimptr,g0prim,g0primptr,gprim,gprimptr]=prim_calc(primary)
918     wprim=[];wprimptr=1
919     gprim=[];gprimptr=1
920     g0prim=[];g0primptr=1
921
922
923     for i=1:size(primary,"*")
924         w0=primary(i)
925         if typ_l(w0) then
926             w=get_allchilds(w0,fblks,fblksptr,typ_l)
927             j=find(w==w0)
928             w([1,j])=w([j,1])  // put w0 on top
929         else
930             w=w0;
931         end
932         wprim=[wprim;w(:)]
933         wprimptr($+1)=wprimptr($)+size(w,"*")
934
935         px=blksptr(w(1));py=blksptr(w(1)+1)-1
936         //mprintf([px,py,size(blks,'*')])
937         g0prim=[g0prim;blks(px:py)]
938         g0primptr($+1)=g0primptr($)+size(px:py,2)
939
940         g=[]
941         for i1=2:size(w,"*") // 1 is done already
942             px=blksptr(w(i1));py=blksptr(w(i1)+1)-1
943             g=[g;blks(px:py)]
944         end
945         gprim=[gprim;g]
946         gprimptr($+1)=gprimptr($)+size(g,"*")
947     end
948 endfunction
949
950 function primary=discardprimary(primary)
951     // discard
952     mma=max(primary(:,2))+1
953     con=mma*primary(:,1)+primary(:,2)
954     [junk,ind]=gsort(-con);con=-junk
955     primary=primary(ind,:)
956     // discard duplicate calls to the same block port
957     if size(con,"*")>=2 then
958         primary(find(con(2:$)-con(1:$-1)==0),:)=[]
959     end
960     // group calls to different ports of the same block.
961     primary=[primary(:,1),2^(primary(:,2)-ones(primary(:,2)))]
962     primary=int(primary)
963     con=primary(:,1)
964     clkconnectjj=[]
965     if size(con,"*")>=2 then
966         iini=[find(con(2:$)-con(1:$-1)<>0),size(primary,1)]
967     else
968         iini=1
969     end
970     for ii=iini
971         clkconnectjj=[clkconnectjj;[primary(ii,1),..
972         mysum(primary(find(primary(:,1)==primary(ii,1)),2))]]
973     end
974     primary=clkconnectjj
975 endfunction
976
977
978
979
980 function [ordclk,iord,oord,zord,typ_z,ok]=scheduler(inpptr,outptr,clkptr,execlk_cons,..
981     outoin,outoinptr,evoutoin,evoutoinptr,typ_z,typ_x,typ_l,bexe,boptr,..
982     blnk,blptr,ordclk,ordptr,cord,dep_t,dep_u,dep_uptr);
983
984     nblk=size(typ_x,1)
985     //compute iord
986     if execlk_cons<>[] then
987         vec=-ones(1,nblk)
988         no_tu_dep=execlk_cons(:,1)
989         wec=zeros(1,nblk)
990         wec(no_tu_dep')=execlk_cons(:,2)'
991         vec(no_tu_dep)=0*no_tu_dep'
992         [r,ok]=newc_tree2(vec,outoin,outoinptr,dep_u,dep_uptr)
993
994         iord=[r,wec(r)']
995     else
996         iord=[]
997     end
998     //
999     if ~ok then
1000         disp(msprintf("%s: scheduling failed", "c_pass2"));
1001         messagebox(_("Algebraic loop."),"modal","error");
1002         iord=[],oord=[],zord=[],critev=[]
1003         return,
1004     end
1005
1006     n=size(cord,1)
1007     vec=-ones(1,nblk);
1008     vec(cord(:,1))=0;
1009     typp=zeros(typ_l);typp(typ_l)=1
1010
1011     ext_cord1=cord;
1012     j=1
1013     while %t
1014         ii=ext_cord1(j,1)
1015         if typ_l(ii)
1016             for i=[clkptr(ii):clkptr(ii+1)-1]
1017                 ext_cord1=[ext_cord1;ordclk([ordptr(i):ordptr(i+1)-1],:)];
1018             end
1019         end
1020         j=j+1
1021         if j>size(ext_cord1,1) then break;end
1022     end
1023     // code to replace faulty unique which reorders
1024     yy=ext_cord1(:,1)'
1025     [xx,kkn]=unique(yy);
1026     ext_cord=yy(-gsort(-kkn))
1027     //ext_cord=unique(ext_cord1(:,1)');
1028     //for i=ext_cord
1029     //  if typ_l(i) then typ_z(i)=clkptr(i+1)-clkptr(i)-1;end
1030     //end  // adding zero crossing surfaces to cont. time synchros
1031
1032     //a supprimer
1033
1034     [ext_cord_old,ok]=newc_tree3(vec,dep_u,dep_uptr,typp);
1035
1036     if or(gsort(ext_cord_old)<>gsort(ext_cord)) then pause,end
1037     //
1038     //pour mettre a zero les typ_z qui ne sont pas dans ext_cord
1039     //noter que typ_z contient les tailles des nzcross (peut etre >1)
1040     typ_z(ext_cord)=-typ_z(ext_cord)
1041     typ_z=-min(typ_z,0)
1042
1043     if ~ok then mprintf("serious bug, report.");pause;end
1044     // ext_cord=ext_cord(n+1:$);
1045
1046     typ_z_save=typ_z
1047
1048     fin=0
1049     while ~fin
1050         fin=1
1051         for i=ext_cord($:-1:1)
1052             for ii=[outoin(outoinptr(i):outoinptr(i+1)-1,1)',..
1053                 evoutoin(evoutoinptr(i):evoutoinptr(i+1)-1,1)']
1054                 //ii est un block affecte par changement de sortie du
1055                 //i-eme block de oord
1056                 if typ_z(ii) then
1057                     if typ_z(i)==0 then typ_z(i)=1;fin=0;end
1058                 end
1059                 if typ_x(ii) then
1060                     if ~typ_x(i) then typ_x(i)=%t;fin=0;end
1061                 end
1062                 if typ_z(i)&typ_x(i) then break,end
1063             end
1064         end
1065     end
1066     //supprimer les blocks a supprimer
1067     ind=find(typ_z(cord(:,1)));
1068     zord=cord(ind,:)
1069     ind=find(typ_x(cord(:,1)));
1070     oord=cord(ind,:)
1071     typ_z=typ_z_save
1072     //critev: vecteur indiquant si evenement est important pour tcrit
1073     //Donc les blocks indiques sont des blocks susceptibles de produire
1074     //des discontinuites quand l'evenement se produit
1075     if isempty(ext_cord1) then
1076         if isempty(ordclk) then
1077             maX=1;
1078         else
1079             maX=max(ordclk(:,2))+1;
1080         end
1081         cordX = [];
1082     else
1083         maX=max([ext_cord1(:,2);ordclk(:,2)])+1;
1084         cordX=ext_cord1(:,1)*maX+ext_cord1(:,2);
1085     end
1086
1087     // 1: important; 0:non
1088     //n=clkptr(nblk+1)-1 //nb d'evenement
1089     n=size(ordptr,"*")-1 //nb d'evenement
1090
1091     //a priori tous les evenements sont non-importants
1092     //critev=zeros(n,1)
1093     for i=1:n
1094         for hh=ordptr(i):ordptr(i+1)-1
1095             jj= ordclk(hh,1) //block excite par evenement i
1096             //Following line is not correct because of ever active synchros
1097             if or(jj*maX+ordclk(hh,2)==cordX) then
1098                 ordclk(hh,2)=-ordclk(hh,2)
1099             end
1100         end
1101     end
1102 endfunction
1103
1104 function [ord,ok]=tree3(vec,dep_ut,typ_l)
1105     //compute blocks execution tree
1106     ok=%t
1107     nb=size(vec,"*")
1108     for j=1:nb+2
1109         fini=%t
1110         for i=1:nb
1111             if vec(i)==j-1&typ_l(i)<>-1 then
1112                 if j==nb+2 then
1113                     disp(msprintf("%s: tree (3) failed", "c_pass2"));
1114                     messagebox(_("Algebraic loop."),"modal","error");ok=%f;ord=[];return;
1115                 end
1116                 if typ_l(i)==1 then
1117                     fini=%f;
1118                     kk=bexe(boptr(i):boptr(i+1)-1)';
1119                 else
1120                     kk=[];
1121                     for ii=blnk(blptr(i):blptr(i+1)-1)'
1122                         if vec(ii)>-1 & (dep_ut(ii,1) | (typ_l(ii)==1)) then
1123                             fini=%f;
1124                             kk=[kk ii];
1125                         end
1126                     end
1127                 end
1128                 vec(kk)=j*ones(kk) ;   //mprintf(vec)
1129             end
1130         end
1131         if fini then break;end
1132     end
1133     [k,ord]=gsort(-vec);
1134     ord(find(k==1))=[];
1135 endfunction
1136
1137 function [clkconnectj_cons]=discard(clkptr,cliptr,clkconnect,exe_cons)
1138
1139     if exe_cons<>[] then
1140         clkconnectj=exe_cons
1141         mma=max(clkconnectj(:,2))+1
1142         con=mma*(clkconnectj(:,1))+clkconnectj(:,2)
1143         [junk,ind]=gsort(-con);con=-junk
1144         clkconnectj=clkconnectj(ind,:)
1145         // discard duplicate calls to the same block port
1146         if size(con,"*")>=2 then
1147             clkconnectj(find(con(2:$)-con(1:$-1)==0),:)=[]
1148         end
1149         // group calls to different ports of the same block.
1150         clkconnectj=[clkconnectj(:,1),2^(clkconnectj(:,2)-ones(clkconnectj(:,2)))]
1151         clkconnectj=int(clkconnectj)
1152         con=clkconnectj(:,1)
1153         clkconnectj_cons=[]
1154         if size(con,"*")>=2 then
1155             iini=[find(con(2:$)-con(1:$-1)<>0),size(clkconnectj,1)]
1156         else
1157             iini=1
1158         end
1159         for ii=iini
1160             clkconnectj_cons=[clkconnectj_cons;[clkconnectj(ii,1),..
1161             mysum(clkconnectj(find(clkconnectj(:,1)==clkconnectj(ii,1)),2))]]
1162         end
1163     else
1164         clkconnectj_cons=[]
1165     end
1166 endfunction
1167
1168 function a=mysum(b)
1169     if b<>[] then a=sum(b), else a=[], end
1170 endfunction
1171
1172 function [lnksz,lnktyp,inplnk,outlnk,clkptr,cliptr,inpptr,outptr,xptr,zptr,..
1173     ozptr,typ_mod,rpptr,ipptr,opptr,xc0,xcd0,xd0,oxd0,rpar,..
1174     ipar,opar,typ_z,typ_x,typ_m,funs,funtyp,initexe,labels,uids,..
1175     bexe,boptr,blnk,blptr,ok]=extract_info(bllst,connectmat,clkconnect,typ_l)
1176
1177     ok=%t
1178     nbl=length(bllst)
1179     clkptr=zeros(nbl+1,1);clkptr(1)=1
1180     cliptr=clkptr;inpptr=cliptr;outptr=inpptr;
1181     xptr=1;zptr=1;ozptr=1;
1182     rpptr=clkptr;ipptr=clkptr;opptr=clkptr;
1183     //
1184     xc0=[];xcd0=[];xd0=[];
1185     oxd0=list()
1186     rpar=[];ipar=[];
1187     opar=list();
1188
1189     fff=ones(nbl,1)==1
1190     typ_z=zeros(nbl,1);typ_x=fff;typ_m=fff;typ_mod=zeros(nbl,1);
1191
1192     initexe=[];
1193     funs=list();
1194     funtyp=zeros(typ_z)
1195     labels=[]
1196     uids=[]
1197     [ok,bllst]=adjust_inout(bllst,connectmat)
1198     if ok then
1199         [ok,bllst]=adjust_typ(bllst,connectmat)
1200     end
1201
1202     // placed here to make sure nzcross and nmode correctly updated
1203     if ~ok then
1204         lnksz=[],lnktyp=[],inplnk=[],outlnk=[],clkptr=[],cliptr=[],inpptr=[],outptr=[],..
1205         xptr=[],zptr=[],ozptr=[],rpptr=[],ipptr=[],opptr=[],xc0=[],..
1206         xcd0=[],xd0=[],oxd0=list(),rpar=[],ipar=[],opar=list(),..
1207         typ_z=[],typ_x=[],typ_m=[],funs=[],funtyp=[],initexe=[],..
1208         labels=[],uids=[],bexe=[],boptr=[],blnk=[],blptr=[]
1209         return;
1210     end
1211     for i=1:nbl
1212         ll=bllst(i)
1213
1214         if type(ll.sim)==15 then
1215             funs(i)=ll.sim(1)
1216             funtyp(i,1)=ll.sim(2)
1217         else
1218             funs(i)=ll.sim;
1219             funtyp(i,1)=0;
1220         end
1221         if funtyp(i,1)>999&funtyp(i,1)<10000 then
1222             if ~c_link(funs(i)) then
1223                 messagebox(msprintf(_("A C or Fortran block is used but not linked.\n"+..
1224                 "You can save your compiled diagram and load it.\n"+..
1225                 "This will automatically link the C or Fortran function.")),"modal","error")
1226             end
1227         end
1228         inpnum=ll.in;outnum=ll.out;cinpnum=ll.evtin;coutnum=ll.evtout;
1229         //
1230         inpptr(i+1)=inpptr(i)+size(inpnum,"*")
1231         outptr(i+1)=outptr(i)+size(outnum,"*")
1232         cliptr(i+1)=cliptr(i)+size(cinpnum,"*")
1233         clkptr(i+1)=clkptr(i)+size(coutnum,"*")
1234         //
1235         X0=ll.state(:)
1236         if funtyp(i,1)<10000 then
1237             xcd0=[xcd0;0*X0]
1238             xc0=[xc0;X0]
1239             xptr(i+1)=xptr(i)+size(ll.state,"*")
1240         else
1241             xcd0=[xcd0;X0($/2+1:$)]
1242             xc0=[xc0;X0(1:$/2)]
1243             xptr(i+1)=xptr(i)+size(ll.state,"*")/2
1244         end
1245
1246         //dstate
1247         if (funtyp(i,1)==3 | funtyp(i,1)==5 | funtyp(i,1)==10005) then //sciblocks
1248             if ll.dstate==[] then xd0k=[]; else xd0k=var2vec(ll.dstate);end
1249         else
1250             xd0k=ll.dstate(:)
1251         end
1252         xd0=[xd0;xd0k]
1253         zptr(i+1)=zptr(i)+size(xd0k,"*")
1254
1255         //odstate
1256         if type(ll.odstate)==15 then
1257             if ((funtyp(i,1)==5) | (funtyp(i,1)==10005)) then //sciblocks : don't extract
1258                 if lstsize(ll.odstate)>0 then
1259                     oxd0($+1)=ll.odstate
1260                     ozptr(i+1)=ozptr(i)+1;
1261                 else
1262                     ozptr(i+1)=ozptr(i);
1263                 end
1264             elseif ((funtyp(i,1)==4)    | (funtyp(i,1)==10004) |...
1265                 (funtyp(i,1)==2004) | (funtyp(i,1)==12004))  //C blocks : extract
1266                 ozsz=lstsize(ll.odstate);
1267                 if ozsz>0 then
1268                     for j=1:ozsz, oxd0($+1)=ll.odstate(j), end;
1269                     ozptr(i+1)=ozptr(i)+ozsz;
1270                 else
1271                     ozptr(i+1)=ozptr(i);
1272                 end
1273             else
1274                 ozptr(i+1)=ozptr(i);
1275             end
1276         else
1277             //add an error message here please !
1278             ozptr(i+1)=ozptr(i);
1279         end
1280
1281         //mod
1282         typ_mod(i)=ll.nmode;
1283         if typ_mod(i)<0 then
1284             messagebox(msprintf(_("Number of modes in block #%d cannot be determined."),i),"modal","error")
1285             ok=%f
1286         end
1287
1288         //real paramaters
1289         rpark=ll.rpar(:)
1290         rpar=[rpar;rpark]
1291         rpptr(i+1)=rpptr(i)+size(rpark,"*")
1292
1293         //integer parameters
1294         if type(ll.ipar)==1 then
1295             ipar=[ipar;ll.ipar(:)]
1296             ipptr(i+1)=ipptr(i)+size(ll.ipar,"*")
1297         else
1298             ipptr(i+1)=ipptr(i)
1299         end
1300
1301         //object parameters
1302         if type(ll.opar)==15 then
1303             if ((funtyp(i,1)==5) | (funtyp(i,1)==10005)) then //sciblocks : don't extract
1304                 if lstsize(ll.opar)>0 then
1305                     opar($+1)=ll.opar
1306                     opptr(i+1)=opptr(i)+1;
1307                 else
1308                     opptr(i+1)=opptr(i);
1309                 end
1310             elseif ((funtyp(i,1)==4)    | (funtyp(i,1)==10004) |...
1311                 (funtyp(i,1)==2004) | (funtyp(i,1)==12004)) then //C blocks : extract
1312                 oparsz=lstsize(ll.opar);
1313                 if oparsz>0 then
1314                     for j=1:oparsz, opar($+1)=ll.opar(j), end;
1315                     opptr(i+1)=opptr(i)+oparsz;
1316                 else
1317                     opptr(i+1)=opptr(i);
1318                 end
1319             else
1320                 opptr(i+1)=opptr(i);
1321             end
1322         else
1323             //add an error message here please !
1324             opptr(i+1)=opptr(i);
1325         end
1326
1327         //    typ_z(i)=ll.blocktype=='z'
1328         typ_z(i)=ll.nzcross
1329         if typ_z(i)<0 then
1330             messagebox(msprintf(_("Number of zero crossings in block #%d cannot be determined."),i),"modal","error")
1331             ok=%f
1332         end
1333         typ_x(i)=ll.state<>[]|ll.blocktype=="x" // some blocks like delay
1334         // need to be in oord even
1335         // without state
1336
1337         typ_m(i)=ll.blocktype=="m"
1338         //
1339         if ll.evtout<>[] then
1340             ll11=ll.firing
1341             prt=find(ll11>=zeros(ll11))
1342             nprt=prod(size(prt))
1343             initexe=[initexe;[i*ones(nprt,1),matrix(prt,nprt,1),matrix(ll11(prt),nprt,1)]];
1344         end
1345
1346         if type(ll.label)==10 then
1347             labels=[labels;ll.label(1)]
1348         else
1349             labels=[labels;" "]
1350         end
1351
1352         if type(ll.uid)==10 then
1353             uids=[uids;ll.uid(1)]
1354         else
1355             uids=[uids;" "]
1356         end
1357     end
1358
1359     clkconnect=clkconnect(find(clkconnect(:,1)<>0),:);
1360
1361     if isempty(clkconnect) then
1362         con=-1;
1363     else
1364         con=clkptr(clkconnect(:,1))+clkconnect(:,2)-1;
1365     end
1366     [junk,ind]=gsort(-con);con=-junk;
1367     clkconnect=clkconnect(ind,:);
1368     //
1369     bclkconnect=clkconnect(:,[1 3]);
1370     boptr=1;
1371     bexe=[];
1372     for i=1:nbl
1373         r=bclkconnect(find(bclkconnect(:,1)==i),2);
1374         bexe=[bexe;r];
1375         boptr=[boptr;boptr($)+size(r,1)];
1376     end
1377     //
1378
1379     blptr=1;
1380     blnk=[];
1381
1382     for i=1:nbl
1383         r=connectmat(find(connectmat(:,1)==i),3:4);
1384         blnk=[blnk;r];
1385         blptr=[blptr;blptr($)+size(r,1)];
1386     end
1387     //
1388
1389     nlnk=size(connectmat,1)
1390     inplnk=zeros(inpptr($)-1,1);outlnk=zeros(outptr($)-1,1);ptlnk=1;
1391     lnksz=[];lnktyp=[];
1392     for jj=1:nlnk
1393         ko=outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)
1394         ki=inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)
1395         if ko<>0 & ki<>0 then
1396             if ko>ki then
1397                 outlnk(outlnk>ko)=outlnk(outlnk>ko)-1
1398                 outlnk(outlnk==ko)=ki
1399                 inplnk(inplnk>ko)=inplnk(inplnk>ko)-1
1400                 inplnk(inplnk==ko)=ki
1401                 ptlnk=-1+ptlnk
1402                 lnksz(ko,1)=[];
1403                 lnksz(ko,2)=[];
1404                 lnktyp(ko) =[];
1405             elseif ki>ko
1406                 outlnk(outlnk>ki)=outlnk(outlnk>ki)-1
1407                 outlnk(outlnk==ki)=ko
1408                 inplnk(inplnk>ki)=inplnk(inplnk>ki)-1
1409                 inplnk(inplnk==ki)=ko
1410                 ptlnk=-1+ptlnk
1411                 lnksz(ki,1)=[];
1412                 lnksz(ki,2)=[];
1413                 lnktyp(ki) =[];
1414             end
1415         elseif ko<>0 then
1416             inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)=ko
1417         elseif ki<>0 then
1418             outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)=ki
1419         else
1420             outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)=ptlnk
1421             inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)=ptlnk
1422             lnksz(ptlnk,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2));
1423             lnksz(ptlnk,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2));
1424             lnktyp(ptlnk)=bllst(connectmat(jj,1)).outtyp(connectmat(jj,2));
1425             ptlnk=1+ptlnk
1426         end
1427     end
1428
1429     //store unconnected outputs, if any, at the end of outtb
1430     unco=find(outlnk==0);
1431     for j=unco
1432         m=max(find(outptr<=j))
1433         n=j-outptr(m)+1
1434         nm=bllst(m).out(n)
1435         if nm<1 then
1436             under_connection(corinv(m),n,nm,-1,0,0,1),ok=%f,return,
1437         end
1438         nm2=bllst(m).out2(n)
1439         if nm2<1 then
1440             under_connection(corinv(m),n,nm2,-1,0,0,1),ok=%f,return,
1441         end
1442         lnksz($+1,1)=bllst(m).out(n);
1443         lnksz($,2)=bllst(m).out2(n);
1444         lnktyp($+1)=bllst(m).outtyp(n);
1445         outlnk(j)=max(outlnk)+1
1446     end
1447
1448     //store unconnected inputs, if any, at the end of outtb
1449     unco=find(inplnk==0);
1450     for j=unco
1451         m=max(find(inpptr<=j))
1452         n=j-inpptr(m)+1
1453         nm=bllst(m).in(n)
1454         if nm<1 then
1455             under_connection(corinv(m),n,nm,-2,0,0,1),ok=%f,return,
1456         end
1457         nm2=bllst(m).in2(n)
1458         if nm2<1 then
1459             under_connection(corinv(m),n,nm2,-2,0,0,1),ok=%f,return,
1460         end
1461         lnksz($+1,1)=bllst(m).in(n);
1462         lnksz($,2)=bllst(m).in2(n);
1463         lnktyp($+1)=bllst(m).intyp(n);
1464         inplnk(j)=max([inplnk;max(outlnk)])+1
1465     end
1466
1467 endfunction
1468
1469 function [outoin,outoinptr]=conn_mat(inpptr,outptr,inplnk,outlnk)
1470     outoin=[];outoinptr=1
1471     nblk=size(inpptr,1)-1
1472     for i=1:nblk
1473         k=outptr(i):outptr(i+1)-1
1474         ii=[]
1475         for j=outlnk(k)'
1476             ii=[ii,find(inplnk==j)]
1477         end
1478         outoini=[];jj=0
1479         for j=ii
1480             m=max(find(inpptr<=j))
1481             n=j-inpptr(m)+1
1482             outoini=[outoini;[m,n]]
1483             jj=jj+1
1484         end
1485         outoinptr=[outoinptr;outoinptr($)+jj]
1486         outoin=[outoin;outoini]
1487     end
1488 endfunction
1489
1490 function [ord,ok]=tree2(vec,outoin,outoinptr,dep_ut)
1491     //compute blocks execution tree
1492     ok=%t;
1493
1494     nb=size(vec,"*");
1495     for j=1:nb+2
1496         fini=%t
1497         for i=1:nb
1498             if vec(i)==j-1 then
1499                 if j==nb+2 then
1500                     disp(msprintf("%s: tree (2) failed", "c_pass2"));
1501                     messagebox(_("Algebraic loop."),"modal","error");ok=%f;ord=[];return;
1502                 end
1503                 for k=outoinptr(i):outoinptr(i+1)-1
1504                     ii=outoin(k,1);
1505                     //indport=find(dep_u(dep_uptr(ii):dep_uptr(ii+1)-1)==1);
1506                     //if (indport ~=[] &vec(ii)>-1) then
1507                     if (dep_ut(ii) &vec(ii)>-1) then
1508                         fini=%f;
1509                         vec(ii)=j;
1510                     end
1511                 end
1512             end
1513         end
1514         if fini then break;end
1515     end
1516
1517     [k,ord]=gsort(-vec);
1518     ord(find(k==1))=[];
1519     ord=ord(:)
1520 endfunction
1521
1522
1523 //adjust_inout : it resolves positive, negative and null size
1524 //               of in/out port dimensions of connected block.
1525 //               If it's not done in a first pass, the second
1526 //               pass try to resolve negative or null port
1527 //               dimensions by asking user to informed dimensions
1528 //               with underconnection function.
1529 //               It is a fixed point algorithm.
1530 //
1531 //in parameters  : bllst : list of blocks
1532 //
1533 //                 connectmat : matrix of connection
1534 //                              connectmat(lnk,1) : source block
1535 //                              connectmat(lnk,2) : source port
1536 //                              connectmat(lnk,3) : target block
1537 //                              connectmat(lnk,4) : target port
1538 //
1539 //out parameters : ok : a boolean flag to known if adjust_inout have
1540 //                      succeeded to resolve the in/out port size
1541 //                      - ok = %t : all size have been resolved in bllst
1542 //                      - ok = %f : problem in size adjustement
1543 //
1544 //                 bllst : modified list of blocks
1545 //
1546 //18/05/06, Alan  : improvement in order to take into
1547 //                  account two dimensional port size.
1548 //
1549 //28/12/06, Alan : type for source port and target port must
1550 //                 be the same.
1551 //
1552 //29/12/06, Fady : type for source and target can be different
1553 //                 in one condition that they are double and complex.
1554 //                 the result on the link will be complex.
1555 //
1556 //04/01/07, Fady : Can test the case of negatives equals target's dimensions.
1557 //
1558 //19/01/07, Alan : - Return correct information for user in editor
1559 //                   with preceding test of Fady in the first pass
1560 //                 - Second pass reviewed : under_connection returns two dimensions now
1561 //
1562 //10/05/07, Alan : - if-then-else event-select case
1563
1564 function [ok,bllst]=adjust_inout(bllst,connectmat)
1565
1566     //Adjust in2/out2, inttyp/outtyp
1567     //in accordance to in/out in bllst
1568     [ko,bllst]=adjust_in2out2(bllst);
1569     if ~ko then ok=%f,return, end //if adjust_in2out2 failed then exit
1570     //adjust_inout with flag ok=%f
1571
1572     nlnk=size(connectmat,1) //nlnk is the number of link
1573
1574     //loop on number of block (pass 1 and pass 2)
1575     for hhjj=1:length(bllst)+1
1576         //%%%%% pass 1 %%%%%//
1577         for hh=1:length(bllst)+1 //second loop on number of block
1578             ok=%t
1579             for jj=1:nlnk //loop on number of link
1580
1581                 //intyp/outtyp are the type of the
1582                 //target port and the source port of the observed link
1583                 outtyp = bllst(connectmat(jj,1)).outtyp(connectmat(jj,2))
1584                 intyp = bllst(connectmat(jj,3)).intyp(connectmat(jj,4))
1585                 //nnin/nnout are the size (two dimensions) of the
1586                 //target port and the source port of the observed link
1587                 //before adjust
1588                 nnout(1,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2))
1589                 nnout(1,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2))
1590                 nnin(1,1)=bllst(connectmat(jj,3)).in(connectmat(jj,4))
1591                 nnin(1,2)=bllst(connectmat(jj,3)).in2(connectmat(jj,4))
1592
1593                 //This Part is done in adjust_typ
1594
1595                 //check intyp/outtyp
1596                 //            if intyp<>outtyp then
1597                 //              if (intyp==1 & outtyp==2) then
1598                 //                bllst(connectmat(jj,3)).intyp(connectmat(jj,4))=2;
1599                 //              elseif (intyp==2 & outtyp==1) then
1600                 //                bllst(connectmat(jj,1)).outtyp(connectmat(jj,2))=2;
1601                 //              else
1602                 //                if bllst(connectmat(jj,3)).sim(2)<0 //if-then-else/eselect case
1603                 //                  bllst(connectmat(jj,3)).intyp(connectmat(jj,4))=...
1604                 //                    bllst(connectmat(jj,1)).outtyp(connectmat(jj,2))
1605                 //                else
1606                 //                  bad_connection(corinv(connectmat(jj,1)),connectmat(jj,2),..
1607                 //                                 nnout,outtyp,..
1608                 //                                 corinv(connectmat(jj,3)),connectmat(jj,4),..
1609                 //                                 nnin,intyp,1)
1610                 //                  ok=%f;
1611                 //                  return
1612                 //                end
1613                 //              end
1614                 //            end
1615
1616                 //loop on the two dimensions of source/target port
1617                 for ndim=1:2
1618                     //check test source/target sizes
1619                     //in case of negatif equal target dimensions
1620                     //nin/nout are the size (two dimensions) of the
1621                     //target port and the source port of the observed link
1622                     nout(1,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2))
1623                     nout(1,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2))
1624                     nin(1,1)=bllst(connectmat(jj,3)).in(connectmat(jj,4))
1625                     nin(1,2)=bllst(connectmat(jj,3)).in2(connectmat(jj,4))
1626
1627                     //first case : dimension of source and
1628                     //             target ports are explicitly informed
1629                     //             informed with positive size
1630                     if(nout(1,ndim)>0&nin(1,ndim)>0) then
1631                         //if dimension of source and target port doesn't match
1632                         //then call bad_connection, set flag ok to false and exit
1633                         if nin(1,ndim)<>nout(1,ndim) then
1634                             bad_connection(corinv(connectmat(jj,1)),connectmat(jj,2),..
1635                             nnout,outtyp,..
1636                             corinv(connectmat(jj,3)),connectmat(jj,4),..
1637                             nnin,intyp)
1638                             ok=%f;return
1639                         end
1640
1641                         //second case : dimension of source port is
1642                         //              positive and dimension of
1643                         //              target port is negative
1644                     elseif(nout(1,ndim)>0&nin(1,ndim)<0) then
1645                         //find vector of input ports of target block with
1646                         //first/second dimension equal to size nin(1,ndim)
1647                         //and assign it to nout(1,ndim)
1648                         ww=find(bllst(connectmat(jj,3)).in==nin(1,ndim))
1649                         bllst(connectmat(jj,3)).in(ww)=nout(1,ndim)
1650                         ww=find(bllst(connectmat(jj,3)).in2==nin(1,ndim))
1651                         bllst(connectmat(jj,3)).in2(ww)=nout(1,ndim)
1652
1653                         //find vector of output ports of target block with
1654                         //first/second dimension equal to size nin(1,ndim)
1655                         //and assign it to nout(1,ndim)
1656                         ww=find(bllst(connectmat(jj,3)).out==nin(1,ndim))
1657                         bllst(connectmat(jj,3)).out(ww)=nout(1,ndim)
1658                         ww=find(bllst(connectmat(jj,3)).out2==nin(1,ndim))
1659                         bllst(connectmat(jj,3)).out2(ww)=nout(1,ndim)
1660
1661                         //find vector of output ports of target block with
1662                         //ndim dimension equal to zero and sum the ndim
1663                         //dimension of all input ports of target block
1664                         //to be the new dimension of the ndim dimension
1665                         //of the output ports of the target block
1666                         if ndim==1 then
1667                             ww=find(bllst(connectmat(jj,3)).out==0)
1668                             if (ww<>[]&min(bllst(connectmat(jj,3)).in(:))>0) then
1669                                 bllst(connectmat(jj,3)).out(ww)=sum(bllst(connectmat(jj,3)).in(:))
1670                             end
1671                         elseif ndim==2 then
1672                             ww=find(bllst(connectmat(jj,3)).out2==0)
1673                             if (ww<>[]&min(bllst(connectmat(jj,3)).in2(:))>0) then
1674                                 bllst(connectmat(jj,3)).out2(ww)=sum(bllst(connectmat(jj,3)).in2(:))
1675                             end
1676                         end
1677
1678                         //if nzcross of the target block match with
1679                         //the negative dimension nin(1,ndim) then
1680                         //adjust it to nout(1,ndim)
1681                         if bllst(connectmat(jj,3)).nzcross==nin(1,ndim) then
1682                             bllst(connectmat(jj,3)).nzcross=nout(1,ndim)
1683                         end
1684                         //if nmode of the target block match with
1685                         //the negative dimension nin(1,ndim) then
1686                         //adjust it to nout(1,ndim)
1687                         if bllst(connectmat(jj,3)).nmode==nin(1,ndim) then
1688                             bllst(connectmat(jj,3)).nmode=nout(1,ndim)
1689                         end
1690
1691                         //third case : dimension of source port is
1692                         //             negative and dimension of
1693                         //             target port is positive
1694                     elseif(nout(1,ndim)<0&nin(1,ndim)>0) then
1695                         //find vector of output ports of source block with
1696                         //first/second dimension equal to size nout(1,ndim)
1697                         //and assign it to nin(1,ndim)
1698                         ww=find(bllst(connectmat(jj,1)).out==nout(1,ndim))
1699                         bllst(connectmat(jj,1)).out(ww)=nin(1,ndim)
1700                         ww=find(bllst(connectmat(jj,1)).out2==nout(1,ndim))
1701                         bllst(connectmat(jj,1)).out2(ww)=nin(1,ndim)
1702
1703                         //find vector of input ports of source block with
1704                         //first/second dimension equal to size nout(1,ndim)
1705                         //and assign it to nin(1,ndim)
1706                         ww=find(bllst(connectmat(jj,1)).in==nout(1,ndim))
1707                         bllst(connectmat(jj,1)).in(ww)=nin(1,ndim)
1708                         ww=find(bllst(connectmat(jj,1)).in2==nout(1,ndim))
1709                         bllst(connectmat(jj,1)).in2(ww)=nin(1,ndim)
1710
1711                         //find vector of input ports of source block with
1712                         //ndim dimension equal to zero and sum the ndim
1713                         //dimension of all output ports of source block
1714                         //to be the new dimension of the ndim dimension
1715                         //of the input ports of the source block
1716                         if ndim==1 then
1717                             ww=find(bllst(connectmat(jj,1)).in==0)
1718                             if (ww<>[]&min(bllst(connectmat(jj,1)).out(:))>0) then
1719                                 bllst(connectmat(jj,1)).in(ww)=sum(bllst(connectmat(jj,1)).out(:))
1720                             end
1721                         elseif ndim==2 then
1722                             ww=find(bllst(connectmat(jj,1)).in2==0)
1723                             if (ww<>[]&min(bllst(connectmat(jj,1)).out2(:))>0) then
1724                                 bllst(connectmat(jj,1)).in2(ww)=sum(bllst(connectmat(jj,1)).out2(:))
1725                             end
1726                         end
1727
1728                         //if nzcross of the source block match with
1729                         //the negative dimension nout(1,ndim) then
1730                         //adjust it to nin(1,ndim)
1731                         if bllst(connectmat(jj,1)).nzcross==nout(1,ndim) then
1732                             bllst(connectmat(jj,1)).nzcross=nin(1,ndim)
1733                         end
1734                         //if nmode of the source block match with
1735                         //the negative dimension nout(1,ndim) then
1736                         //adjust it to nin(1,ndim)
1737                         if bllst(connectmat(jj,1)).nmode==nout(1,ndim) then
1738                             bllst(connectmat(jj,1)).nmode=nin(1,ndim)
1739                         end
1740
1741                         //fourth case : a dimension of source port is
1742                         //              null
1743                     elseif(nout(1,ndim)==0) then
1744                         //set ww to be the vector of size of the ndim
1745                         //dimension of input port of the source block
1746                         if ndim==1 then
1747                             ww=bllst(connectmat(jj,1)).in(:)
1748                         elseif ndim==2 then
1749                             ww=bllst(connectmat(jj,1)).in2(:)
1750                         end
1751
1752                         //test if all size of the ndim dimension of input
1753                         //port of the source block is positive
1754                         if min(ww)>0 then
1755                             //test if the dimension of the target port
1756                             //is positive
1757                             if nin(1,ndim)>0 then
1758
1759                                 //if the sum of the size of the ndim dimension of the input
1760                                 //port of the source block is equal to the size of the ndim dimension
1761                                 //of the target port, then the size of the ndim dimension of the source
1762                                 //port is equal to nin(1,ndim)
1763                                 if sum(ww)==nin(1,ndim) then
1764                                     if ndim==1 then
1765                                         bllst(connectmat(jj,1)).out(connectmat(jj,2))=nin(1,ndim)
1766                                     elseif ndim==2 then
1767                                         bllst(connectmat(jj,1)).out2(connectmat(jj,2))=nin(1,ndim)
1768                                     end
1769                                     //else call bad_connection, set flag ok to false and exit
1770                                 else
1771                                     bad_connection(corinv(connectmat(jj,1)),0,0,1,-1,0,0,1)
1772                                     ok=%f;return
1773                                 end
1774
1775                                 //if the ndim dimension of the target port is negative
1776                                 //then the size of the ndim dimension of the source port
1777                                 //is equal to the sum of the size of the ndim dimension
1778                                 //of input ports of source block, and flag ok is set to false
1779                             else
1780                                 if ndim==1 then
1781                                     bllst(connectmat(jj,1)).out(connectmat(jj,2))=sum(ww)
1782                                 elseif ndim==2 then
1783                                     bllst(connectmat(jj,1)).out2(connectmat(jj,2))=sum(ww)
1784                                 end
1785                                 ok=%f
1786                             end
1787
1788                         else
1789                             //set nww to be the vector of all negative size of input ports
1790                             //of the source block
1791                             nww=ww(find(ww<0))
1792
1793                             //if all negative size have same size and if size of the
1794                             //ndim dimension of the target port is positive then assign
1795                             //size of the ndim dimension of the source port to nin(1,ndim)
1796                             if norm(nww-nww(1),1)==0 & nin(1,ndim)>0 then
1797                                 if ndim==1 then
1798                                     bllst(connectmat(jj,1)).out(connectmat(jj,2))=nin(1,ndim)
1799                                 elseif ndim==2 then
1800                                     bllst(connectmat(jj,1)).out2(connectmat(jj,2))=nin(1,ndim)
1801                                 end
1802
1803                                 //compute a size to be the difference between the size
1804                                 //of the ndim dimension of the target block and sum of positive
1805                                 //size of input ports of the source block divided by the number
1806                                 //of input ports of source block with same negative size
1807                                 k=(nin(1,ndim)-sum(ww(find(ww>0))))/size(nww,"*")
1808
1809                                 //if this size is a positive integer then assign it
1810                                 //to the size of the ndim dimension of input ports of the
1811                                 //source block which have negative size
1812                                 if k==int(k)&k>0 then
1813                                     if ndim==1 then
1814                                         bllst(connectmat(jj,1)).in(find(ww<0))=k
1815                                     elseif ndim==2 then
1816                                         bllst(connectmat(jj,1)).in2(find(ww<0))=k
1817                                     end
1818                                     //else call bad_connection, set flag ok to false and exit
1819                                 else
1820                                     bad_connection(corinv(connectmat(jj,1)),0,0,1,-1,0,0,1)
1821                                     ok=%f;return
1822                                 end
1823
1824                                 //set flag ok to false
1825                             else
1826                                 ok=%f
1827                             end
1828
1829                         end
1830
1831                         //fifth case : a dimension of target port is
1832                         //             null
1833                     elseif(nin(1,ndim)==0) then
1834                         //set ww to be the vector of size of the ndim
1835                         //dimension of output port of the target block
1836                         if ndim==1 then
1837                             ww=bllst(connectmat(jj,3)).out(:)
1838                         elseif ndim==2 then
1839                             ww=bllst(connectmat(jj,3)).out2(:)
1840                         end
1841
1842                         //test if all size of the ndim dimension of output
1843                         //port of the target block is positive
1844                         if min(ww)>0 then
1845                             //test if the dimension of the source port
1846                             //is positive
1847                             if nout(1,ndim)>0 then
1848
1849                                 //if the sum of the size of the ndim dimension of the output
1850                                 //port of the target block is equal to the size of the ndim dimension
1851                                 //of the source port, then the size of the ndim dimension of the target
1852                                 //port is equal to nout(1,ndim)
1853                                 if sum(ww)==nout(1,ndim) then
1854                                     if ndim==1 then
1855                                         bllst(connectmat(jj,3)).in(connectmat(jj,4))=nout(1,ndim)
1856                                     elseif ndim==2 then
1857                                         bllst(connectmat(jj,3)).in2(connectmat(jj,4))=nout(1,ndim)
1858                                     end
1859                                     //else call bad_connection, set flag ok to false and exit
1860                                 else
1861                                     bad_connection(corinv(connectmat(jj,3)),0,0,1,-1,0,0,1)
1862                                     ok=%f;return
1863                                 end
1864
1865                                 //if the ndim dimension of the source port is negative
1866                                 //then the size of the ndim dimension of the target port
1867                                 //is equal to the sum of the size of the ndim dimension
1868                                 //of output ports of target block, and flag ok is set to false
1869                             else
1870                                 if ndim==1 then
1871                                     bllst(connectmat(jj,3)).in(connectmat(jj,4))=sum(ww)
1872                                 elseif ndim==2 then
1873                                     bllst(connectmat(jj,3)).in2(connectmat(jj,4))=sum(ww)
1874                                 end
1875                                 ok=%f
1876                             end
1877
1878                         else
1879                             //set nww to be the vector of all negative size of output ports
1880                             //of the target block
1881                             nww=ww(find(ww<0))
1882
1883                             //if all negative size have same size and if size of the
1884                             //ndim dimension of the source port is positive then assign
1885                             //size of the ndim dimension of the target port to nout(1,ndim)
1886                             if norm(nww-nww(1),1)==0 & nout(1,ndim)>0 then
1887                                 if ndim==1 then
1888                                     bllst(connectmat(jj,3)).in(connectmat(jj,4))=nout(1,ndim)
1889                                 elseif ndim==2 then
1890                                     bllst(connectmat(jj,3)).in2(connectmat(jj,4))=nout(1,ndim)
1891                                 end
1892
1893                                 //compute a size to be the difference between the size
1894                                 //of the ndim dimension of the source block and sum of positive
1895                                 //size of output ports of the target block divided by the number
1896                                 //of output ports of target block with same negative size
1897                                 k=(nout(1,ndim)-sum(ww(find(ww>0))))/size(nww,"*")
1898
1899                                 //if this size is a positive integer then assign it
1900                                 //to the size of the ndim dimension of output ports of the
1901                                 //target block which have negative size
1902                                 if k==int(k)&k>0 then
1903                                     if ndim==1 then
1904                                         bllst(connectmat(jj,3)).out(find(ww<0))=k
1905                                     elseif ndim==2 then
1906                                         bllst(connectmat(jj,3)).out2(find(ww<0))=k
1907                                     end
1908                                     //else call bad_connection, set flag ok to false and exit
1909                                 else
1910                                     bad_connection(corinv(connectmat(jj,3)),0,0,1,-1,0,0,1)
1911                                     ok=%f;return
1912                                 end
1913
1914                                 //set flag ok to false
1915                             else
1916                                 ok=%f
1917                             end
1918
1919                         end
1920
1921                         //sixth (& last) case : dimension of both source
1922                         //                      and target port are negatives
1923                     else
1924                         ok=%f //set flag ok to false
1925                     end
1926                 end
1927             end
1928             if ok then return, end //if ok is set true then exit adjust_inout
1929         end
1930         //if failed then display message
1931         messagebox(msprintf(_("Not enough information to find port sizes.\n"+..
1932         "I try to find the problem.")),"modal","info");
1933
1934         //%%%%% pass 2 %%%%%//
1935         //Alan 19/01/07 : Warning  : Behavior have changed, To Be more Tested
1936         findflag=%f //set findflag to false
1937
1938         for jj=1:nlnk //loop on number of block
1939             //nin/nout are the size (two dimensions) of the
1940             //target port and the source port of the observed link
1941             nout(1,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2))
1942             nout(1,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2))
1943             nin(1,1)=bllst(connectmat(jj,3)).in(connectmat(jj,4))
1944             nin(1,2)=bllst(connectmat(jj,3)).in2(connectmat(jj,4))
1945
1946             //loop on the two dimensions of source/target port
1947             //only case : target and source ports are both
1948             //            negatives or null
1949             if nout(1,1)<=0&nin(1,1)<=0 | nout(1,2)<=0&nin(1,2)<=0 then
1950                 findflag=%t;
1951                 //
1952                 ninnout=under_connection(corinv(connectmat(jj,1)),connectmat(jj,2),nout(1,ndim),..
1953                 corinv(connectmat(jj,3)),connectmat(jj,4),nin(1,ndim),1)
1954                 //
1955                 if size(ninnout,2) <> 2 then ok=%f;return;end
1956                 if ninnout==[] then ok=%f;return;end
1957                 if ninnout(1,1)<=0 | ninnout(1,2)<=0 then ok=%f;return;end
1958                 //
1959                 ww=find(bllst(connectmat(jj,1)).out==nout(1,1))
1960                 bllst(connectmat(jj,1)).out(ww)=ninnout(1,1)
1961                 ww=find(bllst(connectmat(jj,1)).out2==nout(1,1))
1962                 bllst(connectmat(jj,1)).out2(ww)=ninnout(1,1)
1963
1964                 ww=find(bllst(connectmat(jj,1)).out==nout(1,2))
1965                 bllst(connectmat(jj,1)).out(ww)=ninnout(1,2)
1966                 ww=find(bllst(connectmat(jj,1)).out2==nout(1,2))
1967                 bllst(connectmat(jj,1)).out2(ww)=ninnout(1,2)
1968                 //
1969
1970                 if bllst(connectmat(jj,1)).nzcross==nout(1,1) then
1971                     bllst(connectmat(jj,1)).nzcross=ninnout(1,1)
1972                 end
1973                 if bllst(connectmat(jj,1)).nzcross==nout(1,2) then
1974                     bllst(connectmat(jj,1)).nzcross=ninnout(1,2)
1975                 end
1976                 //
1977                 if bllst(connectmat(jj,1)).nmode==nout(1,1) then
1978                     bllst(connectmat(jj,1)).nmode=ninnout(1,1)
1979                 end
1980                 if bllst(connectmat(jj,1)).nmode==nout(1,2) then
1981                     bllst(connectmat(jj,1)).nmode=ninnout(1,2)
1982                 end
1983                 //
1984                 ww=find(bllst(connectmat(jj,1)).in==nout(1,1))
1985                 bllst(connectmat(jj,1)).in(ww)=ninnout(1,1)
1986                 ww=find(bllst(connectmat(jj,1)).in2==nout(1,1))
1987                 bllst(connectmat(jj,1)).in2(ww)=ninnout(1,1)
1988
1989                 ww=find(bllst(connectmat(jj,1)).in==nout(1,2))
1990                 bllst(connectmat(jj,1)).in(ww)=ninnout(1,2)
1991                 ww=find(bllst(connectmat(jj,1)).in2==nout(1,2))
1992                 bllst(connectmat(jj,1)).in2(ww)=ninnout(1,2)
1993                 //
1994                 ww=find(bllst(connectmat(jj,1)).in==0)
1995                 if (ww<>[]&min(bllst(connectmat(jj,1)).out(:))>0) then
1996                     bllst(connectmat(jj,1)).in(ww)=sum(bllst(connectmat(jj,1)).out)
1997                 end
1998
1999                 ww=find(bllst(connectmat(jj,1)).in2==0)
2000                 if (ww<>[]&min(bllst(connectmat(jj,1)).out2(:))>0) then
2001                     bllst(connectmat(jj,1)).in2(ww)=sum(bllst(connectmat(jj,1)).out2)
2002                 end
2003                 //
2004                 ww=find(bllst(connectmat(jj,3)).in==nin(1,1))
2005                 bllst(connectmat(jj,3)).in(ww)=ninnout(1,1)
2006                 ww=find(bllst(connectmat(jj,3)).in2==nin(1,1))
2007                 bllst(connectmat(jj,3)).in2(ww)=ninnout(1,1)
2008
2009                 ww=find(bllst(connectmat(jj,3)).in==nin(1,2))
2010                 bllst(connectmat(jj,3)).in(ww)=ninnout(1,2)
2011                 ww=find(bllst(connectmat(jj,3)).in2==nin(1,2))
2012                 bllst(connectmat(jj,3)).in2(ww)=ninnout(1,2)
2013                 //
2014                 if bllst(connectmat(jj,3)).nzcross==nin(1,1) then
2015                     bllst(connectmat(jj,3)).nzcross=ninnout(1,1)
2016                 end
2017                 if bllst(connectmat(jj,3)).nzcross==nin(1,2) then
2018                     bllst(connectmat(jj,3)).nzcross=ninnout(1,2)
2019                 end
2020                 if bllst(connectmat(jj,3)).nmode==nin(1,1) then
2021                     bllst(connectmat(jj,3)).nmode=ninnout(1,1)
2022                 end
2023                 if bllst(connectmat(jj,3)).nmode==nin(1,2) then
2024                     bllst(connectmat(jj,3)).nmode=ninnout(1,2)
2025                 end
2026                 //
2027                 ww=find(bllst(connectmat(jj,3)).out==nin(1,1))
2028                 bllst(connectmat(jj,3)).out(ww)=ninnout(1,1)
2029                 ww=find(bllst(connectmat(jj,3)).out2==nin(1,1))
2030                 bllst(connectmat(jj,3)).out2(ww)=ninnout(1,1)
2031
2032                 ww=find(bllst(connectmat(jj,3)).out==nin(1,2))
2033                 bllst(connectmat(jj,3)).out(ww)=ninnout(1,2)
2034                 ww=find(bllst(connectmat(jj,3)).out2==nin(1,2))
2035                 bllst(connectmat(jj,3)).out2(ww)=ninnout(1,2)
2036                 //
2037                 ww=find(bllst(connectmat(jj,3)).out==0)
2038                 if (ww<>[]&min(bllst(connectmat(jj,3)).in(:))>0) then
2039                     bllst(connectmat(jj,3)).out(ww)=sum(bllst(connectmat(jj,3)).in(:))
2040                 end
2041                 ww=find(bllst(connectmat(jj,3)).out2==0)
2042                 if (ww<>[]&min(bllst(connectmat(jj,3)).in2(:))>0) then
2043                     bllst(connectmat(jj,3)).out2(ww)=sum(bllst(connectmat(jj,3)).in2(:))
2044                 end
2045             end
2046         end
2047
2048         //if failed then display message
2049         if ~findflag then
2050             messagebox(msprintf(_("I cannot find a link with undetermined size.\n"+..
2051             "My guess is that you have a block with unconnected \n"+..
2052             "undetermined output ports.")),"modal","error");
2053             ok=%f;return;
2054         end
2055     end
2056 endfunction
2057
2058 function id = getBlockIds(path)
2059     // Return a block id path from a block index path
2060     //
2061     // path: the path in the index form
2062     // id: th path in the uid form
2063
2064     scs_m; // check scs_m access
2065     id=[];
2066
2067     k = path(:);
2068     for i = k
2069         b = scs_m.objs(i);
2070         if typeof(b) == "Block" &  length(scs_m.objs(i).model.uid) >= 1 then
2071             id($ + 1) = scs_m.objs(i).model.uid;
2072         end
2073         if typeof(b.model.rpar) == "diagram" then
2074             scs_m = b.model.rpar;
2075         end
2076     end
2077 endfunction
2078
2079 //19/01/07, Alan : under_connection show bad link and returns two dimensions now
2080 function ninnout=under_connection(path_out,prt_out,nout,path_in,prt_in,nin,flagg)
2081     // alert for badly connected blocks
2082     // path_out : Path of the "from block" in scs_m
2083     // path_in  : Path of the "to block" in scs_m
2084     //!
2085
2086     if path_in==-1 then
2087         msg = "<html><body>";
2088         msg = msg + gettext("One of this block output has negative size.<br />Please check.");
2089         msg = msg + "</body></html>";
2090         hilite_path(path_out, msg);
2091         ninnout=0
2092         return
2093     end
2094
2095     if path_in==-2 then
2096         msg = "<html><body>";
2097         msg = msg + gettext("Block input has negative size:");
2098         msg = msg + "<ul>";
2099         msg = msg + "<li>" + msprintf(gettext("Input port %s size is: %s"), string(prt_out), sci2exp(nout)) + "</li>";
2100         msg = msg + "</ul>";
2101         msg = msg + "</body></html>";
2102         hilite_path(path_out, msg);
2103         ninnout=0
2104         return
2105     end
2106
2107     // different use case (Unable to report on a non opened diagram)
2108     if isdef("Code_gene_run") then
2109         messagebox([gettext("Unable to report an error into a SuperBlock"); gettext("Please compile the diagram to report the error.")], "Compilation error", "error", "modal");
2110         ninnout=0
2111         return
2112     end
2113
2114     msg = "<html><body>";
2115     if flagg==1 then
2116         msg = msg + gettext("<em>Please update the diagram to avoid this warning.</em><br />Block output port has a non-determined size:");
2117         msg = msg + "<ul>";
2118         msg = msg + "<li>" + msprintf(gettext("Output port %s size is: %s"), string(prt_out), sci2exp(nout)) + "</li>";
2119         msg = msg + "<li>" + msprintf(gettext("Input port %s size is: %s"), string(prt_in), sci2exp(nin)) + "</li>";
2120     else
2121         msg = msg + gettext("<em>Please update the diagram to avoid this warning.</em><br />Block output port has a non-determined type:");
2122         msg = msg + "<ul>";
2123         msg = msg + "<li>" + msprintf(gettext("Output port %s type."), string(prt_out)) + "</li>";
2124         msg = msg + "<li>" + msprintf(gettext("Input port %s type."), string(prt_in)) + "</li>";
2125     end
2126     msg = msg + "</ul>";
2127     msg = msg + "</body></html>";
2128     hilite_path(path_out, msg)
2129
2130     if or(path_in<>path_out) then
2131         msg = "<html><body>";
2132         if flagg==1 then
2133             msg = msg + gettext("<em>Please update the diagram to avoid this warning.</em><br />Block input port has a non-determined size:");
2134             msg = msg + "<ul>";
2135             msg = msg + "<li>" + msprintf(gettext("Output port %s size is: %s"), string(prt_out), sci2exp(nout)) + "</li>";
2136             msg = msg + "<li>" + msprintf(gettext("Input port %s size is: %s"), string(prt_in), sci2exp(nin)) + "</li>";
2137         else
2138             msg = msg + gettext("<em>Please update the diagram to avoid this warning.</em><br />Block input port has a non-determined type:");
2139             msg = msg + "<ul>";
2140             msg = msg + "<li>" + msprintf(gettext("Output port %s type."), string(prt_out)) + "</li>";
2141             msg = msg + "<li>" + msprintf(gettext("Input port %s type."), string(prt_in)) + "</li>";
2142         end
2143         msg = msg + "</ul>";
2144         msg = msg + "</body></html>";
2145         hilite_path(path_in, msg)
2146     end
2147
2148     mess=msprintf(_("Highlighted block(s) have connected ports \nwith  sizes that cannot be determined by the context.\nWhat is the size of this link?"))
2149
2150     if flagg==1 then
2151         ninnout=evstr(dialog(mess,"[1,1]"))
2152     else
2153         ninnout=evstr(dialog(mess,"1"))
2154     end
2155 endfunction
2156
2157 function [clkconnect,exe_cons]=pak_ersi(connectmat,clkconnect,..
2158     typ_r,typ_l,outoin,outoinptr,tblock,typ_cons,clkptr)
2159
2160     //add every event to the time event because time includes all events
2161     all_out=[]
2162     for k=1:size(clkptr,1)-1
2163         if ~typ_l(k) then
2164             kk=[1:(clkptr(k+1)-clkptr(k))]'
2165             all_out=[all_out;[k*ones(kk),kk]]
2166         end
2167     end
2168     all_out=[all_out;[0,0]]
2169
2170     //add time event if needed
2171     ind=find(tblock)
2172     ind=ind(:)
2173     for k=ind'
2174         clkconnect=[clkconnect;[all_out,ones(all_out)*[k,0;0,0]]]
2175     end
2176     if show_trace then mprintf("c_pass4444:\t%f\n", timer()),end
2177     ind1=find(typ_cons)
2178     ind=[ind;ind1(:)]
2179     exe_cons=[ind,zeros(ind)]
2180
2181     vec=-ones(1,nblk);
2182     vec(ind)=0
2183     [r,ok]=newc_tree4(vec,outoin,outoinptr,typ_r)
2184
2185     exe_cons=[exe_cons;r]
2186
2187     if show_trace then mprintf("c_pass4445:\t%f\n", timer()),end
2188
2189     [clkr,clkc]=size(clkconnect);
2190     if isempty(clkconnect) then
2191         cll=[];
2192     else
2193         mm=max(clkconnect(:,2))+1;
2194         cll=clkconnect(:,1)*mm+clkconnect(:,2);
2195     end
2196     [cll,ind]=gsort(-cll);
2197     clkconnect=clkconnect(ind,:);
2198     if cll<>[] then mcll=max(-cll)+1, else mcll=1;end
2199     cll=[-1;-cll;mcll];
2200     ii=find(cll(2:$)-cll(1:$-1)<>0)
2201
2202     for k=1:size(ii,"*")-1
2203         oo=[ii(k):ii(k+1)-1]
2204         vec=-ones(1,nblk);
2205         vec(clkconnect(oo,3))=0
2206         [r,ok]=newc_tree4(vec,outoin,outoinptr,typ_r)
2207         m=size(r,1)
2208         r=[clkconnect(ii(k),1)*ones(m,1),clkconnect(ii(k),2)*ones(m,1),r]
2209         clkconnect=[clkconnect;r]
2210     end
2211     // temporary fix to take care of conditional blocks inherting from
2212     // constants: make these blocks always active
2213
2214     ind=setdiff(find(typ_l),clkconnect(:,3))
2215     ind=ind(:)
2216     for k=ind'
2217         clkconnect=[clkconnect;[all_out,ones(all_out)*[k,0;0,0]]]
2218     end
2219     // end of  temoprary fix
2220     if show_trace then mprintf("c_pass4446:\t%f\n", timer()),end
2221 endfunction
2222
2223 function [r,ok]=tree4(vec,outoin,outoinptr,typ_r)
2224     //compute blocks which inherit
2225     ok=%t;
2226     nb=size(vec,"*");
2227     r=[];
2228     for j=1:nb-1
2229         fini=%t
2230         for i=1:nb
2231             if vec(i)==j-1 then
2232                 for k=outoinptr(i):outoinptr(i+1)-1
2233                     ii=outoin(k,1);
2234                     if (vec(ii)>-1)|typ_r(ii) then
2235                         fini=%f;
2236                         vec(ii)=j;
2237                     end
2238                     if typ_r(ii) then
2239                         r=[r;outoin(k,:)]
2240                     end
2241                 end
2242             end
2243         end
2244         if fini then break;end
2245     end
2246 endfunction
2247
2248 function [bllst,inplnk,outlnk,clkptr,cliptr,inpptr,outptr,dep_u,dep_uptr,dep_t,..
2249     typ_l,typ_r,typ_m,tblock,typ_cons,typ_zx,ok]=mini_extract_info(bllst,..
2250     connectmat,clkconnect)
2251     ok=%t
2252     nbl=length(bllst)
2253     clkptr=zeros(nbl+1,1);clkptr(1)=1
2254     cliptr=clkptr;inpptr=cliptr;outptr=inpptr;
2255     fff=ones(nbl,1)==1
2256     typ_l=fff;typ_r=fff;typ_cons=fff;typ_m=fff;typ_zx=fff;
2257     dep_t=ones(nbl,1)==1;
2258     dep_u=[];dep_uptr=1;
2259     tblock=fff
2260     //tblock=[]  // specifies blocks that must be connected to time event.
2261     //
2262     for i=1:nbl
2263         ll=bllst(i)
2264         if (ll.state==[]&ll.nzcross==0) then typ_zx(i)=%f;end
2265         inpnum=ll.in;outnum=ll.out;cinpnum=ll.evtin;coutnum=ll.evtout;
2266         //
2267         if cinpnum==[] then
2268             // this block inherits
2269             //ok=%f
2270
2271             typ_r(i)=~ll.dep_ut($)
2272             tblock(i)=ll.dep_ut($)
2273             //if block depends on time but has no event input port
2274             if ~ll.dep_ut($) then
2275                 //inherits from the inputs
2276                 cinpnum=ones(inpnum)
2277                 bllst(i).evtin=cinpnum  //XXXXXXXXXXXXXXXXXXXXX
2278             end
2279             //
2280         else
2281             tblock(i)=ll.dep_ut($);typ_r(i)=%f
2282         end
2283         inpptr(i+1)=inpptr(i)+size(inpnum,"*")
2284         outptr(i+1)=outptr(i)+size(outnum,"*")
2285         cliptr(i+1)=cliptr(i)+size(cinpnum,"*")
2286         clkptr(i+1)=clkptr(i)+size(coutnum,"*")
2287         //
2288
2289         typ_l(i)=ll.blocktype=="l";typ_m(i)=ll.blocktype=="m";
2290         typ_cons(i)=cinpnum==[]&inpnum==[]&~ll.dep_ut($)
2291         //test of the dep_ut size
2292         sizenin=size(ll.in,"*");
2293         if (size(ll.dep_ut,"*") <> 2) then
2294             if ( size(ll.dep_ut(1:$-1),"*") <> sizenin) then
2295                 messagebox(msprintf(_("the dep_ut size of the %s block is not correct.\n"+..
2296                 "It should be a colon vector of size %d."),..
2297                 ll.sim(1),sizenin+1),"modal","error");
2298                 ok=%f;
2299             end
2300         end
2301
2302         dep_t(i)=ll.dep_ut($);
2303
2304         if (size(ll.dep_ut,"*") == 2) then
2305             if (sizenin == 1) then
2306                 dep_u($+1)=ll.dep_ut(1);
2307                 dep_uptr($+1)=dep_uptr($)+1;
2308             elseif (sizenin > 1) then
2309                 dep_u=[dep_u;ones(sizenin,1)==1*ll.dep_ut(1)];
2310                 dep_uptr($+1)=dep_uptr($)+sizenin;
2311             else
2312                 dep_uptr($+1)=dep_uptr($);
2313             end
2314         else
2315             dep_u_i=ll.dep_ut(1:$-1);
2316             dep_u=[dep_u;dep_u_i(:)];
2317             dep_uptr($+1)=dep_uptr($)+sizenin;
2318         end
2319
2320         //
2321     end
2322     if show_trace then mprintf("c_pass22222222:\t%f\n", timer()),end //'
2323     nlnk=size(connectmat,1)
2324     inplnk=zeros(inpptr($)-1,1);outlnk=zeros(outptr($)-1,1);ptlnk=1;
2325
2326     for jj=1:nlnk
2327         ko=outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)
2328         ki=inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)
2329         if ko<>0 & ki<>0 then
2330             if ko>ki then
2331                 outlnk(outlnk>ko)=outlnk(outlnk>ko)-1
2332                 outlnk(outlnk==ko)=ki
2333                 inplnk(inplnk>ko)=inplnk(inplnk>ko)-1
2334                 inplnk(inplnk==ko)=ki
2335                 ptlnk=-1+ptlnk
2336             elseif ki>ko
2337                 outlnk(outlnk>ki)=outlnk(outlnk>ki)-1
2338                 outlnk(outlnk==ki)=ko
2339                 inplnk(inplnk>ki)=inplnk(inplnk>ki)-1
2340                 inplnk(inplnk==ki)=ko
2341                 ptlnk=-1+ptlnk
2342             end
2343         elseif ko<>0 then
2344             inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)=ko
2345         elseif ki<>0 then
2346             outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)=ki
2347         else
2348             outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)=ptlnk
2349             inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)=ptlnk
2350             ptlnk=1+ptlnk
2351         end
2352     end
2353
2354     //store unconnected outputs, if any, at the end of outtb
2355     for unco=find(outlnk==0);
2356         outlnk(unco)=max(outlnk)+1
2357     end
2358
2359     //store unconnected inputs, if any, at the end of outtb
2360     for unco=find(inplnk==0);
2361         inplnk(unco)=max([inplnk;max(outlnk)])+1
2362     end
2363 endfunction
2364
2365 function [evoutoin,evoutoinptr]=synch_clkconnect(typ_l,clkconnect)
2366     nblk=size(typ_l,"*")
2367     evoutoin=[];evoutoinptr=1
2368     for i=1:nblk
2369         if typ_l(i) then
2370             dd=clkconnect(clkconnect(:,1)==i,3)
2371         else
2372             dd=[]
2373         end
2374         evoutoin=[evoutoin;dd]
2375         evoutoinptr=[evoutoinptr;evoutoinptr($)+size(dd,"*")]
2376     end
2377 endfunction
2378
2379 function   clkconnect=cleanup(clkconnect)
2380     mm=max(clkconnect)+1
2381     cc=clkconnect(:,4)+mm*clkconnect(:,3)+clkconnect(:,2)*mm^2+..
2382     clkconnect(:,1)*mm^3
2383     [cc1,ind]=gsort(-cc)
2384     clkconnect=clkconnect(ind,:)
2385     ind=find(cc1(2:$)-cc1(1:$-1)==0)
2386     clkconnect(ind,:)=[]
2387 endfunction
2388
2389 //function mat=cleanup1(mat)
2390 //  mm=max(mat)+1
2391 //  cc=mat(:,1)*mm
2392 //  [cc1,ind]=gsort(-cc)
2393 //  mat=mat(ind,:)
2394 //  ind=find(cc1(2:$)-cc1(1:$-1)==0)
2395 //  mat(ind,:)=[]
2396 //endfunction
2397
2398 function vec=intersection(vec1,vec2)
2399     vec=[]
2400     for i=1:size(vec1,1)
2401         if find(vec1(i)==vec2)~=[] then
2402             vec=[vec;vec1(i)]
2403         end
2404     end
2405 endfunction
2406
2407 function  [r,ok]=newc_tree2(vec,outoin,outoinptr,dep_u,dep_uptr)
2408     dd=zeros(dep_u);dd(dep_u)=1;
2409     [r,ok2]=ctree2(vec,outoin,outoinptr,dd,dep_uptr)
2410     ok=ok2==1
2411 endfunction
2412
2413 function  [r,ok]=new_tree2(vec,outoin,outoinptr,dep_u,dep_uptr)
2414     dd=zeros(dep_u);dd(dep_u)=1;
2415     [r,ok2]=sci_tree2(vec,outoin,outoinptr,dd)
2416     ok=ok2==1
2417 endfunction
2418
2419 function  [r,ok]=new_tree3(vec,dep_ut,typ_l)
2420     dd=zeros(dep_ut);dd(dep_ut)=1;
2421     [r2,ok2]=sci_tree3(vec,dd,typ_l,bexe,boptr,blnk,blptr)
2422     r=r2'
2423     ok=ok2==1
2424 endfunction
2425
2426 function  [r,ok]=newc_tree3(vec,dep_u,dep_uptr,typ_l)
2427     dd=zeros(dep_u);dd(dep_u)=1;
2428     [r2,ok2]=ctree3(vec,dd,dep_uptr,typ_l,bexe,boptr,blnk,blptr)
2429     r=r2'
2430     ok=ok2==1
2431 endfunction
2432
2433 function  [r,ok]=new_tree4(vec,outoin,outoinptr,typ_r)
2434     if isempty(outoin) then
2435         nd=zeros(size(vec,"*"),1);
2436     else
2437         nd=zeros(size(vec,"*"),(max(outoin(:,2))+1));
2438     end
2439     ddd=zeros(typ_r);ddd(typ_r)=1;
2440     [r1,r2]=sci_tree4(vec,outoin,outoinptr,nd,ddd)
2441     r=[r1',r2']
2442     ok=%t
2443 endfunction
2444
2445 function  [r,ok]=newc_tree4(vec,outoin,outoinptr,typ_r)
2446     if isempty(outoin) then
2447         nd=zeros(size(vec,"*"),1);
2448     else
2449         nd=zeros(size(vec,"*"),(max(outoin(:,2))+1));
2450     end
2451     ddd=zeros(typ_r);ddd(typ_r)=1;
2452     [r1,r2]=ctree4(vec,outoin,outoinptr,nd,ddd)
2453     r=[r1',r2']
2454     ok=%t
2455 endfunction
2456
2457 function [critev]=critical_events(connectmat,clkconnect,dep_t,typ_r,..
2458     typ_l,typ_zx,outoin,outoinptr,clkptr)
2459
2460     if isempty(clkconnect) then
2461         critev = [];
2462         return
2463     end
2464
2465     typ_c=typ_l<>typ_l;
2466     typ_r=typ_r|dep_t
2467
2468     done1=%f
2469     while ~done1
2470         done1=%t
2471         [clkr,clkc]=size(clkconnect);
2472         mm=max(clkconnect)+1;
2473
2474         cll=clkconnect(:,1)*mm+clkconnect(:,2);
2475         [cll,ind]=gsort(-cll);
2476         clkconnect=clkconnect(ind,:);
2477         cll=[-1;-cll;mm];
2478         ii=find(cll(2:$)-cll(1:$-1)<>0)
2479
2480         for k=1:size(ii,"*")-1
2481             oo=[ii(k):ii(k+1)-1]
2482             vec=-ones(1,nblk);
2483             vec(clkconnect(oo,3))=0
2484             [r,ok]=newc_tree4(vec,outoin,outoinptr,typ_r)
2485
2486             m=size(r,1)
2487             r=[clkconnect(ii(k),1)*ones(m,1),clkconnect(ii(k),2)*ones(m,1),r]
2488             clkconnect=[clkconnect;r]
2489         end
2490
2491         done=%f;
2492         while ~done
2493             done=%t;
2494             for jj=find(typ_l&(~typ_c));
2495                 if ~or(jj==clkconnect(:,3)) then
2496                     typ_r(clkconnect(find(jj==clkconnect(:,1)),3))=%t
2497                     clkconnect(find(jj==clkconnect(:,1)),:)=[];
2498                     typ_c(jj)=%t;
2499                     done1=%f
2500                     done=%f
2501                 end
2502             end
2503         end
2504     end
2505     critev=zeros(clkptr($)-1,1);
2506     for bb=1:size(clkptr,1)-1
2507         for i=clkptr(bb):clkptr(bb+1)-1
2508             if or(typ_zx(clkconnect(find((clkconnect(:,1)==bb)&..
2509                 (clkconnect(:,2)==i-clkptr(bb)+1)),3))) then
2510                 critev(i)=1
2511             end
2512         end
2513     end
2514 endfunction
2515
2516 // adjust_typ: It resolves positive and negative port types.
2517 //                 Its Algorithm is based on the algorithm of adjust_inout
2518 // Fady NASSIF: 14/06/2007
2519
2520 function [ok,bllst]=adjust_typ(bllst,connectmat)
2521
2522     for i=1:length(bllst)
2523         if size(bllst(i).in,"*")<>size(bllst(i).intyp,"*") then
2524             bllst(i).intyp=bllst(i).intyp(1)*ones(bllst(i).in);
2525         end
2526         if size(bllst(i).out,"*")<>size(bllst(i).outtyp,"*") then
2527             bllst(i).outtyp=bllst(i).outtyp(1)*ones(bllst(i).out);
2528         end
2529     end
2530     nlnk=size(connectmat,1)
2531     for hhjj=1:length(bllst)+1
2532         for hh=1:length(bllst)+1
2533             ok=%t
2534             for jj=1:nlnk
2535                 nnout(1,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2))
2536                 nnout(1,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2))
2537                 nnin(1,1)=bllst(connectmat(jj,3)).in(connectmat(jj,4))
2538                 nnin(1,2)=bllst(connectmat(jj,3)).in2(connectmat(jj,4))
2539                 outtyp = bllst(connectmat(jj,1)).outtyp(connectmat(jj,2))
2540                 intyp = bllst(connectmat(jj,3)).intyp(connectmat(jj,4))
2541
2542                 //first case : types of source and
2543                 //             target ports are explicitly informed
2544                 //             with positive types
2545                 if (intyp>0 & outtyp>0) then
2546                     //if types of source and target port don't match and aren't double and complex
2547                     //then call bad_connection, set flag ok to false and exit
2548
2549                     if intyp<>outtyp then
2550                         if (intyp==1 & outtyp==2) then
2551                             bllst(connectmat(jj,3)).intyp(connectmat(jj,4))=2;
2552                         elseif (intyp==2 & outtyp==1) then
2553                             bllst(connectmat(jj,1)).outtyp(connectmat(jj,2))=2;
2554                         else
2555                             bad_connection(corinv(connectmat(jj,1)),connectmat(jj,2),..
2556                             nnout,outtyp,..
2557                             corinv(connectmat(jj,3)),connectmat(jj,4),..
2558                             nnin,intyp,1)
2559                             ok=%f;
2560                             return
2561                         end
2562                     end
2563
2564                     //second case : type of source port is
2565                     //              positive and type of
2566                     //              target port is negative
2567                 elseif(outtyp>0&intyp<0) then
2568                     //find vector of input ports of target block with
2569                     //type equal to intyp
2570                     //and assign it to outtyp
2571                     ww=find(bllst(connectmat(jj,3)).intyp==intyp)
2572                     bllst(connectmat(jj,3)).intyp(ww)=outtyp
2573
2574                     //find vector of output ports of target block with
2575                     //type equal to intyp
2576                     //and assign it to outtyp
2577                     ww=find(bllst(connectmat(jj,3)).outtyp==intyp)
2578                     bllst(connectmat(jj,3)).outtyp(ww)=outtyp
2579
2580                     //third case : type of source port is
2581                     //             negative and type of
2582                     //             target port is positive
2583                 elseif(outtyp<0&intyp>0) then
2584                     //find vector of output ports of source block with
2585                     //type equal to outtyp
2586                     //and assign it to intyp
2587                     ww=find(bllst(connectmat(jj,1)).outtyp==outtyp)
2588                     bllst(connectmat(jj,1)).outtyp(ww)=intyp
2589
2590                     //find vector of input ports of source block with
2591                     //type equal to size outtyp
2592                     //and assign it to intyp
2593                     ww=find(bllst(connectmat(jj,1)).intyp==outtyp)
2594                     bllst(connectmat(jj,1)).intyp(ww)=intyp
2595
2596
2597                     //fourth (& last) case : type of both source
2598                     //                      and target port are negatives
2599                 else
2600                     ok=%f //set flag ok to false
2601                 end
2602             end
2603             if ok then return, end //if ok is set true then exit adjust_typ
2604         end
2605         //if failed then display message
2606         messagebox(msprintf(_("Not enough information to find port type.\n"+..
2607         "I will try to find the problem.")),"modal","info");
2608         findflag=%f
2609         for jj=1:nlnk
2610             nouttyp=bllst(connectmat(jj,1)).outtyp(connectmat(jj,2))
2611             nintyp=bllst(connectmat(jj,3)).intyp(connectmat(jj,4))
2612
2613             //loop on the two dimensions of source/target port
2614             //only case : target and source ports are both
2615             //            negative or null
2616             if nouttyp<=0 & nintyp<=0 then
2617                 findflag=%t;
2618                 //
2619                 inouttyp=under_connection(corinv(connectmat(jj,1)),connectmat(jj,2),nouttyp,..
2620                 corinv(connectmat(jj,3)),connectmat(jj,4),nintyp,2)
2621                 //
2622                 if inouttyp<1|inouttyp>8 then ok=%f;return;end
2623                 //
2624                 ww=find(bllst(connectmat(jj,1)).outtyp==nouttyp)
2625                 bllst(connectmat(jj,1)).outtyp(ww)=inouttyp
2626
2627                 //
2628                 ww=find(bllst(connectmat(jj,1)).intyp==nouttyp)
2629                 bllst(connectmat(jj,1)).intyp(ww)=inouttyp
2630
2631                 ww=find(bllst(connectmat(jj,3)).intyp==nintyp)
2632                 bllst(connectmat(jj,3)).intyp(ww)=inouttyp
2633                 //
2634                 ww=find(bllst(connectmat(jj,3)).outtyp==nintyp)
2635                 bllst(connectmat(jj,3)).outtyp(ww)=inouttyp
2636
2637                 //
2638             end
2639         end
2640         //if failed then display message
2641         if ~findflag then
2642             messagebox(msprintf(_("I cannot find a link with undetermined size.\n"+..
2643             "My guess is that you have a block with unconnected \n"+..
2644             "undetermined types.")),"modal","error");
2645             ok=%f;return;
2646         end
2647     end
2648 endfunction
2649