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
22function 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
216endfunction
217
218
219//donne les sources d'activation du sch�ma
220function [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
233endfunction
234
235
236
237//insere le vecteur primary dans vec_clk apr�s la ligne comptenant le bloc i
238function 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
259endfunction
260
261//insere la sous-matrice primary dans vec_clk apr�s la ligne k
262function 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
286endfunction
287
288//insere la sous-matrice ordoclk0 dans ordclk apr�s le block k
289function [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
344endfunction
345
346
347//donne les blocs activant blk
348function [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
361endfunction
362
363
364function [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
377endfunction
378
379function [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
392endfunction
393
394
395function [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
408endfunction
409
410
411function [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
420endfunction
421
422
423function [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
436endfunction
437
438
439function 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),:)
449endfunction
450
451function [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
479endfunction
480
481function [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
495endfunction
496
497
498function 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
519endfunction
520
521function [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
730endfunction
731
732function  [primary0,port0]=aggregate(primary0,port0)
733    primary=discardprimary([primary0,port0]) // must rewrite
734    primary0=primary(:,1);port0=primary(:,2)
735endfunction
736
737
738function [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
756endfunction
757
758//suppression des liens inutiles
759function [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
788endfunction
789
790function [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
804endfunction
805
806
807function  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
815endfunction
816
817function [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
852endfunction
853
854function [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
886endfunction
887
888
889function  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
906endfunction
907
908function  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
915endfunction
916
917function [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
948endfunction
949
950function 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
975endfunction
976
977
978
979
980function [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
1102endfunction
1103
1104function [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))=[];
1135endfunction
1136
1137function [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
1166endfunction
1167
1168function a=mysum(b)
1169    if b<>[] then a=sum(b), else a=[], end
1170endfunction
1171
1172function [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
1466endfunction
1467
1468function [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
1487endfunction
1488
1489function [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(:)
1519endfunction
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
1563function [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
2055endfunction
2056
2057function 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
2076endfunction
2077
2078//19/01/07, Alan : under_connection show bad link and returns two dimensions now
2079function 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
2154endfunction
2155
2156function [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
2220endfunction
2221
2222function [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
2245endfunction
2246
2247function [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 column 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
2361endfunction
2362
2363function [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
2375endfunction
2376
2377function   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,:)=[]
2385endfunction
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
2396function 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
2403endfunction
2404
2405function  [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
2409endfunction
2410
2411function  [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
2415endfunction
2416
2417function  [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
2422endfunction
2423
2424function  [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
2429endfunction
2430
2431function  [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
2441endfunction
2442
2443function  [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
2453endfunction
2454
2455function [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
2512endfunction
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
2518function [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
2646endfunction
2647
2648