74c7e0c058fd19cd8f632b5aaae986af8236d038
[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= zeros(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                 msg = _("A C or Fortran block is used but not linked.\nYou can save your compiled diagram and load it.\nThis will automatically link the C or Fortran function.")
1224                 messagebox(msprintf(msg), "modal", "error")
1225             end
1226         end
1227         inpnum=ll.in;outnum=ll.out;cinpnum=ll.evtin;coutnum=ll.evtout;
1228         //
1229         inpptr(i+1)=inpptr(i)+size(inpnum,"*")
1230         outptr(i+1)=outptr(i)+size(outnum,"*")
1231         cliptr(i+1)=cliptr(i)+size(cinpnum,"*")
1232         clkptr(i+1)=clkptr(i)+size(coutnum,"*")
1233         //
1234         X0=ll.state(:)
1235         if funtyp(i,1)<10000 then
1236             xcd0=[xcd0;0*X0]
1237             xc0=[xc0;X0]
1238             xptr(i+1)=xptr(i)+size(ll.state,"*")
1239         else
1240             xcd0=[xcd0;X0($/2+1:$)]
1241             xc0=[xc0;X0(1:$/2)]
1242             xptr(i+1)=xptr(i)+size(ll.state,"*")/2
1243         end
1244
1245         //dstate
1246         if (funtyp(i,1)==3 | funtyp(i,1)==5 | funtyp(i,1)==10005) then //sciblocks
1247             if ll.dstate==[] then xd0k=[]; else xd0k=var2vec(ll.dstate);end
1248         else
1249             xd0k=ll.dstate(:)
1250         end
1251         xd0=[xd0;xd0k]
1252         zptr(i+1)=zptr(i)+size(xd0k,"*")
1253
1254         //odstate
1255         if type(ll.odstate)==15 then
1256             if ((funtyp(i,1)==5) | (funtyp(i,1)==10005)) then //sciblocks : don't extract
1257                 if size(ll.odstate)>0 then
1258                     oxd0($+1)=ll.odstate
1259                     ozptr(i+1)=ozptr(i)+1;
1260                 else
1261                     ozptr(i+1)=ozptr(i);
1262                 end
1263             elseif ((funtyp(i,1)==4)    | (funtyp(i,1)==10004) |...
1264                 (funtyp(i,1)==2004) | (funtyp(i,1)==12004))  //C blocks : extract
1265                 ozsz = size(ll.odstate);
1266                 if ozsz>0 then
1267                     for j=1:ozsz, oxd0($+1)=ll.odstate(j), end;
1268                     ozptr(i+1)=ozptr(i)+ozsz;
1269                 else
1270                     ozptr(i+1)=ozptr(i);
1271                 end
1272             else
1273                 ozptr(i+1)=ozptr(i);
1274             end
1275         else
1276             //add an error message here please !
1277             ozptr(i+1)=ozptr(i);
1278         end
1279
1280         //mod
1281         typ_mod(i)=ll.nmode;
1282         if typ_mod(i)<0 then
1283             messagebox(msprintf(_("Number of modes in block #%d cannot be determined."),i),"modal","error")
1284             ok=%f
1285         end
1286
1287         //real paramaters
1288         rpark=ll.rpar(:)
1289         rpar=[rpar;rpark]
1290         rpptr(i+1)=rpptr(i)+size(rpark,"*")
1291
1292         //integer parameters
1293         if type(ll.ipar)==1 then
1294             ipar=[ipar;ll.ipar(:)]
1295             ipptr(i+1)=ipptr(i)+size(ll.ipar,"*")
1296         else
1297             ipptr(i+1)=ipptr(i)
1298         end
1299
1300         //object parameters
1301         if type(ll.opar)==15 then
1302             if ((funtyp(i,1)==5) | (funtyp(i,1)==10005)) then //sciblocks : don't extract
1303                 if size(ll.opar)>0 then
1304                     opar($+1)=ll.opar
1305                     opptr(i+1)=opptr(i)+1;
1306                 else
1307                     opptr(i+1)=opptr(i);
1308                 end
1309             elseif ((funtyp(i,1)==4)    | (funtyp(i,1)==10004) |...
1310                 (funtyp(i,1)==2004) | (funtyp(i,1)==12004)) then //C blocks : extract
1311                 oparsz = size(ll.opar);
1312                 if oparsz>0 then
1313                     for j=1:oparsz, opar($+1)=ll.opar(j), end;
1314                     opptr(i+1)=opptr(i)+oparsz;
1315                 else
1316                     opptr(i+1)=opptr(i);
1317                 end
1318             else
1319                 opptr(i+1)=opptr(i);
1320             end
1321         else
1322             //add an error message here please !
1323             opptr(i+1)=opptr(i);
1324         end
1325
1326         //    typ_z(i)=ll.blocktype=='z'
1327         typ_z(i)=ll.nzcross
1328         if typ_z(i)<0 then
1329             messagebox(msprintf(_("Number of zero crossings in block #%d cannot be determined."),i),"modal","error")
1330             ok=%f
1331         end
1332         typ_x(i)=ll.state<>[]|ll.blocktype=="x" // some blocks like delay
1333         // need to be in oord even
1334         // without state
1335
1336         typ_m(i)=ll.blocktype=="m"
1337         //
1338         if ll.evtout<>[] then
1339             ll11=ll.firing
1340             prt=find(ll11>=zeros(ll11))
1341             nprt=prod(size(prt))
1342             initexe=[initexe;[i*ones(nprt,1),matrix(prt,nprt,1),matrix(ll11(prt),nprt,1)]];
1343         end
1344
1345         if type(ll.label)==10 then
1346             labels=[labels;ll.label(1)]
1347         else
1348             labels=[labels;" "]
1349         end
1350
1351         if type(ll.uid)==10 then
1352             uids=[uids;ll.uid(1)]
1353         else
1354             uids=[uids;" "]
1355         end
1356     end
1357
1358     clkconnect=clkconnect(find(clkconnect(:,1)<>0),:);
1359
1360     if isempty(clkconnect) then
1361         con=-1;
1362     else
1363         con=clkptr(clkconnect(:,1))+clkconnect(:,2)-1;
1364     end
1365     [junk,ind]=gsort(-con);con=-junk;
1366     clkconnect=clkconnect(ind,:);
1367     //
1368     bclkconnect=clkconnect(:,[1 3]);
1369     boptr=1;
1370     bexe=[];
1371     for i=1:nbl
1372         r=bclkconnect(find(bclkconnect(:,1)==i),2);
1373         bexe=[bexe;r];
1374         boptr=[boptr;boptr($)+size(r,1)];
1375     end
1376     //
1377
1378     blptr=1;
1379     blnk=[];
1380
1381     for i=1:nbl
1382         r=connectmat(find(connectmat(:,1)==i),3:4);
1383         blnk=[blnk;r];
1384         blptr=[blptr;blptr($)+size(r,1)];
1385     end
1386     //
1387
1388     nlnk=size(connectmat,1)
1389     inplnk=zeros(inpptr($)-1,1);outlnk=zeros(outptr($)-1,1);ptlnk=1;
1390     lnksz=[];lnktyp=[];
1391     for jj=1:nlnk
1392         ko=outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)
1393         ki=inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)
1394         if ko<>0 & ki<>0 then
1395             if ko>ki then
1396                 outlnk(outlnk>ko)=outlnk(outlnk>ko)-1
1397                 outlnk(outlnk==ko)=ki
1398                 inplnk(inplnk>ko)=inplnk(inplnk>ko)-1
1399                 inplnk(inplnk==ko)=ki
1400                 ptlnk=-1+ptlnk
1401                 lnksz(ko,1)=[];
1402                 lnksz(ko,2)=[];
1403                 lnktyp(ko) =[];
1404             elseif ki>ko
1405                 outlnk(outlnk>ki)=outlnk(outlnk>ki)-1
1406                 outlnk(outlnk==ki)=ko
1407                 inplnk(inplnk>ki)=inplnk(inplnk>ki)-1
1408                 inplnk(inplnk==ki)=ko
1409                 ptlnk=-1+ptlnk
1410                 lnksz(ki,1)=[];
1411                 lnksz(ki,2)=[];
1412                 lnktyp(ki) =[];
1413             end
1414         elseif ko<>0 then
1415             inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)=ko
1416         elseif ki<>0 then
1417             outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)=ki
1418         else
1419             outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)=ptlnk
1420             inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)=ptlnk
1421             lnksz(ptlnk,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2));
1422             lnksz(ptlnk,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2));
1423             lnktyp(ptlnk)=bllst(connectmat(jj,1)).outtyp(connectmat(jj,2));
1424             ptlnk=1+ptlnk
1425         end
1426     end
1427
1428     //store unconnected outputs, if any, at the end of outtb
1429     unco=find(outlnk==0);
1430     for j=unco
1431         m=max(find(outptr<=j))
1432         n=j-outptr(m)+1
1433         nm=bllst(m).out(n)
1434         if nm<1 then
1435             under_connection(corinv(m),n,nm,-1,0,0,1),ok=%f,return,
1436         end
1437         nm2=bllst(m).out2(n)
1438         if nm2<1 then
1439             under_connection(corinv(m),n,nm2,-1,0,0,1),ok=%f,return,
1440         end
1441         lnksz($+1,1)=bllst(m).out(n);
1442         lnksz($,2)=bllst(m).out2(n);
1443         lnktyp($+1)=bllst(m).outtyp(n);
1444         outlnk(j)=max(outlnk)+1
1445     end
1446
1447     //store unconnected inputs, if any, at the end of outtb
1448     unco=find(inplnk==0);
1449     for j=unco
1450         m=max(find(inpptr<=j))
1451         n=j-inpptr(m)+1
1452         nm=bllst(m).in(n)
1453         if nm<1 then
1454             under_connection(corinv(m),n,nm,-2,0,0,1),ok=%f,return,
1455         end
1456         nm2=bllst(m).in2(n)
1457         if nm2<1 then
1458             under_connection(corinv(m),n,nm2,-2,0,0,1),ok=%f,return,
1459         end
1460         lnksz($+1,1)=bllst(m).in(n);
1461         lnksz($,2)=bllst(m).in2(n);
1462         lnktyp($+1)=bllst(m).intyp(n);
1463         inplnk(j)=max([inplnk;max(outlnk)])+1
1464     end
1465
1466 endfunction
1467
1468 function [outoin,outoinptr]=conn_mat(inpptr,outptr,inplnk,outlnk)
1469     outoin=[];outoinptr=1
1470     nblk=size(inpptr,1)-1
1471     for i=1:nblk
1472         k=outptr(i):outptr(i+1)-1
1473         ii=[]
1474         for j=outlnk(k)'
1475             ii=[ii,find(inplnk==j)]
1476         end
1477         outoini=[];jj=0
1478         for j=ii
1479             m=max(find(inpptr<=j))
1480             n=j-inpptr(m)+1
1481             outoini=[outoini;[m,n]]
1482             jj=jj+1
1483         end
1484         outoinptr=[outoinptr;outoinptr($)+jj]
1485         outoin=[outoin;outoini]
1486     end
1487 endfunction
1488
1489 function [ord,ok]=tree2(vec,outoin,outoinptr,dep_ut)
1490     //compute blocks execution tree
1491     ok=%t;
1492
1493     nb=size(vec,"*");
1494     for j=1:nb+2
1495         fini=%t
1496         for i=1:nb
1497             if vec(i)==j-1 then
1498                 if j==nb+2 then
1499                     disp(msprintf("%s: tree (2) failed", "c_pass2"));
1500                     messagebox(_("Algebraic loop."),"modal","error");ok=%f;ord=[];return;
1501                 end
1502                 for k=outoinptr(i):outoinptr(i+1)-1
1503                     ii=outoin(k,1);
1504                     //indport=find(dep_u(dep_uptr(ii):dep_uptr(ii+1)-1)==1);
1505                     //if (indport ~=[] &vec(ii)>-1) then
1506                     if (dep_ut(ii) &vec(ii)>-1) then
1507                         fini=%f;
1508                         vec(ii)=j;
1509                     end
1510                 end
1511             end
1512         end
1513         if fini then break;end
1514     end
1515
1516     [k,ord]=gsort(-vec);
1517     ord(find(k==1))=[];
1518     ord=ord(:)
1519 endfunction
1520
1521
1522 //adjust_inout : it resolves positive, negative and null size
1523 //               of in/out port dimensions of connected block.
1524 //               If it's not done in a first pass, the second
1525 //               pass try to resolve negative or null port
1526 //               dimensions by asking user to informed dimensions
1527 //               with underconnection function.
1528 //               It is a fixed point algorithm.
1529 //
1530 //in parameters  : bllst : list of blocks
1531 //
1532 //                 connectmat : matrix of connection
1533 //                              connectmat(lnk,1) : source block
1534 //                              connectmat(lnk,2) : source port
1535 //                              connectmat(lnk,3) : target block
1536 //                              connectmat(lnk,4) : target port
1537 //
1538 //out parameters : ok : a boolean flag to known if adjust_inout have
1539 //                      succeeded to resolve the in/out port size
1540 //                      - ok = %t : all size have been resolved in bllst
1541 //                      - ok = %f : problem in size adjustement
1542 //
1543 //                 bllst : modified list of blocks
1544 //
1545 //18/05/06, Alan  : improvement in order to take into
1546 //                  account two dimensional port size.
1547 //
1548 //28/12/06, Alan : type for source port and target port must
1549 //                 be the same.
1550 //
1551 //29/12/06, Fady : type for source and target can be different
1552 //                 in one condition that they are double and complex.
1553 //                 the result on the link will be complex.
1554 //
1555 //04/01/07, Fady : Can test the case of negatives equals target's dimensions.
1556 //
1557 //19/01/07, Alan : - Return correct information for user in editor
1558 //                   with preceding test of Fady in the first pass
1559 //                 - Second pass reviewed : under_connection returns two dimensions now
1560 //
1561 //10/05/07, Alan : - if-then-else event-select case
1562
1563 function [ok,bllst]=adjust_inout(bllst,connectmat)
1564
1565     //Adjust in2/out2, inttyp/outtyp
1566     //in accordance to in/out in bllst
1567     [ko,bllst]=adjust_in2out2(bllst);
1568     if ~ko then ok=%f,return, end //if adjust_in2out2 failed then exit
1569     //adjust_inout with flag ok=%f
1570
1571     nlnk=size(connectmat,1) //nlnk is the number of link
1572
1573     //loop on number of block (pass 1 and pass 2)
1574     for hhjj=1:length(bllst)+1
1575         //%%%%% pass 1 %%%%%//
1576         for hh=1:length(bllst)+1 //second loop on number of block
1577             ok=%t
1578             for jj=1:nlnk //loop on number of link
1579
1580                 //intyp/outtyp are the type of the
1581                 //target port and the source port of the observed link
1582                 outtyp = bllst(connectmat(jj,1)).outtyp(connectmat(jj,2))
1583                 intyp = bllst(connectmat(jj,3)).intyp(connectmat(jj,4))
1584                 //nnin/nnout are the size (two dimensions) of the
1585                 //target port and the source port of the observed link
1586                 //before adjust
1587                 nnout(1,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2))
1588                 nnout(1,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2))
1589                 nnin(1,1)=bllst(connectmat(jj,3)).in(connectmat(jj,4))
1590                 nnin(1,2)=bllst(connectmat(jj,3)).in2(connectmat(jj,4))
1591
1592                 //This Part is done in adjust_typ
1593
1594                 //check intyp/outtyp
1595                 //            if intyp<>outtyp then
1596                 //              if (intyp==1 & outtyp==2) then
1597                 //                bllst(connectmat(jj,3)).intyp(connectmat(jj,4))=2;
1598                 //              elseif (intyp==2 & outtyp==1) then
1599                 //                bllst(connectmat(jj,1)).outtyp(connectmat(jj,2))=2;
1600                 //              else
1601                 //                if bllst(connectmat(jj,3)).sim(2)<0 //if-then-else/eselect case
1602                 //                  bllst(connectmat(jj,3)).intyp(connectmat(jj,4))=...
1603                 //                    bllst(connectmat(jj,1)).outtyp(connectmat(jj,2))
1604                 //                else
1605                 //                  bad_connection(corinv(connectmat(jj,1)),connectmat(jj,2),..
1606                 //                                 nnout,outtyp,..
1607                 //                                 corinv(connectmat(jj,3)),connectmat(jj,4),..
1608                 //                                 nnin,intyp,1)
1609                 //                  ok=%f;
1610                 //                  return
1611                 //                end
1612                 //              end
1613                 //            end
1614
1615                 //loop on the two dimensions of source/target port
1616                 for ndim=1:2
1617                     //check test source/target sizes
1618                     //in case of negatif equal target dimensions
1619                     //nin/nout are the size (two dimensions) of the
1620                     //target port and the source port of the observed link
1621                     nout(1,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2))
1622                     nout(1,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2))
1623                     nin(1,1)=bllst(connectmat(jj,3)).in(connectmat(jj,4))
1624                     nin(1,2)=bllst(connectmat(jj,3)).in2(connectmat(jj,4))
1625
1626                     //first case : dimension of source and
1627                     //             target ports are explicitly informed
1628                     //             informed with positive size
1629                     if(nout(1,ndim)>0&nin(1,ndim)>0) then
1630                         //if dimension of source and target port doesn't match
1631                         //then call bad_connection, set flag ok to false and exit
1632                         if nin(1,ndim)<>nout(1,ndim) then
1633                             bad_connection(corinv(connectmat(jj,1)),connectmat(jj,2),..
1634                             nnout,outtyp,..
1635                             corinv(connectmat(jj,3)),connectmat(jj,4),..
1636                             nnin,intyp)
1637                             ok=%f;return
1638                         end
1639
1640                         //second case : dimension of source port is
1641                         //              positive and dimension of
1642                         //              target port is negative
1643                     elseif(nout(1,ndim)>0&nin(1,ndim)<0) then
1644                         //find vector of input ports of target block with
1645                         //first/second dimension equal to size nin(1,ndim)
1646                         //and assign it to nout(1,ndim)
1647                         ww=find(bllst(connectmat(jj,3)).in==nin(1,ndim))
1648                         bllst(connectmat(jj,3)).in(ww)=nout(1,ndim)
1649                         ww=find(bllst(connectmat(jj,3)).in2==nin(1,ndim))
1650                         bllst(connectmat(jj,3)).in2(ww)=nout(1,ndim)
1651
1652                         //find vector of output ports of target block with
1653                         //first/second dimension equal to size nin(1,ndim)
1654                         //and assign it to nout(1,ndim)
1655                         ww=find(bllst(connectmat(jj,3)).out==nin(1,ndim))
1656                         bllst(connectmat(jj,3)).out(ww)=nout(1,ndim)
1657                         ww=find(bllst(connectmat(jj,3)).out2==nin(1,ndim))
1658                         bllst(connectmat(jj,3)).out2(ww)=nout(1,ndim)
1659
1660                         //find vector of output ports of target block with
1661                         //ndim dimension equal to zero and sum the ndim
1662                         //dimension of all input ports of target block
1663                         //to be the new dimension of the ndim dimension
1664                         //of the output ports of the target block
1665                         if ndim==1 then
1666                             ww=find(bllst(connectmat(jj,3)).out==0)
1667                             if (ww<>[]&min(bllst(connectmat(jj,3)).in(:))>0) then
1668                                 bllst(connectmat(jj,3)).out(ww)=sum(bllst(connectmat(jj,3)).in(:))
1669                             end
1670                         elseif ndim==2 then
1671                             ww=find(bllst(connectmat(jj,3)).out2==0)
1672                             if (ww<>[]&min(bllst(connectmat(jj,3)).in2(:))>0) then
1673                                 bllst(connectmat(jj,3)).out2(ww)=sum(bllst(connectmat(jj,3)).in2(:))
1674                             end
1675                         end
1676
1677                         //if nzcross of the target block match with
1678                         //the negative dimension nin(1,ndim) then
1679                         //adjust it to nout(1,ndim)
1680                         if bllst(connectmat(jj,3)).nzcross==nin(1,ndim) then
1681                             bllst(connectmat(jj,3)).nzcross=nout(1,ndim)
1682                         end
1683                         //if nmode of the target block match with
1684                         //the negative dimension nin(1,ndim) then
1685                         //adjust it to nout(1,ndim)
1686                         if bllst(connectmat(jj,3)).nmode==nin(1,ndim) then
1687                             bllst(connectmat(jj,3)).nmode=nout(1,ndim)
1688                         end
1689
1690                         //third case : dimension of source port is
1691                         //             negative and dimension of
1692                         //             target port is positive
1693                     elseif(nout(1,ndim)<0&nin(1,ndim)>0) then
1694                         //find vector of output ports of source block with
1695                         //first/second dimension equal to size nout(1,ndim)
1696                         //and assign it to nin(1,ndim)
1697                         ww=find(bllst(connectmat(jj,1)).out==nout(1,ndim))
1698                         bllst(connectmat(jj,1)).out(ww)=nin(1,ndim)
1699                         ww=find(bllst(connectmat(jj,1)).out2==nout(1,ndim))
1700                         bllst(connectmat(jj,1)).out2(ww)=nin(1,ndim)
1701
1702                         //find vector of input ports of source block with
1703                         //first/second dimension equal to size nout(1,ndim)
1704                         //and assign it to nin(1,ndim)
1705                         ww=find(bllst(connectmat(jj,1)).in==nout(1,ndim))
1706                         bllst(connectmat(jj,1)).in(ww)=nin(1,ndim)
1707                         ww=find(bllst(connectmat(jj,1)).in2==nout(1,ndim))
1708                         bllst(connectmat(jj,1)).in2(ww)=nin(1,ndim)
1709
1710                         //find vector of input ports of source block with
1711                         //ndim dimension equal to zero and sum the ndim
1712                         //dimension of all output ports of source block
1713                         //to be the new dimension of the ndim dimension
1714                         //of the input ports of the source block
1715                         if ndim==1 then
1716                             ww=find(bllst(connectmat(jj,1)).in==0)
1717                             if (ww<>[]&min(bllst(connectmat(jj,1)).out(:))>0) then
1718                                 bllst(connectmat(jj,1)).in(ww)=sum(bllst(connectmat(jj,1)).out(:))
1719                             end
1720                         elseif ndim==2 then
1721                             ww=find(bllst(connectmat(jj,1)).in2==0)
1722                             if (ww<>[]&min(bllst(connectmat(jj,1)).out2(:))>0) then
1723                                 bllst(connectmat(jj,1)).in2(ww)=sum(bllst(connectmat(jj,1)).out2(:))
1724                             end
1725                         end
1726
1727                         //if nzcross of the source block match with
1728                         //the negative dimension nout(1,ndim) then
1729                         //adjust it to nin(1,ndim)
1730                         if bllst(connectmat(jj,1)).nzcross==nout(1,ndim) then
1731                             bllst(connectmat(jj,1)).nzcross=nin(1,ndim)
1732                         end
1733                         //if nmode of the source block match with
1734                         //the negative dimension nout(1,ndim) then
1735                         //adjust it to nin(1,ndim)
1736                         if bllst(connectmat(jj,1)).nmode==nout(1,ndim) then
1737                             bllst(connectmat(jj,1)).nmode=nin(1,ndim)
1738                         end
1739
1740                         //fourth case : a dimension of source port is
1741                         //              null
1742                     elseif(nout(1,ndim)==0) then
1743                         //set ww to be the vector of size of the ndim
1744                         //dimension of input port of the source block
1745                         if ndim==1 then
1746                             ww=bllst(connectmat(jj,1)).in(:)
1747                         elseif ndim==2 then
1748                             ww=bllst(connectmat(jj,1)).in2(:)
1749                         end
1750
1751                         //test if all size of the ndim dimension of input
1752                         //port of the source block is positive
1753                         if min(ww)>0 then
1754                             //test if the dimension of the target port
1755                             //is positive
1756                             if nin(1,ndim)>0 then
1757
1758                                 //if the sum of the size of the ndim dimension of the input
1759                                 //port of the source block is equal to the size of the ndim dimension
1760                                 //of the target port, then the size of the ndim dimension of the source
1761                                 //port is equal to nin(1,ndim)
1762                                 if sum(ww)==nin(1,ndim) then
1763                                     if ndim==1 then
1764                                         bllst(connectmat(jj,1)).out(connectmat(jj,2))=nin(1,ndim)
1765                                     elseif ndim==2 then
1766                                         bllst(connectmat(jj,1)).out2(connectmat(jj,2))=nin(1,ndim)
1767                                     end
1768                                     //else call bad_connection, set flag ok to false and exit
1769                                 else
1770                                     bad_connection(corinv(connectmat(jj,1)),0,0,1,-1,0,0,1)
1771                                     ok=%f;return
1772                                 end
1773
1774                                 //if the ndim dimension of the target port is negative
1775                                 //then the size of the ndim dimension of the source port
1776                                 //is equal to the sum of the size of the ndim dimension
1777                                 //of input ports of source block, and flag ok is set to false
1778                             else
1779                                 if ndim==1 then
1780                                     bllst(connectmat(jj,1)).out(connectmat(jj,2))=sum(ww)
1781                                 elseif ndim==2 then
1782                                     bllst(connectmat(jj,1)).out2(connectmat(jj,2))=sum(ww)
1783                                 end
1784                                 ok=%f
1785                             end
1786
1787                         else
1788                             //set nww to be the vector of all negative size of input ports
1789                             //of the source block
1790                             nww=ww(find(ww<0))
1791
1792                             //if all negative size have same size and if size of the
1793                             //ndim dimension of the target port is positive then assign
1794                             //size of the ndim dimension of the source port to nin(1,ndim)
1795                             if norm(nww-nww(1),1)==0 & nin(1,ndim)>0 then
1796                                 if ndim==1 then
1797                                     bllst(connectmat(jj,1)).out(connectmat(jj,2))=nin(1,ndim)
1798                                 elseif ndim==2 then
1799                                     bllst(connectmat(jj,1)).out2(connectmat(jj,2))=nin(1,ndim)
1800                                 end
1801
1802                                 //compute a size to be the difference between the size
1803                                 //of the ndim dimension of the target block and sum of positive
1804                                 //size of input ports of the source block divided by the number
1805                                 //of input ports of source block with same negative size
1806                                 k=(nin(1,ndim)-sum(ww(find(ww>0))))/size(nww,"*")
1807
1808                                 //if this size is a positive integer then assign it
1809                                 //to the size of the ndim dimension of input ports of the
1810                                 //source block which have negative size
1811                                 if k==int(k)&k>0 then
1812                                     if ndim==1 then
1813                                         bllst(connectmat(jj,1)).in(find(ww<0))=k
1814                                     elseif ndim==2 then
1815                                         bllst(connectmat(jj,1)).in2(find(ww<0))=k
1816                                     end
1817                                     //else call bad_connection, set flag ok to false and exit
1818                                 else
1819                                     bad_connection(corinv(connectmat(jj,1)),0,0,1,-1,0,0,1)
1820                                     ok=%f;return
1821                                 end
1822
1823                                 //set flag ok to false
1824                             else
1825                                 ok=%f
1826                             end
1827
1828                         end
1829
1830                         //fifth case : a dimension of target port is
1831                         //             null
1832                     elseif(nin(1,ndim)==0) then
1833                         //set ww to be the vector of size of the ndim
1834                         //dimension of output port of the target block
1835                         if ndim==1 then
1836                             ww=bllst(connectmat(jj,3)).out(:)
1837                         elseif ndim==2 then
1838                             ww=bllst(connectmat(jj,3)).out2(:)
1839                         end
1840
1841                         //test if all size of the ndim dimension of output
1842                         //port of the target block is positive
1843                         if min(ww)>0 then
1844                             //test if the dimension of the source port
1845                             //is positive
1846                             if nout(1,ndim)>0 then
1847
1848                                 //if the sum of the size of the ndim dimension of the output
1849                                 //port of the target block is equal to the size of the ndim dimension
1850                                 //of the source port, then the size of the ndim dimension of the target
1851                                 //port is equal to nout(1,ndim)
1852                                 if sum(ww)==nout(1,ndim) then
1853                                     if ndim==1 then
1854                                         bllst(connectmat(jj,3)).in(connectmat(jj,4))=nout(1,ndim)
1855                                     elseif ndim==2 then
1856                                         bllst(connectmat(jj,3)).in2(connectmat(jj,4))=nout(1,ndim)
1857                                     end
1858                                     //else call bad_connection, set flag ok to false and exit
1859                                 else
1860                                     bad_connection(corinv(connectmat(jj,3)),0,0,1,-1,0,0,1)
1861                                     ok=%f;return
1862                                 end
1863
1864                                 //if the ndim dimension of the source port is negative
1865                                 //then the size of the ndim dimension of the target port
1866                                 //is equal to the sum of the size of the ndim dimension
1867                                 //of output ports of target block, and flag ok is set to false
1868                             else
1869                                 if ndim==1 then
1870                                     bllst(connectmat(jj,3)).in(connectmat(jj,4))=sum(ww)
1871                                 elseif ndim==2 then
1872                                     bllst(connectmat(jj,3)).in2(connectmat(jj,4))=sum(ww)
1873                                 end
1874                                 ok=%f
1875                             end
1876
1877                         else
1878                             //set nww to be the vector of all negative size of output ports
1879                             //of the target block
1880                             nww=ww(find(ww<0))
1881
1882                             //if all negative size have same size and if size of the
1883                             //ndim dimension of the source port is positive then assign
1884                             //size of the ndim dimension of the target port to nout(1,ndim)
1885                             if norm(nww-nww(1),1)==0 & nout(1,ndim)>0 then
1886                                 if ndim==1 then
1887                                     bllst(connectmat(jj,3)).in(connectmat(jj,4))=nout(1,ndim)
1888                                 elseif ndim==2 then
1889                                     bllst(connectmat(jj,3)).in2(connectmat(jj,4))=nout(1,ndim)
1890                                 end
1891
1892                                 //compute a size to be the difference between the size
1893                                 //of the ndim dimension of the source block and sum of positive
1894                                 //size of output ports of the target block divided by the number
1895                                 //of output ports of target block with same negative size
1896                                 k=(nout(1,ndim)-sum(ww(find(ww>0))))/size(nww,"*")
1897
1898                                 //if this size is a positive integer then assign it
1899                                 //to the size of the ndim dimension of output ports of the
1900                                 //target block which have negative size
1901                                 if k==int(k)&k>0 then
1902                                     if ndim==1 then
1903                                         bllst(connectmat(jj,3)).out(find(ww<0))=k
1904                                     elseif ndim==2 then
1905                                         bllst(connectmat(jj,3)).out2(find(ww<0))=k
1906                                     end
1907                                     //else call bad_connection, set flag ok to false and exit
1908                                 else
1909                                     bad_connection(corinv(connectmat(jj,3)),0,0,1,-1,0,0,1)
1910                                     ok=%f;return
1911                                 end
1912
1913                                 //set flag ok to false
1914                             else
1915                                 ok=%f
1916                             end
1917
1918                         end
1919
1920                         //sixth (& last) case : dimension of both source
1921                         //                      and target port are negatives
1922                     else
1923                         ok=%f //set flag ok to false
1924                     end
1925                 end
1926             end
1927             if ok then return, end //if ok is set true then exit adjust_inout
1928         end
1929         //if failed then display message
1930         msg = _("Not enough information to find port sizes.\nI try to find the problem.")
1931         messagebox(msprintf(msg),"modal","info");
1932
1933         //%%%%% pass 2 %%%%%//
1934         //Alan 19/01/07 : Warning  : Behavior have changed, To Be more Tested
1935         findflag=%f //set findflag to false
1936
1937         for jj=1:nlnk //loop on number of block
1938             //nin/nout are the size (two dimensions) of the
1939             //target port and the source port of the observed link
1940             nout(1,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2))
1941             nout(1,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2))
1942             nin(1,1)=bllst(connectmat(jj,3)).in(connectmat(jj,4))
1943             nin(1,2)=bllst(connectmat(jj,3)).in2(connectmat(jj,4))
1944
1945             //loop on the two dimensions of source/target port
1946             //only case : target and source ports are both
1947             //            negatives or null
1948             if nout(1,1)<=0&nin(1,1)<=0 | nout(1,2)<=0&nin(1,2)<=0 then
1949                 findflag=%t;
1950                 //
1951                 ninnout=under_connection(corinv(connectmat(jj,1)),connectmat(jj,2),nout(1,ndim),..
1952                 corinv(connectmat(jj,3)),connectmat(jj,4),nin(1,ndim),1)
1953                 //
1954                 if size(ninnout,2) <> 2 then ok=%f;return;end
1955                 if ninnout==[] then ok=%f;return;end
1956                 if ninnout(1,1)<=0 | ninnout(1,2)<=0 then ok=%f;return;end
1957                 //
1958                 ww=find(bllst(connectmat(jj,1)).out==nout(1,1))
1959                 bllst(connectmat(jj,1)).out(ww)=ninnout(1,1)
1960                 ww=find(bllst(connectmat(jj,1)).out2==nout(1,1))
1961                 bllst(connectmat(jj,1)).out2(ww)=ninnout(1,1)
1962
1963                 ww=find(bllst(connectmat(jj,1)).out==nout(1,2))
1964                 bllst(connectmat(jj,1)).out(ww)=ninnout(1,2)
1965                 ww=find(bllst(connectmat(jj,1)).out2==nout(1,2))
1966                 bllst(connectmat(jj,1)).out2(ww)=ninnout(1,2)
1967                 //
1968
1969                 if bllst(connectmat(jj,1)).nzcross==nout(1,1) then
1970                     bllst(connectmat(jj,1)).nzcross=ninnout(1,1)
1971                 end
1972                 if bllst(connectmat(jj,1)).nzcross==nout(1,2) then
1973                     bllst(connectmat(jj,1)).nzcross=ninnout(1,2)
1974                 end
1975                 //
1976                 if bllst(connectmat(jj,1)).nmode==nout(1,1) then
1977                     bllst(connectmat(jj,1)).nmode=ninnout(1,1)
1978                 end
1979                 if bllst(connectmat(jj,1)).nmode==nout(1,2) then
1980                     bllst(connectmat(jj,1)).nmode=ninnout(1,2)
1981                 end
1982                 //
1983                 ww=find(bllst(connectmat(jj,1)).in==nout(1,1))
1984                 bllst(connectmat(jj,1)).in(ww)=ninnout(1,1)
1985                 ww=find(bllst(connectmat(jj,1)).in2==nout(1,1))
1986                 bllst(connectmat(jj,1)).in2(ww)=ninnout(1,1)
1987
1988                 ww=find(bllst(connectmat(jj,1)).in==nout(1,2))
1989                 bllst(connectmat(jj,1)).in(ww)=ninnout(1,2)
1990                 ww=find(bllst(connectmat(jj,1)).in2==nout(1,2))
1991                 bllst(connectmat(jj,1)).in2(ww)=ninnout(1,2)
1992                 //
1993                 ww=find(bllst(connectmat(jj,1)).in==0)
1994                 if (ww<>[]&min(bllst(connectmat(jj,1)).out(:))>0) then
1995                     bllst(connectmat(jj,1)).in(ww)=sum(bllst(connectmat(jj,1)).out)
1996                 end
1997
1998                 ww=find(bllst(connectmat(jj,1)).in2==0)
1999                 if (ww<>[]&min(bllst(connectmat(jj,1)).out2(:))>0) then
2000                     bllst(connectmat(jj,1)).in2(ww)=sum(bllst(connectmat(jj,1)).out2)
2001                 end
2002                 //
2003                 ww=find(bllst(connectmat(jj,3)).in==nin(1,1))
2004                 bllst(connectmat(jj,3)).in(ww)=ninnout(1,1)
2005                 ww=find(bllst(connectmat(jj,3)).in2==nin(1,1))
2006                 bllst(connectmat(jj,3)).in2(ww)=ninnout(1,1)
2007
2008                 ww=find(bllst(connectmat(jj,3)).in==nin(1,2))
2009                 bllst(connectmat(jj,3)).in(ww)=ninnout(1,2)
2010                 ww=find(bllst(connectmat(jj,3)).in2==nin(1,2))
2011                 bllst(connectmat(jj,3)).in2(ww)=ninnout(1,2)
2012                 //
2013                 if bllst(connectmat(jj,3)).nzcross==nin(1,1) then
2014                     bllst(connectmat(jj,3)).nzcross=ninnout(1,1)
2015                 end
2016                 if bllst(connectmat(jj,3)).nzcross==nin(1,2) then
2017                     bllst(connectmat(jj,3)).nzcross=ninnout(1,2)
2018                 end
2019                 if bllst(connectmat(jj,3)).nmode==nin(1,1) then
2020                     bllst(connectmat(jj,3)).nmode=ninnout(1,1)
2021                 end
2022                 if bllst(connectmat(jj,3)).nmode==nin(1,2) then
2023                     bllst(connectmat(jj,3)).nmode=ninnout(1,2)
2024                 end
2025                 //
2026                 ww=find(bllst(connectmat(jj,3)).out==nin(1,1))
2027                 bllst(connectmat(jj,3)).out(ww)=ninnout(1,1)
2028                 ww=find(bllst(connectmat(jj,3)).out2==nin(1,1))
2029                 bllst(connectmat(jj,3)).out2(ww)=ninnout(1,1)
2030
2031                 ww=find(bllst(connectmat(jj,3)).out==nin(1,2))
2032                 bllst(connectmat(jj,3)).out(ww)=ninnout(1,2)
2033                 ww=find(bllst(connectmat(jj,3)).out2==nin(1,2))
2034                 bllst(connectmat(jj,3)).out2(ww)=ninnout(1,2)
2035                 //
2036                 ww=find(bllst(connectmat(jj,3)).out==0)
2037                 if (ww<>[]&min(bllst(connectmat(jj,3)).in(:))>0) then
2038                     bllst(connectmat(jj,3)).out(ww)=sum(bllst(connectmat(jj,3)).in(:))
2039                 end
2040                 ww=find(bllst(connectmat(jj,3)).out2==0)
2041                 if (ww<>[]&min(bllst(connectmat(jj,3)).in2(:))>0) then
2042                     bllst(connectmat(jj,3)).out2(ww)=sum(bllst(connectmat(jj,3)).in2(:))
2043                 end
2044             end
2045         end
2046
2047         //if failed then display message
2048         if ~findflag then
2049             msg = _("I cannot find a link with undetermined size.\nMy guess is that you have a block with unconnected \nundetermined output ports.")
2050             messagebox(msprintf(msg), "modal", "error")
2051             ok = %f
2052             return
2053         end
2054     end
2055 endfunction
2056
2057 function id = getBlockIds(path)
2058     // Return a block id path from a block index path
2059     //
2060     // path: the path in the index form
2061     // id: th path in the uid form
2062
2063     scs_m; // check scs_m access
2064     id=[];
2065
2066     k = path(:);
2067     for i = k
2068         b = scs_m.objs(i);
2069         if typeof(b) == "Block" &  length(scs_m.objs(i).model.uid) >= 1 then
2070             id($ + 1) = scs_m.objs(i).model.uid;
2071         end
2072         if typeof(b.model.rpar) == "diagram" then
2073             scs_m = b.model.rpar;
2074         end
2075     end
2076 endfunction
2077
2078 //19/01/07, Alan : under_connection show bad link and returns two dimensions now
2079 function ninnout=under_connection(path_out,prt_out,nout,path_in,prt_in,nin,flagg)
2080     // alert for badly connected blocks
2081     // path_out : Path of the "from block" in scs_m
2082     // path_in  : Path of the "to block" in scs_m
2083     //!
2084
2085     if path_in==-1 then
2086         msg = "<html><body>";
2087         msg = msg + gettext("One of this block output has negative size.<br />Please check.");
2088         msg = msg + "</body></html>";
2089         hilite_path(path_out, msg);
2090         ninnout=0
2091         return
2092     end
2093
2094     if path_in==-2 then
2095         msg = "<html><body>";
2096         msg = msg + gettext("Block input has negative size:");
2097         msg = msg + "<ul>";
2098         msg = msg + "<li>" + msprintf(gettext("Input port %s size is: %s"), string(prt_out), sci2exp(nout)) + "</li>";
2099         msg = msg + "</ul>";
2100         msg = msg + "</body></html>";
2101         hilite_path(path_out, msg);
2102         ninnout=0
2103         return
2104     end
2105
2106     // different use case (Unable to report on a non opened diagram)
2107     if isdef("Code_gene_run") then
2108         messagebox([gettext("Unable to report an error into a SuperBlock"); gettext("Please compile the diagram to report the error.")], "Compilation error", "error", "modal");
2109         ninnout=0
2110         return
2111     end
2112
2113     msg = "<html><body>";
2114     if flagg==1 then
2115         msg = msg + gettext("<em>Please update the diagram to avoid this warning.</em><br />Block output port has a non-determined size:");
2116         msg = msg + "<ul>";
2117         msg = msg + "<li>" + msprintf(gettext("Output port %s size is: %s"), string(prt_out), sci2exp(nout)) + "</li>";
2118         msg = msg + "<li>" + msprintf(gettext("Input port %s size is: %s"), string(prt_in), sci2exp(nin)) + "</li>";
2119     else
2120         msg = msg + gettext("<em>Please update the diagram to avoid this warning.</em><br />Block output port has a non-determined type:");
2121         msg = msg + "<ul>";
2122         msg = msg + "<li>" + msprintf(gettext("Output port %s type."), string(prt_out)) + "</li>";
2123         msg = msg + "<li>" + msprintf(gettext("Input port %s type."), string(prt_in)) + "</li>";
2124     end
2125     msg = msg + "</ul>";
2126     msg = msg + "</body></html>";
2127     hilite_path(path_out, msg)
2128
2129     if or(path_in<>path_out) then
2130         msg = "<html><body>";
2131         if flagg==1 then
2132             msg = msg + gettext("<em>Please update the diagram to avoid this warning.</em><br />Block input port has a non-determined size:");
2133             msg = msg + "<ul>";
2134             msg = msg + "<li>" + msprintf(gettext("Output port %s size is: %s"), string(prt_out), sci2exp(nout)) + "</li>";
2135             msg = msg + "<li>" + msprintf(gettext("Input port %s size is: %s"), string(prt_in), sci2exp(nin)) + "</li>";
2136         else
2137             msg = msg + gettext("<em>Please update the diagram to avoid this warning.</em><br />Block input port has a non-determined type:");
2138             msg = msg + "<ul>";
2139             msg = msg + "<li>" + msprintf(gettext("Output port %s type."), string(prt_out)) + "</li>";
2140             msg = msg + "<li>" + msprintf(gettext("Input port %s type."), string(prt_in)) + "</li>";
2141         end
2142         msg = msg + "</ul>";
2143         msg = msg + "</body></html>";
2144         hilite_path(path_in, msg)
2145     end
2146
2147     mess=msprintf(_("Highlighted block(s) have connected ports \nwith  sizes that cannot be determined by the context.\nWhat is the size of this link?"))
2148
2149     if flagg==1 then
2150         ninnout=evstr(dialog(mess,"[1,1]"))
2151     else
2152         ninnout=evstr(dialog(mess,"1"))
2153     end
2154 endfunction
2155
2156 function [clkconnect,exe_cons]=pak_ersi(connectmat,clkconnect,..
2157     typ_r,typ_l,outoin,outoinptr,tblock,typ_cons,clkptr)
2158
2159     //add every event to the time event because time includes all events
2160     all_out=[]
2161     for k=1:size(clkptr,1)-1
2162         if ~typ_l(k) then
2163             kk=[1:(clkptr(k+1)-clkptr(k))]'
2164             all_out=[all_out;[k*ones(kk),kk]]
2165         end
2166     end
2167     all_out=[all_out;[0,0]]
2168
2169     //add time event if needed
2170     ind=find(tblock)
2171     ind=ind(:)
2172     for k=ind'
2173         clkconnect=[clkconnect;[all_out,ones(all_out)*[k,0;0,0]]]
2174     end
2175     if show_trace then mprintf("c_pass4444:\t%f\n", timer()),end
2176     ind1=find(typ_cons)
2177     ind=[ind;ind1(:)]
2178     exe_cons=[ind,zeros(ind)]
2179
2180     vec=-ones(1,nblk);
2181     vec(ind)=0
2182     [r,ok]=newc_tree4(vec,outoin,outoinptr,typ_r)
2183
2184     exe_cons=[exe_cons;r]
2185
2186     if show_trace then mprintf("c_pass4445:\t%f\n", timer()),end
2187
2188     [clkr,clkc]=size(clkconnect);
2189     if isempty(clkconnect) then
2190         cll=[];
2191     else
2192         mm=max(clkconnect(:,2))+1;
2193         cll=clkconnect(:,1)*mm+clkconnect(:,2);
2194     end
2195     [cll,ind]=gsort(-cll);
2196     clkconnect=clkconnect(ind,:);
2197     if cll<>[] then mcll=max(-cll)+1, else mcll=1;end
2198     cll=[-1;-cll;mcll];
2199     ii=find(cll(2:$)-cll(1:$-1)<>0)
2200
2201     for k=1:size(ii,"*")-1
2202         oo=[ii(k):ii(k+1)-1]
2203         vec=-ones(1,nblk);
2204         vec(clkconnect(oo,3))=0
2205         [r,ok]=newc_tree4(vec,outoin,outoinptr,typ_r)
2206         m=size(r,1)
2207         r=[clkconnect(ii(k),1)*ones(m,1),clkconnect(ii(k),2)*ones(m,1),r]
2208         clkconnect=[clkconnect;r]
2209     end
2210     // temporary fix to take care of conditional blocks inherting from
2211     // constants: make these blocks always active
2212
2213     ind=setdiff(find(typ_l),clkconnect(:,3))
2214     ind=ind(:)
2215     for k=ind'
2216         clkconnect=[clkconnect;[all_out,ones(all_out)*[k,0;0,0]]]
2217     end
2218     // end of  temoprary fix
2219     if show_trace then mprintf("c_pass4446:\t%f\n", timer()),end
2220 endfunction
2221
2222 function [r,ok]=tree4(vec,outoin,outoinptr,typ_r)
2223     //compute blocks which inherit
2224     ok=%t;
2225     nb=size(vec,"*");
2226     r=[];
2227     for j=1:nb-1
2228         fini=%t
2229         for i=1:nb
2230             if vec(i)==j-1 then
2231                 for k=outoinptr(i):outoinptr(i+1)-1
2232                     ii=outoin(k,1);
2233                     if (vec(ii)>-1)|typ_r(ii) then
2234                         fini=%f;
2235                         vec(ii)=j;
2236                     end
2237                     if typ_r(ii) then
2238                         r=[r;outoin(k,:)]
2239                     end
2240                 end
2241             end
2242         end
2243         if fini then break;end
2244     end
2245 endfunction
2246
2247 function [bllst,inplnk,outlnk,clkptr,cliptr,inpptr,outptr,dep_u,dep_uptr,dep_t,..
2248     typ_l,typ_r,typ_m,tblock,typ_cons,typ_zx,ok]=mini_extract_info(bllst,..
2249     connectmat,clkconnect)
2250     ok=%t
2251     nbl=length(bllst)
2252     clkptr=zeros(nbl+1,1);clkptr(1)=1
2253     cliptr=clkptr;inpptr=cliptr;outptr=inpptr;
2254     fff=ones(nbl,1)==1
2255     typ_l=fff;typ_r=fff;typ_cons=fff;typ_m=fff;typ_zx=fff;
2256     dep_t=ones(nbl,1)==1;
2257     dep_u=[];dep_uptr=1;
2258     tblock=fff
2259     //tblock=[]  // specifies blocks that must be connected to time event.
2260     //
2261     for i=1:nbl
2262         ll=bllst(i)
2263         if (ll.state==[]&ll.nzcross==0) then typ_zx(i)=%f;end
2264         inpnum=ll.in;outnum=ll.out;cinpnum=ll.evtin;coutnum=ll.evtout;
2265         //
2266         if cinpnum==[] then
2267             // this block inherits
2268             //ok=%f
2269
2270             typ_r(i)=~ll.dep_ut($)
2271             tblock(i)=ll.dep_ut($)
2272             //if block depends on time but has no event input port
2273             if ~ll.dep_ut($) then
2274                 //inherits from the inputs
2275                 cinpnum=ones(inpnum)
2276                 bllst(i).evtin=cinpnum  //XXXXXXXXXXXXXXXXXXXXX
2277             end
2278             //
2279         else
2280             tblock(i)=ll.dep_ut($);typ_r(i)=%f
2281         end
2282         inpptr(i+1)=inpptr(i)+size(inpnum,"*")
2283         outptr(i+1)=outptr(i)+size(outnum,"*")
2284         cliptr(i+1)=cliptr(i)+size(cinpnum,"*")
2285         clkptr(i+1)=clkptr(i)+size(coutnum,"*")
2286         //
2287
2288         typ_l(i)=ll.blocktype=="l";typ_m(i)=ll.blocktype=="m";
2289         typ_cons(i)=cinpnum==[]&inpnum==[]&~ll.dep_ut($)
2290         //test of the dep_ut size
2291         sizenin=size(ll.in,"*");
2292         if (size(ll.dep_ut,"*") <> 2) then
2293             if ( size(ll.dep_ut(1:$-1),"*") <> sizenin) then
2294                 msg = _("the dep_ut size of the %s block is not correct.\nIt should be a colon vector of size %d.")
2295                 messagebox(msprintf(msg, ll.sim(1), sizenin+1), "modal", "error")
2296                 ok=%f;
2297             end
2298         end
2299
2300         dep_t(i)=ll.dep_ut($);
2301
2302         if (size(ll.dep_ut,"*") == 2) then
2303             if (sizenin == 1) then
2304                 dep_u($+1)=ll.dep_ut(1);
2305                 dep_uptr($+1)=dep_uptr($)+1;
2306             elseif (sizenin > 1) then
2307                 dep_u=[dep_u;ones(sizenin,1)==1*ll.dep_ut(1)];
2308                 dep_uptr($+1)=dep_uptr($)+sizenin;
2309             else
2310                 dep_uptr($+1)=dep_uptr($);
2311             end
2312         else
2313             dep_u_i=ll.dep_ut(1:$-1);
2314             dep_u=[dep_u;dep_u_i(:)];
2315             dep_uptr($+1)=dep_uptr($)+sizenin;
2316         end
2317
2318         //
2319     end
2320     if show_trace then mprintf("c_pass22222222:\t%f\n", timer()),end //'
2321     nlnk=size(connectmat,1)
2322     inplnk=zeros(inpptr($)-1,1);outlnk=zeros(outptr($)-1,1);ptlnk=1;
2323
2324     for jj=1:nlnk
2325         ko=outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)
2326         ki=inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)
2327         if ko<>0 & ki<>0 then
2328             if ko>ki then
2329                 outlnk(outlnk>ko)=outlnk(outlnk>ko)-1
2330                 outlnk(outlnk==ko)=ki
2331                 inplnk(inplnk>ko)=inplnk(inplnk>ko)-1
2332                 inplnk(inplnk==ko)=ki
2333                 ptlnk=-1+ptlnk
2334             elseif ki>ko
2335                 outlnk(outlnk>ki)=outlnk(outlnk>ki)-1
2336                 outlnk(outlnk==ki)=ko
2337                 inplnk(inplnk>ki)=inplnk(inplnk>ki)-1
2338                 inplnk(inplnk==ki)=ko
2339                 ptlnk=-1+ptlnk
2340             end
2341         elseif ko<>0 then
2342             inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)=ko
2343         elseif ki<>0 then
2344             outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)=ki
2345         else
2346             outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)=ptlnk
2347             inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)=ptlnk
2348             ptlnk=1+ptlnk
2349         end
2350     end
2351
2352     //store unconnected outputs, if any, at the end of outtb
2353     for unco=find(outlnk==0);
2354         outlnk(unco)=max(outlnk)+1
2355     end
2356
2357     //store unconnected inputs, if any, at the end of outtb
2358     for unco=find(inplnk==0);
2359         inplnk(unco)=max([inplnk;max(outlnk)])+1
2360     end
2361 endfunction
2362
2363 function [evoutoin,evoutoinptr]=synch_clkconnect(typ_l,clkconnect)
2364     nblk=size(typ_l,"*")
2365     evoutoin=[];evoutoinptr=1
2366     for i=1:nblk
2367         if typ_l(i) then
2368             dd=clkconnect(clkconnect(:,1)==i,3)
2369         else
2370             dd=[]
2371         end
2372         evoutoin=[evoutoin;dd]
2373         evoutoinptr=[evoutoinptr;evoutoinptr($)+size(dd,"*")]
2374     end
2375 endfunction
2376
2377 function   clkconnect=cleanup(clkconnect)
2378     mm=max(clkconnect)+1
2379     cc=clkconnect(:,4)+mm*clkconnect(:,3)+clkconnect(:,2)*mm^2+..
2380     clkconnect(:,1)*mm^3
2381     [cc1,ind]=gsort(-cc)
2382     clkconnect=clkconnect(ind,:)
2383     ind=find(cc1(2:$)-cc1(1:$-1)==0)
2384     clkconnect(ind,:)=[]
2385 endfunction
2386
2387 //function mat=cleanup1(mat)
2388 //  mm=max(mat)+1
2389 //  cc=mat(:,1)*mm
2390 //  [cc1,ind]=gsort(-cc)
2391 //  mat=mat(ind,:)
2392 //  ind=find(cc1(2:$)-cc1(1:$-1)==0)
2393 //  mat(ind,:)=[]
2394 //endfunction
2395
2396 function vec=intersection(vec1,vec2)
2397     vec=[]
2398     for i=1:size(vec1,1)
2399         if find(vec1(i)==vec2)~=[] then
2400             vec=[vec;vec1(i)]
2401         end
2402     end
2403 endfunction
2404
2405 function  [r,ok]=newc_tree2(vec,outoin,outoinptr,dep_u,dep_uptr)
2406     dd=zeros(dep_u);dd(dep_u)=1;
2407     [r,ok2]=ctree2(vec,outoin,outoinptr,dd,dep_uptr)
2408     ok=ok2==1
2409 endfunction
2410
2411 function  [r,ok]=new_tree2(vec,outoin,outoinptr,dep_u,dep_uptr)
2412     dd=zeros(dep_u);dd(dep_u)=1;
2413     [r,ok2]=sci_tree2(vec,outoin,outoinptr,dd)
2414     ok=ok2==1
2415 endfunction
2416
2417 function  [r,ok]=new_tree3(vec,dep_ut,typ_l)
2418     dd=zeros(dep_ut);dd(dep_ut)=1;
2419     [r2,ok2]=sci_tree3(vec,dd,typ_l,bexe,boptr,blnk,blptr)
2420     r=r2'
2421     ok=ok2==1
2422 endfunction
2423
2424 function  [r,ok]=newc_tree3(vec,dep_u,dep_uptr,typ_l)
2425     dd=zeros(dep_u);dd(dep_u)=1;
2426     [r2,ok2]=ctree3(vec,dd,dep_uptr,typ_l,bexe,boptr,blnk,blptr)
2427     r=r2'
2428     ok=ok2==1
2429 endfunction
2430
2431 function  [r,ok]=new_tree4(vec,outoin,outoinptr,typ_r)
2432     if isempty(outoin) then
2433         nd=zeros(size(vec,"*"),1);
2434     else
2435         nd=zeros(size(vec,"*"),(max(outoin(:,2))+1));
2436     end
2437     ddd=zeros(typ_r);ddd(typ_r)=1;
2438     [r1,r2]=sci_tree4(vec,outoin,outoinptr,nd,ddd)
2439     r=[r1',r2']
2440     ok=%t
2441 endfunction
2442
2443 function  [r,ok]=newc_tree4(vec,outoin,outoinptr,typ_r)
2444     if isempty(outoin) then
2445         nd=zeros(size(vec,"*"),1);
2446     else
2447         nd=zeros(size(vec,"*"),(max(outoin(:,2))+1));
2448     end
2449     ddd=zeros(typ_r);ddd(typ_r)=1;
2450     [r1,r2]=ctree4(vec,outoin,outoinptr,nd,ddd)
2451     r=[r1',r2']
2452     ok=%t
2453 endfunction
2454
2455 function [critev]=critical_events(connectmat,clkconnect,dep_t,typ_r,..
2456     typ_l,typ_zx,outoin,outoinptr,clkptr)
2457
2458     if isempty(clkconnect) then
2459         critev = [];
2460         return
2461     end
2462
2463     typ_c=typ_l<>typ_l;
2464     typ_r=typ_r|dep_t
2465
2466     done1=%f
2467     while ~done1
2468         done1=%t
2469         [clkr,clkc]=size(clkconnect);
2470         mm=max(clkconnect)+1;
2471
2472         cll=clkconnect(:,1)*mm+clkconnect(:,2);
2473         [cll,ind]=gsort(-cll);
2474         clkconnect=clkconnect(ind,:);
2475         cll=[-1;-cll;mm];
2476         ii=find(cll(2:$)-cll(1:$-1)<>0)
2477
2478         for k=1:size(ii,"*")-1
2479             oo=[ii(k):ii(k+1)-1]
2480             vec=-ones(1,nblk);
2481             vec(clkconnect(oo,3))=0
2482             [r,ok]=newc_tree4(vec,outoin,outoinptr,typ_r)
2483
2484             m=size(r,1)
2485             r=[clkconnect(ii(k),1)*ones(m,1),clkconnect(ii(k),2)*ones(m,1),r]
2486             clkconnect=[clkconnect;r]
2487         end
2488
2489         done=%f;
2490         while ~done
2491             done=%t;
2492             for jj=find(typ_l&(~typ_c));
2493                 if ~or(jj==clkconnect(:,3)) then
2494                     typ_r(clkconnect(find(jj==clkconnect(:,1)),3))=%t
2495                     clkconnect(find(jj==clkconnect(:,1)),:)=[];
2496                     typ_c(jj)=%t;
2497                     done1=%f
2498                     done=%f
2499                 end
2500             end
2501         end
2502     end
2503     critev=zeros(clkptr($)-1,1);
2504     for bb=1:size(clkptr,1)-1
2505         for i=clkptr(bb):clkptr(bb+1)-1
2506             if or(typ_zx(clkconnect(find((clkconnect(:,1)==bb)&..
2507                 (clkconnect(:,2)==i-clkptr(bb)+1)),3))) then
2508                 critev(i)=1
2509             end
2510         end
2511     end
2512 endfunction
2513
2514 // adjust_typ: It resolves positive and negative port types.
2515 //                 Its Algorithm is based on the algorithm of adjust_inout
2516 // Fady NASSIF: 14/06/2007
2517
2518 function [ok,bllst]=adjust_typ(bllst,connectmat)
2519
2520     for i=1:length(bllst)
2521         if size(bllst(i).in,"*")<>size(bllst(i).intyp,"*") then
2522             bllst(i).intyp=bllst(i).intyp(1)*ones(bllst(i).in);
2523         end
2524         if size(bllst(i).out,"*")<>size(bllst(i).outtyp,"*") then
2525             bllst(i).outtyp=bllst(i).outtyp(1)*ones(bllst(i).out);
2526         end
2527     end
2528     nlnk=size(connectmat,1)
2529     for hhjj=1:length(bllst)+1
2530         for hh=1:length(bllst)+1
2531             ok=%t
2532             for jj=1:nlnk
2533                 nnout(1,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2))
2534                 nnout(1,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2))
2535                 nnin(1,1)=bllst(connectmat(jj,3)).in(connectmat(jj,4))
2536                 nnin(1,2)=bllst(connectmat(jj,3)).in2(connectmat(jj,4))
2537                 outtyp = bllst(connectmat(jj,1)).outtyp(connectmat(jj,2))
2538                 intyp = bllst(connectmat(jj,3)).intyp(connectmat(jj,4))
2539
2540                 //first case : types of source and
2541                 //             target ports are explicitly informed
2542                 //             with positive types
2543                 if (intyp>0 & outtyp>0) then
2544                     //if types of source and target port don't match and aren't double and complex
2545                     //then call bad_connection, set flag ok to false and exit
2546
2547                     if intyp<>outtyp then
2548                         if (intyp==1 & outtyp==2) then
2549                             bllst(connectmat(jj,3)).intyp(connectmat(jj,4))=2;
2550                         elseif (intyp==2 & outtyp==1) then
2551                             bllst(connectmat(jj,1)).outtyp(connectmat(jj,2))=2;
2552                         else
2553                             bad_connection(corinv(connectmat(jj,1)),connectmat(jj,2),..
2554                             nnout,outtyp,..
2555                             corinv(connectmat(jj,3)),connectmat(jj,4),..
2556                             nnin,intyp,1)
2557                             ok=%f;
2558                             return
2559                         end
2560                     end
2561
2562                     //second case : type of source port is
2563                     //              positive and type of
2564                     //              target port is negative
2565                 elseif(outtyp>0&intyp<0) then
2566                     //find vector of input ports of target block with
2567                     //type equal to intyp
2568                     //and assign it to outtyp
2569                     ww=find(bllst(connectmat(jj,3)).intyp==intyp)
2570                     bllst(connectmat(jj,3)).intyp(ww)=outtyp
2571
2572                     //find vector of output ports of target block with
2573                     //type equal to intyp
2574                     //and assign it to outtyp
2575                     ww=find(bllst(connectmat(jj,3)).outtyp==intyp)
2576                     bllst(connectmat(jj,3)).outtyp(ww)=outtyp
2577
2578                     //third case : type of source port is
2579                     //             negative and type of
2580                     //             target port is positive
2581                 elseif(outtyp<0&intyp>0) then
2582                     //find vector of output ports of source block with
2583                     //type equal to outtyp
2584                     //and assign it to intyp
2585                     ww=find(bllst(connectmat(jj,1)).outtyp==outtyp)
2586                     bllst(connectmat(jj,1)).outtyp(ww)=intyp
2587
2588                     //find vector of input ports of source block with
2589                     //type equal to size outtyp
2590                     //and assign it to intyp
2591                     ww=find(bllst(connectmat(jj,1)).intyp==outtyp)
2592                     bllst(connectmat(jj,1)).intyp(ww)=intyp
2593
2594
2595                     //fourth (& last) case : type of both source
2596                     //                      and target port are negatives
2597                 else
2598                     ok=%f //set flag ok to false
2599                 end
2600             end
2601             if ok then return, end //if ok is set true then exit adjust_typ
2602         end
2603         //if failed then display message
2604         tmp = _("Not enough information to find port type.\nI will try to find the problem.")
2605         messagebox(msprintf(tmp),"modal","info");
2606         findflag=%f
2607         for jj=1:nlnk
2608             nouttyp=bllst(connectmat(jj,1)).outtyp(connectmat(jj,2))
2609             nintyp=bllst(connectmat(jj,3)).intyp(connectmat(jj,4))
2610
2611             //loop on the two dimensions of source/target port
2612             //only case : target and source ports are both
2613             //            negative or null
2614             if nouttyp<=0 & nintyp<=0 then
2615                 findflag=%t;
2616                 //
2617                 inouttyp=under_connection(corinv(connectmat(jj,1)),connectmat(jj,2),nouttyp,..
2618                 corinv(connectmat(jj,3)),connectmat(jj,4),nintyp,2)
2619                 //
2620                 if inouttyp<1|inouttyp>8 then ok=%f;return;end
2621                 //
2622                 ww=find(bllst(connectmat(jj,1)).outtyp==nouttyp)
2623                 bllst(connectmat(jj,1)).outtyp(ww)=inouttyp
2624
2625                 //
2626                 ww=find(bllst(connectmat(jj,1)).intyp==nouttyp)
2627                 bllst(connectmat(jj,1)).intyp(ww)=inouttyp
2628
2629                 ww=find(bllst(connectmat(jj,3)).intyp==nintyp)
2630                 bllst(connectmat(jj,3)).intyp(ww)=inouttyp
2631                 //
2632                 ww=find(bllst(connectmat(jj,3)).outtyp==nintyp)
2633                 bllst(connectmat(jj,3)).outtyp(ww)=inouttyp
2634
2635                 //
2636             end
2637         end
2638         //if failed then display message
2639         if ~findflag then
2640             msg = _("I cannot find a link with undetermined size.\nMy guess is that you have a block with unconnected \nundetermined types.")
2641             messagebox(msprintf(msg), "modal","error")
2642             ok = %f
2643             return
2644         end
2645     end
2646 endfunction
2647