Changeset 51dd041 in OpenModelica


Ignore:
Timestamp:
2022-11-08T08:21:24+01:00 (17 months ago)
Author:
kabdelhak <karim.abdelhak@…>
Children:
08e5f0e
Parents:
d2012370
git-author:
kabdelhak <karim.abdelhak@…> (11/03/22 11:39:54)
git-committer:
kabdelhak <karim.abdelhak@…> (11/08/22 08:21:24)
Message:

[NF] Further updates to SBGraph connect algorithm

  • new complement functions
  • error handling
Location:
OMCompiler/Compiler/Util
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • OMCompiler/Compiler/Util/SBAtomicSet.mo

    rcea85cf r51dd041  
    112112  end crossProd;
    113113
     114  function normalize
     115    input SBAtomicSet set1;
     116    input SBAtomicSet set2;
     117    output SBAtomicSet res;
     118  algorithm
     119    res := new(SBMultiInterval.normalize(set1.aset, set2.aset));
     120  end normalize;
     121
    114122  function cardinality
    115123    input SBAtomicSet set;
  • OMCompiler/Compiler/Util/SBFunctions.mo

    rd2012370 r51dd041  
    211211  end minPW;
    212212
    213   function minMap
     213  function minMap2
    214214    input SBPWLinearMap pw1;
    215215    input SBPWLinearMap pw2;
     
    245245      end for;
    246246    end for;
    247   end minMap;
     247  end minMap2;
    248248
    249249  function reduceMapN
     
    253253  protected
    254254    array<SBSet> dom, new_s;
    255     Vector<SBSet> sres;
    256255    array<SBLinearMap> lmap, new_l;
    257     Vector<SBLinearMap> lres;
    258256    SBPWLinearMap pw_copy, new_map;
    259     SBSet di, new_domi;
     257    SBSet di, new_domi, reduced, not_reduced;
    260258    SBLinearMap li, new_lm;
    261259    Real gdim, odim;
     
    263261    SBMultiInterval mi;
    264262    SBInterval idim, new_inter;
    265     Integer loint, hiint;
    266     array<Real> resg, reso;
     263    Integer loint, stint, hiint, newoff;
    267264    SBAtomicSet aux_as;
    268265    UnorderedSet<SBAtomicSet> aux_newd;
     
    273270
    274271    pw_copy := SBPWLinearMap.copy(pw);
    275     sres := Vector.fromArray(SBPWLinearMap.dom(pw_copy));
    276     lres := Vector.fromArray(SBPWLinearMap.lmap(pw_copy));
     272    outMap := SBPWLinearMap.newEmpty();
     273    outMap.ndim := pw.ndim;
    277274
    278275    for i in 1:arrayLength(dom) loop
     
    282279      odim := arrayGet(SBLinearMap.offset(li), dim);
    283280
    284       if gdim == 1 and odim < 0 then
    285         off := realInt(-odim);
     281      if gdim == 1 and odim <> 0 then
     282        off := intAbs(realInt(odim));
    286283        asets := UnorderedSet.toArray(SBSet.asets(di));
    287284
     
    290287          idim := arrayGet(SBMultiInterval.intervals(mi), dim);
    291288          loint := SBInterval.lowerBound(idim);
     289          stint := SBInterval.stepValue(idim);
    292290          hiint := SBInterval.upperBound(idim);
    293291
    294           if hiint - loint > off * off then
    295             new_s := arrayCreateNoInit(off, di);
    296             new_l := arrayCreateNoInit(off, li);
    297 
    298             for k in 1:off loop
    299               resg := arrayCopy(SBLinearMap.gain(li));
    300               reso := arrayCopy(SBLinearMap.offset(li));
    301               resg[dim] := 0;
    302               reso[dim] := loint + k - off - 1;
    303 
    304               new_l[k] := SBLinearMap.new(resg, reso);
    305 
    306               new_inter := SBInterval.new(loint + k - 1, off, hiint);
    307               aux_as := SBAtomicSet.replace(new_inter, dim, adom);
    308               new_s[k] := SBSet.addAtomicSet(aux_as, SBSet.newEmpty());
    309             end for;
    310 
    311             new_map := SBPWLinearMap.new(new_s, new_l);
    312 
    313             aux_newd := UnorderedSet.new(SBAtomicSet.hash, SBAtomicSet.isEqual);
    314             for aux_asi in asets loop
    315               if not SBAtomicSet.isEqual(aux_asi, adom) then
    316                 UnorderedSet.add(aux_asi, aux_newd);
    317               end if;
    318             end for;
    319 
    320             new_domi := SBSet.new(aux_newd);
    321 
    322             if SBSet.isEmpty(new_domi) then
    323               if i < Vector.size(sres) then
    324                 Vector.remove(sres, i);
    325                 Vector.remove(lres, i);
    326               else
    327                 Vector.shrink(sres, i + 1);
    328                 Vector.shrink(lres, i + 1);
    329               end if;
    330             else
    331               Vector.update(sres, i, new_domi);
     292          // Map's image is in adom, reduction is plausible
     293          if intMod(off, stint) == 0 then
     294            if ((hiint - loint) / stint) > off * off then
     295              new_s := arrayCreateNoInit(off, di);
     296              new_l := arrayCreateNoInit(off, li);
     297
     298              for k in 1:off loop
     299                new_inter := SBInterval.new(loint + k - 1, off, hiint);
     300                aux_as := SBAtomicSet.replace(new_inter, dim, adom);
     301                new_s[k] := SBSet.addAtomicSet(aux_as, SBSet.newEmpty());
     302
     303                if odim > 0 then
     304                  newoff := realInt(SBInterval.upperBound(new_inter) + odim);
     305                else
     306                  newoff := realInt(SBInterval.lowerBound(new_inter) + odim);
     307                end if;
     308                new_l[k] := SBLinearMap.replace(SBLinearMap.copy(lmap[i]), 0, newoff, dim);
     309              end for;
     310              new_map := SBPWLinearMap.new(new_s, new_l);
     311              outMap  := SBPWLinearMap.combine(outMap, new_map);
    332312            end if;
    333 
    334             Vector.appendArray(sres, SBPWLinearMap.dom(new_map));
    335             Vector.appendArray(lres, SBPWLinearMap.lmap(new_map));
    336313          end if;
    337314        end for;
     
    339316    end for;
    340317
    341     outMap := SBPWLinearMap.new(Vector.toArray(sres), Vector.toArray(lres));
     318    // Add intervals that weren't reduced
     319    reduced := SBPWLinearMap.wholeDom(outMap);
     320    for i in 1:arrayLength(dom) loop
     321      not_reduced := SBSet.complement(dom[i], reduced);
     322
     323      if not SBSet.isEmpty(not_reduced) then
     324        new_map := SBPWLinearMap.new(arrayCreate(1, not_reduced), arrayCreate(1, lmap[i]));
     325        outMap  := SBPWLinearMap.combine(outMap, new_map);
     326      end if;
     327    end for;
    342328  end reduceMapN;
    343329
     
    348334  protected
    349335    Integer i;
    350     SBPWLinearMap original = pw, old = SBPWLinearMap.newEmpty();
     336    SBPWLinearMap old = SBPWLinearMap.newEmpty();
    351337  algorithm
    352338    if not SBPWLinearMap.isEmpty(pw) then
     
    362348      else
    363349        old := res;
    364         res := SBPWLinearMap.compPW(res, pw);
     350        for j in 1:SBPWLinearMap.ndim(res) loop
     351          res := reduceMapN(res, j);
     352        end for;
    365353        for j in 1:SBPWLinearMap.ndim(old) loop
    366354          old := reduceMapN(old, j);
    367355        end for;
    368         for j in 1:SBPWLinearMap.ndim(res) loop
    369           res := reduceMapN(res, j);
    370         end for;
     356        res := SBPWLinearMap.compPW(res, res);
    371357
    372358        while not SBPWLinearMap.isEqual(old, res) loop
    373359          old := res;
    374           res := SBPWLinearMap.compPW(res, pw);
     360          res := SBPWLinearMap.compPW(res, res);
    375361          for j in 1:SBPWLinearMap.ndim(res) loop
    376362            res := reduceMapN(res, j);
     
    381367  end mapInf;
    382368
    383   function minAdjCompMap
    384     input SBPWLinearMap pw2;
    385     input SBPWLinearMap pw1;
    386     output SBPWLinearMap outMap;
    387   protected
    388     array<SBSet> dom;
    389     array<SBLinearMap> lmap;
    390     SBSet d, dom_inv, aux;
    391     SBLinearMap lm_inv, aux_lm1, aux_lm2, lm_res;
    392     SBPWLinearMap inv_pw, aux_inv, aux_res;
    393     Real min_g, max_g, inf, g;
    394     array<Integer> min_aux;
    395     array<Real> resg, reso, gain, off, gres, oi, ginv;
    396   algorithm
    397     dom := SBPWLinearMap.dom(pw2);
    398     lmap := SBPWLinearMap.lmap(pw2);
    399 
    400     if arrayLength(dom) <> 1 then
    401       // Warning: There should be only one pair in the map.
    402       outMap := SBPWLinearMap.newEmpty();
    403       return;
    404     end if;
    405 
    406     d := dom[1];
    407     dom_inv := SBPWLinearMap.image(pw2, d);
    408     lm_inv := SBLinearMap.inverse(lmap[1]);
    409 
    410     inv_pw := SBPWLinearMap.newScalar(dom_inv, lm_inv);
    411     inf := intReal(System.intMaxLit());
    412 
    413     if Array.maxElement(SBLinearMap.gain(lm_inv), realLt) < inf then
    414       outMap := SBPWLinearMap.compPW(pw1, inv_pw);
    415     elseif Array.minElement(SBLinearMap.gain(lm_inv), realLt) == inf then
    416       if not SBPWLinearMap.isEmpty(pw2) then
    417         aux := SBPWLinearMap.image(pw1, d);
    418         min_aux := SBSet.minElem(aux);
    419         resg := arrayCreate(arrayLength(min_aux), 0.0);
    420         reso := Array.map(min_aux, intReal);
    421         lm_res := SBLinearMap.new(resg, reso);
    422         outMap := SBPWLinearMap.newScalar(dom_inv, lm_res);
    423       else
    424         outMap := SBPWLinearMap.newEmpty();
    425       end if;
    426     else
    427       min_aux := SBSet.minElem(d);
    428       gain := SBLinearMap.gain(lm_inv);
    429       off := SBLinearMap.offset(lm_inv);
    430       resg := arrayCreateNoInit(arrayLength(gain), 0.0);
    431       reso := arrayCreateNoInit(arrayLength(gain), 0.0);
    432 
    433       for i in 1:arrayLength(gain) loop
    434         g := arrayGetNoBoundsChecking(gain, i);
    435 
    436         if g == inf then
    437           resg[i] := 0.0;
    438           reso[i] := intReal(min_aux[i]);
    439         else
    440           resg[i] := g;
    441           reso[i] := off[i];
     369  partial function minAdjFunc
     370    input SBPWLinearMap map1 "source: *this";
     371    input SBPWLinearMap map2 "source: pw2";
     372    input SBPWLinearMap map3 "source: pw1";
     373    output SBPWLinearMap res;
     374  end minAdjFunc;
     375
     376  function minAdjWrapper
     377    input SBPWLinearMap map1 "source: *this";
     378    input SBPWLinearMap map2 "source: pw1";
     379    input minAdjFunc func;
     380    output SBPWLinearMap res;
     381  protected
     382    SBSet whole_dom, image_dom;
     383    SBPWLinearMap map2_identity "source: pw2";
     384  algorithm
     385    whole_dom     := SBPWLinearMap.wholeDom(map2);
     386    image_dom     := SBPWLinearMap.image(map2, whole_dom);
     387    map2_identity := SBPWLinearMap.newIdentity(image_dom);
     388    // apply function
     389    res := func(map1, map2, map2_identity);
     390  end minAdjWrapper;
     391
     392  function minAdjMap extends minAdjFunc;
     393  protected
     394    SBPWLinearMap aux_map, min_adj, min_map;
     395  algorithm
     396    if not SBPWLinearMap.isEmpty(map1) then
     397      aux_map := SBPWLinearMap.new(arrayCreate(1, map1.dom[1]), arrayCreate(1, map1.lmap[1]));
     398      res := minAdjCompMap(aux_map, map2, map3);
     399      for i in 2:arrayLength(map1.dom) loop
     400        aux_map := SBPWLinearMap.new(arrayCreate(1, map1.dom[i]), arrayCreate(1, map1.lmap[i]));
     401        min_adj := minAdjCompMap(aux_map, map2, map3);
     402        min_map := minMap(aux_map, map2, map3);
     403        res     := SBPWLinearMap.combine(min_adj, res);
     404        if not SBPWLinearMap.isEmpty(min_map) then
     405          res   := SBPWLinearMap.combine(min_map, res);
    442406        end if;
    443407      end for;
    444 
    445       aux_lm1 := SBLinearMap.new(resg, reso);
    446       aux_inv := SBPWLinearMap.newScalar(dom_inv, aux_lm1);
    447       aux_res := SBPWLinearMap.compPW(pw1, aux_inv);
    448 
    449       if SBPWLinearMap.isEmpty(aux_res) then
    450         outMap := SBPWLinearMap.newEmpty();
     408    else
     409      res := SBPWLinearMap.newEmpty();
     410    end if;
     411  end minAdjMap;
     412
     413  function minAdjCompMap extends minAdjFunc;
     414  protected
     415    Vector<SBSet> new_dom;
     416    Vector<SBLinearMap> new_lmap;
     417    SBSet inv_image, image2, image12, scomp, mins2;
     418    SBAtomicSet aset;
     419    SBLinearMap inv_map, new_map;
     420    SBPWLinearMap inv_pw, new_inv_pw, auxres;
     421    Real max_gain, min_gain;
     422    SBMultiInterval mi_comp;
     423    array<Integer> min1, min2;
     424    array<Real> new_gain, new_offset;
     425  algorithm
     426    new_dom   := Vector.new<SBSet>();
     427    new_lmap  := Vector.new<SBLinearMap>();
     428    if arrayLength(map1.dom) == 1 then
     429      inv_image := SBPWLinearMap.image(map1, map1.dom[1]);
     430      inv_map   := SBLinearMap.inverse(map1.lmap[1]);
     431      inv_pw    := SBPWLinearMap.new(arrayCreate(1, inv_image), arrayCreate(1, inv_map));
     432
     433      max_gain := Array.maxElement(inv_map.gain, realLt);
     434      min_gain := Array.minElement(inv_map.gain, realLt);
     435
     436      if max_gain < System.realMaxLit() then
     437        // bijective -> invertible
     438        res := SBPWLinearMap.compPW(map2, inv_pw);
     439        return;
     440      elseif min_gain == System.realMaxLit() then
     441        // constant map
     442        if not SBPWLinearMap.isEmpty(map1) then
     443          image2  := SBPWLinearMap.image(map2, map1.dom[1]);
     444          image12 := SBPWLinearMap.image(map1, image2);
     445
     446          // Get vertices in image of pw2 with minimum image in pw1
     447          mi_comp := SBMultiInterval.fromList(list(SBInterval.newSingle(i) for i in SBSet.minElem(image12)));
     448          aset  := SBAtomicSet.new(mi_comp);
     449          scomp := SBSet.newEmpty();
     450          scomp := SBSet.addAtomicSet(aset, scomp);
     451          mins2 := SBPWLinearMap.preImage(map3, scomp);
     452          mins2 := SBSet.intersection(mins2, image2);
     453          min2  := SBSet.minElem(mins2);
     454
     455          new_gain    := arrayCreate(inv_image.ndim, 0.0);
     456          new_offset  := listArray(list(intReal(i) for i in min2));
     457          new_map := SBLinearMap.new(new_gain, new_offset);
     458
     459          Vector.push(new_dom, inv_image);
     460          Vector.push(new_lmap, new_map);
     461        end if;
    451462      else
    452         aux := SBPWLinearMap.image(pw1, d);
    453         min_aux := SBSet.minElem(aux);
    454         lm_res := arrayGet(SBPWLinearMap.lmap(aux_res), 1);
    455         gres := SBLinearMap.gain(lm_res);
    456         oi := SBLinearMap.offset(lm_res);
    457         ginv := SBLinearMap.gain(lm_inv);
    458 
    459         for i in 1:arrayLength(gain) loop
    460           g := arrayGetNoBoundsChecking(gain, i);
    461 
    462           if g == inf then
    463             resg[i] := 0.0;
    464             reso[i] := intReal(min_aux[i]);
     463        // bijective in some dimensions, and constant in others
     464        min1  := SBSet.minElem(map1.dom[1]);
     465
     466        new_gain    := arrayCreate(arrayLength(inv_map.gain), 0.0);
     467        new_offset  := arrayCreate(arrayLength(inv_map.offset), 0.0);
     468        for i in 1:arrayLength(inv_map.gain) loop
     469          if inv_map.gain[i] < System.realMaxLit() then
     470            new_gain[i]   := inv_map.gain[i];
     471            new_offset[i] := inv_map.offset[i];
    465472          else
    466             resg[i] := gres[i];
    467             reso[i] := oi[i];
     473            new_offset[i] := intReal(min1[i]);
    468474          end if;
    469475        end for;
    470 
    471         aux_lm2 := SBLinearMap.new(resg, reso);
    472         outMap := SBPWLinearMap.newScalar(arrayGet(SBPWLinearMap.dom(aux_res), 1), aux_lm2);
     476        new_map := SBLinearMap.new(new_gain, new_offset);
     477        new_inv_pw := SBPWLinearMap.new(arrayCreate(1, inv_image), arrayCreate(1, new_map));
     478
     479        // compose
     480        auxres := SBPWLinearMap.compPW(map2, new_inv_pw);
     481
     482        // Replace values of constant maps with the desired value
     483        image2  := SBPWLinearMap.image(map2, map1.dom[1]);
     484        image12 := SBPWLinearMap.image(map1, image2);
     485
     486        // Get vertices in image of pw2 with minimum image in pw1
     487        mi_comp := SBMultiInterval.fromList(list(SBInterval.newSingle(i) for i in SBSet.minElem(image12)));
     488        aset  := SBAtomicSet.new(mi_comp);
     489        scomp := SBSet.newEmpty();
     490        scomp := SBSet.addAtomicSet(aset, scomp);
     491        mins2 := SBPWLinearMap.preImage(map3, scomp);
     492        mins2 := SBSet.intersection(mins2, image2);
     493        min2  := SBSet.minElem(mins2);
     494
     495        for i in 1:arrayLength(auxres.dom) loop
     496          new_gain    := arrayCreate(arrayLength(inv_map.gain), 0.0);
     497          new_offset  := arrayCreate(arrayLength(inv_map.offset), 0.0);
     498
     499          for j in 1:arrayLength(inv_map.gain) loop
     500            if inv_map.gain[j] < System.realMaxLit() then
     501              new_gain[j]   := auxres.lmap[i].gain[j];
     502              new_offset[j] := auxres.lmap[i].offset[j];
     503            else
     504              new_offset[j] := intReal(min2[i]);
     505            end if;
     506          end for;
     507
     508          new_map := SBLinearMap.new(new_gain, new_offset);
     509
     510          Vector.push(new_dom, auxres.dom[i]);
     511          Vector.push(new_lmap, new_map);
     512        end for;
    473513      end if;
    474514    end if;
     515
     516    res := SBPWLinearMap.new(Vector.toArray(new_dom), Vector.toArray(new_lmap));
    475517  end minAdjCompMap;
    476518
    477   function minAdjMap
    478     input SBPWLinearMap pw2;
    479     input SBPWLinearMap pw1;
    480     output SBPWLinearMap outMap;
    481   protected
    482     array<SBSet> dom2;
    483     array<SBLinearMap> lm2;
    484     SBPWLinearMap map1, mapi, min_adj, min_m;
    485   algorithm
    486     if SBPWLinearMap.isEmpty(pw2) then
    487       outMap := SBPWLinearMap.newEmpty();
    488       return;
    489     end if;
    490 
    491     dom2 := SBPWLinearMap.dom(pw2);
    492     lm2 := SBPWLinearMap.lmap(pw2);
    493     map1 := SBPWLinearMap.newScalar(dom2[1], lm2[1]);
    494     outMap := minAdjCompMap(map1, pw1);
    495 
    496     for i in 1:arrayLength(dom2) loop
    497       mapi := SBPWLinearMap.newScalar(dom2[i], lm2[i]);
    498       min_adj := minAdjCompMap(mapi, pw1);
    499       min_m := minMap(outMap, min_adj);
    500 
    501       outMap := SBPWLinearMap.combine(min_adj, outMap);
    502 
    503       if not SBPWLinearMap.isEmpty(min_m) then
    504         outMap := SBPWLinearMap.combine(min_m, outMap);
     519  function minMap extends minAdjFunc;
     520  protected
     521    SBSet dom;
     522    SBPWLinearMap aux;
     523  algorithm
     524    res := SBPWLinearMap.newEmpty();
     525    if not (SBPWLinearMap.isEmpty(map1) or SBPWLinearMap.isEmpty(map2)) then
     526      for i in 1:arrayLength(map1.dom) loop
     527        for j in 1:arrayLength(map2.dom) loop
     528          dom := SBSet.intersection(map1.dom[i], map2.dom[j]);
     529          if not SBSet.isEmpty(dom) then
     530            aux := minMapSet(dom, map1.lmap[i], map2.lmap[j]);
     531            if SBPWLinearMap.isEmpty(res) then
     532              res := aux;
     533            else
     534              res := SBPWLinearMap.combine(aux, res);
     535            end if;
     536          end if;
     537        end for;
     538      end for;
     539    end if;
     540  end minMap;
     541
     542  function minMapSet
     543    input SBSet dom;
     544    input SBLinearMap lm1;
     545    input SBLinearMap lm2;
     546    output SBPWLinearMap res;
     547  protected
     548    SBLinearMap idlm;
     549  algorithm
     550    if SBLinearMap.ndim(lm1) == SBLinearMap.ndim(lm2) then
     551      idlm := SBLinearMap.newIdentity(SBLinearMap.ndim(lm1));
     552      res := minMapSet2(dom, lm1, lm2, idlm, idlm);
     553    else
     554      res := SBPWLinearMap.newEmpty();
     555    end if;
     556  end minMapSet;
     557
     558  function minMapSet3
     559    input SBSet dom;
     560    input SBLinearMap lm1;
     561    input SBLinearMap lm2;
     562    input SBPWLinearMap map3;
     563    output SBPWLinearMap res = SBPWLinearMap.newEmpty();
     564  protected
     565    SBPWLinearMap map1 = SBPWLinearMap.new(arrayCreate(1, dom), arrayCreate(1, lm1));
     566    SBPWLinearMap map2 = SBPWLinearMap.new(arrayCreate(1, dom), arrayCreate(1, lm2));
     567    SBSet image1, image2, d, d1, d2, pre1, pre2;
     568  algorithm
     569    image1 := SBPWLinearMap.image(map1, dom);
     570    image2 := SBPWLinearMap.image(map2, dom);
     571    for i in 1:arrayLength(map3.dom) loop
     572      d1 := SBSet.intersection(map3.dom[i], image1);
     573      if not SBSet.isEmpty(d1) then
     574        pre1 := SBPWLinearMap.preImage(map1, d1);
     575        for j in 1:arrayLength(map3.dom) loop
     576          d2 := SBSet.intersection(map3.dom[j], image2);
     577          if not SBSet.isEmpty(d2) then
     578            pre2 := SBPWLinearMap.preImage(map2, d2);
     579            d := SBSet.intersection(SBSet.intersection(pre1, pre2), dom);
     580            if not SBSet.isEmpty(d) then
     581              res := SBPWLinearMap.combine(res, minMapSet2(d, lm1, lm2, map3.lmap[i], map3.lmap[j]));
     582            end if;
     583          end if;
     584        end for;
    505585      end if;
    506586    end for;
    507   end minAdjMap;
     587  end minMapSet3;
     588
     589  function minMapSet2
     590    input SBSet dom;
     591    input SBLinearMap lm1;
     592    input SBLinearMap lm2;
     593    input SBLinearMap lm3;
     594    input SBLinearMap lm4;
     595    output SBPWLinearMap res;
     596  protected
     597    SBAtomicSet asAux;
     598    list<SBAtomicSet> asets = UnorderedSet.toList(dom.asets);
     599    SBPWLinearMap aux = SBPWLinearMap.newEmpty();
     600    SBSet sres1, sres2 = SBSet.newEmpty();
     601    SBLinearMap lres1, lres2;
     602    Vector<SBSet> new_dom = Vector.new<SBSet>();
     603    Vector<SBLinearMap> new_lmap = Vector.new<SBLinearMap>();
     604  algorithm
     605    asAux::asets := asets;
     606    if not SBSet.isEmpty(dom) then
     607      aux := minMapAtomSet(aux, asAux, lm1, lm2, lm3, lm4);
     608      if not SBPWLinearMap.isEmpty(aux) then
     609        sres1 := aux.dom[1];
     610        lres1 := aux.lmap[1];
     611        for aset in asets loop
     612          aux := minMapAtomSet(aux, asAux, lm1, lm2, lm3, lm4);
     613          for i in 1:arrayLength(aux.dom) loop
     614            if SBLinearMap.isEqual(aux.lmap[i], lres1) then
     615              sres1 := SBSet.union(sres1, aux.dom[i]);
     616            else
     617              if SBSet.isEmpty(sres2) then
     618                sres2 := aux.dom[i];
     619                lres2 := aux.lmap[i];
     620              else
     621                sres2 := SBSet.union(sres2, aux.dom[i]);
     622              end if;
     623            end if;
     624          end for;
     625        end for;
     626      end if;
     627    end if;
     628
     629    // combine the sets
     630    if not (SBSet.isEmpty(sres1) or SBLinearMap.isEmpty(lres1)) then
     631      Vector.push(new_dom, sres1);
     632      Vector.push(new_lmap, lres1);
     633    end if;
     634    if not (SBSet.isEmpty(sres2) or SBLinearMap.isEmpty(lres2)) then
     635      Vector.push(new_dom, sres2);
     636      Vector.push(new_lmap, lres2);
     637    end if;
     638    res := SBPWLinearMap.new(Vector.toArray(new_dom), Vector.toArray(new_lmap));
     639  end minMapSet2;
     640
     641  function minMapAtomSet
     642    input output SBPWLinearMap res;
     643    input SBAtomicSet dom;
     644    input SBLinearMap lm1;
     645    input SBLinearMap lm2;
     646    input SBLinearMap lm3;
     647    input SBLinearMap lm4;
     648  protected
     649    SBAtomicSet as1, as2;
     650    SBLinearMap lmAux;
     651    SBLinearMap lm31 = SBLinearMap.compose(lm3, lm1);
     652    SBLinearMap lm42 = SBLinearMap.compose(lm4, lm2);
     653    SBSet d1, d2, aux = SBSet.newEmpty();
     654    Vector<SBSet> new_dom = Vector.new<SBSet>();
     655    Vector<SBLinearMap> new_lmap = Vector.new<SBLinearMap>();
     656    SBLinearMap id;
     657    Real xinter;
     658    SBInterval i1, i2;
     659  algorithm
     660    aux := SBSet.addAtomicSet(dom, aux);
     661
     662    // base case
     663    if SBLinearMap.isEqual(lm31, lm42) and SBLinearMap.isEqual(lm1, lm2) then
     664      Vector.push(new_dom, aux);
     665      Vector.push(new_lmap, lm1);
     666      res := SBPWLinearMap.new(Vector.toArray(new_dom), Vector.toArray(new_lmap));
     667      return;
     668    end if;
     669
     670    // need to analyze gains and offsets of lm31 and lm42
     671    if SBLinearMap.ndim(lm31) == SBLinearMap.ndim(lm42) and SBLinearMap.ndim(lm1) == SBLinearMap.ndim(lm2) then
     672      for i in 1:arrayLength(lm31.gain) loop
     673        lmAux := lm1;
     674
     675        if lm31.gain[i] <> lm42.gain[i] then
     676          // different gains, there's intersection
     677          xinter := (lm42.offset[i] - lm31.offset[i]) / (lm31.gain[i] - lm42.gain[i]);
     678
     679          if xinter <= intReal(dom.aset.intervals[i].lo) then
     680            // 1. intersection before domain
     681            if lm42.gain[i] < lm31.gain[i] then
     682              lmAux := lm2;
     683            end if;
     684            Vector.push(new_dom, aux);
     685            Vector.push(new_lmap, lmAux);
     686          elseif xinter >= intReal(dom.aset.intervals[i].hi) then
     687            // 2. intersection after domain
     688            if lm42.gain[i] > lm31.gain[i] then
     689              lmAux := lm2;
     690            end if;
     691            Vector.push(new_dom, aux);
     692            Vector.push(new_lmap, lmAux);
     693          else
     694            // 3. intersection in domain
     695            i1 := SBInterval.INTERVAL(dom.aset.intervals[i].lo, dom.aset.intervals[i].step, realInt(floor(xinter)));
     696            i2 := SBInterval.INTERVAL(i1.hi + i1.step, dom.aset.intervals[i].step, dom.aset.intervals[i].hi);
     697            as1 := SBAtomicSet.replace(i1, i, dom);
     698            as2 := SBAtomicSet.replace(i2, i, dom);
     699            d1 := SBSet.newEmpty();
     700            d2 := SBSet.newEmpty();
     701            d1 := SBSet.addAtomicSet(as1, d1);
     702            d2 := SBSet.addAtomicSet(as2, d2);
     703            Vector.push(new_dom, d1);
     704            Vector.push(new_dom, d2);
     705
     706            if lm31.gain[i] > lm42.gain[i] then
     707              Vector.push(new_lmap, lm1);
     708              Vector.push(new_lmap, lm2);
     709            else
     710              Vector.push(new_lmap, lm2);
     711              Vector.push(new_lmap, lm1);
     712            end if;
     713          end if;
     714          res := SBPWLinearMap.new(Vector.toArray(new_dom), Vector.toArray(new_lmap));
     715          return;
     716        elseif lm31.offset[i] <> lm42.offset[i] then
     717          // same gain and different offset, no intersection
     718          if lm42.offset[i] < lm31.offset[i] then
     719            lmAux := lm2;
     720          end if;
     721          Vector.push(new_dom, aux);
     722          Vector.push(new_lmap, lmAux);
     723          res := SBPWLinearMap.new(Vector.toArray(new_dom), Vector.toArray(new_lmap));
     724          return;
     725        end if;
     726      end for;
     727    end if;
     728
     729    // same gain and offset, get the minimum: lm1 or lm2
     730    id := SBLinearMap.newIdentity(SBLinearMap.ndim(lm1));
     731    res := minMapAtomSet(res, dom, lm1, lm2, id, id);
     732  end minMapAtomSet;
    508733
    509734  function connectedComponents
     
    523748      ermap1 := SBPWLinearMap.compPW(outMap, emap1);
    524749      ermap2 := SBPWLinearMap.compPW(outMap, emap2);
     750
    525751      // combine maps to get minimal connection from left to right and vice versa
    526       rmap1 := minAdjMap(ermap1, ermap2);
    527       rmap2 := minAdjMap(ermap2, ermap1);
     752      rmap1 := minAdjWrapper(ermap1, ermap2, minAdjMap);
     753      rmap2 := minAdjWrapper(ermap2, ermap1, minAdjMap);
    528754      // inverse apply connected minimal indices to connect from cluster to cluster
    529755      rmap1 := SBPWLinearMap.combine(rmap1, outMap);
    530756      rmap2 := SBPWLinearMap.combine(rmap2, outMap);
    531757      // find minimal connections
    532       new_res := minMap(rmap1, rmap2);
     758      new_res := minAdjWrapper(rmap1, rmap2, minMap);
    533759
    534760      last_im := new_im;
  • OMCompiler/Compiler/Util/SBInterval.mo

    rcea85cf r51dd041  
    118118  end newFull;
    119119
     120  function newSingle
     121    input Integer i;
     122    output SBInterval int = INTERVAL(i, 1, i);
     123  end newSingle;
     124
    120125  function lowerBound
    121126    input SBInterval int;
     
    187192    output UnorderedSet<SBInterval> ints;
    188193  protected
    189     SBInterval i2;
    190     Integer count_r, count_s;
     194    SBInterval inter, aux, left, right;
     195    Integer count_r, count_s, nInters;
    191196  algorithm
    192197    ints := UnorderedSet.new(hash, isEqual);
    193     i2 := intersection(int1, int2);
    194 
    195     if isEmpty(i2) then
     198    inter := intersection(int1, int2);
     199
     200    if isEmpty(inter) then
    196201      // No intersection, nothing to remove.
    197202      UnorderedSet.add(int1, ints);
    198     elseif not isEqual(int1, i2) then
     203    elseif not isEqual(int1, inter) then
     204      // "Before" intersection
     205      if int1.lo < inter.lo then
     206        aux := new(int1.lo, 1, inter.lo-1);
     207        left := intersection(int1, aux);
     208        UnorderedSet.add(left, ints);
     209      end if;
     210
     211      // "During" intersection
     212      if inter.step <= (inter.hi - inter.lo) then
     213        nInters := realInt(inter.step / int1.step);
     214        for i in 1:(nInters-1) loop
     215          aux := new(inter.lo + i * int1.step, inter.step, inter.hi);
     216          UnorderedSet.add(aux, ints);
     217        end for;
     218      end if;
     219
     220      // "After" intersection
     221      if int1.hi > inter.hi then
     222        aux := new(inter.hi + 1, 1, int1.hi);
     223        right := intersection(int1, aux);
     224        UnorderedSet.add(right, ints);
     225      end if;
     226
     227      /* This is the old way of doing it, maybe more correct?
    199228      // Rightmost interval.
    200       if i2.hi < int1.hi then
    201         UnorderedSet.add(new(i2.hi + int1.step, int1.step, int1.hi), ints);
    202       end if;
    203 
    204       count_r := div(i2.step, int1.step) - 1;
    205       count_s := if i2.hi < System.intMaxLit() then div(i2.hi - i2.lo, i2.step) else System.intMaxLit();
     229      if inter.hi < int1.hi then
     230        UnorderedSet.add(new(inter.hi + int1.step, int1.step, int1.hi), ints);
     231      end if;
     232
     233      count_r := div(inter.step, int1.step) - 1;
     234      count_s := if inter.hi < System.intMaxLit() then div(inter.hi - inter.lo, inter.step) else System.intMaxLit();
    206235
    207236      if count_r < count_s then
    208         // create an interval for every residue class not equal to i2.lo
     237        // create an interval for every residue class not equal to inter.lo
    209238        if count_s < System.intMaxLit() then
    210239          for i in count_r:-1:1 loop
    211             UnorderedSet.add(new(i2.lo + i * int1.step, i2.step, i2.hi - i2.step + i * int1.step), ints);
     240            UnorderedSet.add(new(inter.lo + i * int1.step, inter.step, inter.hi - inter.step + i * int1.step), ints);
    212241          end for;
    213242        else
    214243          for i in count_r:-1:1 loop
    215             UnorderedSet.add(new(i2.lo + i * int1.step, i2.step, System.intMaxLit()), ints);
     244            UnorderedSet.add(new(inter.lo + i * int1.step, inter.step, System.intMaxLit()), ints);
    216245          end for;
    217246        end if;
     
    219248        // create an interval for every space between removed points
    220249        for i in count_s:-1:1 loop
    221           UnorderedSet.add(new(i2.lo + int1.step + (i - 1) * i2.step, int1.step, i2.lo - int1.step + i * i2.step), ints);
     250          UnorderedSet.add(new(inter.lo + int1.step + (i - 1) * inter.step, int1.step, inter.lo - int1.step + i * inter.step), ints);
    222251        end for;
    223252      end if;
    224253
    225254      // Leftmost interval.
    226       if i2.lo > int1.lo then
    227         UnorderedSet.add(new(int1.lo, int1.step, i2.lo - int1.step), ints);
    228       end if;
     255      if inter.lo > int1.lo then
     256        UnorderedSet.add(new(int1.lo, int1.step, inter.lo - int1.step), ints);
     257      end if;
     258      */
    229259    end if;
    230260  end complement;
     
    276306    end if;
    277307  end affine;
     308
     309  function normalize
     310    input SBInterval int1;
     311    input SBInterval int2;
     312    output SBInterval res;
     313  algorithm
     314    if int1.step == int2.step then
     315      if int1.hi + int1.step == int2.lo or contains(int2.lo, int1) then
     316        res := new(int1.lo, int1.step, int2.hi);
     317      // kabdelhak: should this be int2.step instead of int1.step in elseif?
     318      elseif int2.hi + int1.step == int1.lo or contains(int1.lo, int2) then
     319        res := new(int2.lo, int1.step, int1.hi);
     320      else
     321        res := new(-1, -1, -1);
     322      end if;
     323    end if;
     324  end normalize;
    278325
    279326  function cardinality
  • OMCompiler/Compiler/Util/SBLinearMap.mo

    r3eea6ab r51dd041  
    8383  end copy;
    8484
     85  function replace
     86    input output SBLinearMap map;
     87    input Integer gain;
     88    input Integer offset;
     89    input Integer dim;
     90  algorithm
     91    map.gain[dim]   := gain;
     92    map.offset[dim] := offset;
     93  end replace;
     94
    8595  function ndim
    8696    input SBLinearMap map;
     
    172182      o := arrayGetNoBoundsChecking(map.offset, i);
    173183
    174       if g <> 0 then
     184      if g > intReal(System.intMaxLit()) * 0.99 then
     185        arrayUpdateNoBoundsChecking(gain, i, 0.0);
     186        arrayUpdateNoBoundsChecking(offset, i, -o / g);
     187      elseif g <> 0 then
    175188        arrayUpdateNoBoundsChecking(gain, i, 1.0 / g);
    176189        arrayUpdateNoBoundsChecking(offset, i, -o / g);
    177190      else
    178191        arrayUpdateNoBoundsChecking(gain, i, intReal(System.intMaxLit()));
    179         arrayUpdateNoBoundsChecking(offset, i, intReal(System.intMaxLit()));
     192        arrayUpdateNoBoundsChecking(offset, i, intReal(-System.intMaxLit()));
    180193      end if;
    181194    end for;
  • OMCompiler/Compiler/Util/SBMultiInterval.mo

    rcea85cf r51dd041  
    211211  end crossProd;
    212212
     213  function normalize
     214    input SBMultiInterval mi1;
     215    input SBMultiInterval mi2;
     216    output SBMultiInterval res;
     217  protected
     218    Integer diffCount, dimDiff;
     219    SBInterval i1, i2, norm;
     220  algorithm
     221    if mi1.ndim == mi2.ndim then
     222      diffCount := 0;
     223      dimDiff := 0;
     224      for i in 1:mi1.ndim loop
     225        if not SBInterval.isEqual(mi1.intervals[i], mi2.intervals[i]) then
     226          diffCount := diffCount + 1;
     227          dimDiff := i + 1;
     228          i1 := mi1.intervals[i];
     229          i2 := mi2.intervals[i];
     230        end if;
     231      end for;
     232
     233      if diffCount == 1 then
     234        norm := SBInterval.normalize(i1, i2);
     235        if not SBInterval.isEmpty(norm) then
     236          res := replace(norm, dimDiff, mi2);
     237          return;
     238        end if;
     239      end if;
     240    else
     241      res := MULTI_INTERVAL(listArray({}), 0);
     242    end if;
     243  end normalize;
     244
    213245  function cardinality
    214246    input SBMultiInterval mi;
     
    255287  algorithm
    256288    ints := arrayCopy(mi.intervals);
    257     ints[dim] := i;
     289    if dim > arrayLength(ints) then
     290      ints := Array.expand(dim - arrayLength(ints), ints, i);
     291    else
     292      ints[dim] := i;
     293    end if;
    258294    res := fromArray(ints);
    259295  end replace;
  • OMCompiler/Compiler/Util/SBPWAtomicLinearMap.mo

    r5a43137 r51dd041  
    3737protected
    3838  import Array;
     39  import Error;
    3940  import List;
    4041  import System;
     
    100101    if compatible then
    101102      map := PW_ATOMIC_LINEAR_MAP(SBAtomicSet.copy(dom), SBLinearMap.copy(lmap));
     103    else
     104      Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed the domain "
     105        + SBAtomicSet.toString(dom) + " and the linear map " + SBLinearMap.toString(lmap) + " are incompatible."});
     106      fail();
    102107    end if;
    103108  end new;
  • OMCompiler/Compiler/Util/SBPWLinearMap.mo

    rd14cb0c r51dd041  
    205205    input SBPWLinearMap map1;
    206206    input SBPWLinearMap map2;
    207     output SBPWLinearMap outMap;
    208   protected
    209     array<SBSet> dom1 = map1.dom, dom2 = map2.dom;
    210     Vector<SBSet> ress;
    211     array<SBLinearMap> lmap1 = map1.lmap, lmap2 = map2.lmap;
    212     Vector<SBLinearMap> reslm;
    213     SBSet aux_dom, new_dom, d1, d2;
    214     SBLinearMap l1, l2, new_lm;
    215   algorithm
    216     if SBPWLinearMap.isEmpty(map1) or SBPWLinearMap.isEmpty(map2) then
    217       outMap := SBPWLinearMap.newEmpty();
    218       return;
    219     end if;
    220 
    221     ress := Vector.new<SBSet>();
    222     reslm := Vector.new<SBLinearMap>();
    223 
    224     for i in 1:arrayLength(dom1) loop
    225       d1 := arrayGetNoBoundsChecking(dom1, i);
    226 
    227       for j in 1:arrayLength(dom2) loop
    228         d2 := arrayGetNoBoundsChecking(dom2, j);
    229 
    230         aux_dom := image(map2, d2);
    231         aux_dom := SBSet.intersection(aux_dom, d1);
    232         aux_dom := preImage(map2, aux_dom);
    233         new_dom := SBSet.intersection(aux_dom, d2);
    234 
    235         if not SBSet.isEmpty(new_dom) then
    236           l1 := lmap1[i];
    237           l2 := lmap2[j];
    238           new_lm := SBLinearMap.compose(l1, l2);
    239           Vector.push(ress, new_dom);
    240           Vector.push(reslm, new_lm);
     207    output SBPWLinearMap res;
     208  protected
     209    Vector<SBSet> new_dom, notId_dom;
     210    Vector<SBLinearMap> new_lmap, notId_lmap;
     211    SBPWLinearMap aux1 = normalize(map1);
     212    SBPWLinearMap aux2 = normalize(map2);
     213    SBPWLinearMap notId;
     214    SBSet pre, inter, atomDom, notIdAtomDom, newDom;
     215    SBLinearMap new_map;
     216  algorithm
     217    new_dom   := Vector.new<SBSet>();
     218    new_lmap  := Vector.new<SBLinearMap>();
     219    if isEqual(aux1, aux2) then
     220      notId_dom   := Vector.new<SBSet>();
     221      notId_lmap  := Vector.new<SBLinearMap>();
     222      for i in 1:arrayLength(aux1.dom) loop
     223        if SBLinearMap.isIdentity(aux1.lmap[i]) then
     224          Vector.push(new_dom, aux1.dom[i]);
     225          Vector.push(new_lmap, aux1.lmap[i]);
     226          pre := preImage(aux1, aux1.dom[i]);
     227          pre := SBSet.complement(pre, aux1.dom[i]);
     228
     229          if not SBSet.isEmpty(pre) then
     230            for j in 1:arrayLength(aux1.dom) loop
     231              inter := SBSet.intersection(pre, aux1.dom[j]);
     232              if not SBSet.isEmpty(inter) then
     233                Vector.push(new_dom, inter);
     234                Vector.push(new_lmap, aux1.lmap[j]);
     235              end if;
     236            end for;
     237          end if;
     238        else
     239          for dom in UnorderedSet.toList(SBSet.asets(aux1.dom[i])) loop
     240            notIdAtomDom := SBSet.newEmpty();
     241            if SBLinearMap.isIdentity(aux1.lmap[i]) then
     242              atomDom := SBSet.newEmpty();
     243              SBSet.addAtomicSet(dom, atomDom);
     244              Vector.push(new_dom, atomDom);
     245              Vector.push(new_lmap, aux1.lmap[i]);
     246              pre := preImage(aux1, atomDom);
     247
     248              if not SBSet.isEmpty(pre) then
     249                for j in 1:arrayLength(aux1.dom) loop
     250                  inter := SBSet.intersection(pre, aux1.dom[j]);
     251                  if not SBSet.isEmpty(inter) then
     252                    Vector.push(new_dom, inter);
     253                    Vector.push(new_lmap, aux1.lmap[j]);
     254                  end if;
     255                end for;
     256              end if;
     257            else
     258              notIdAtomDom := SBSet.addAtomicSet(dom, notIdAtomDom);
     259            end if;
     260          end for;
     261
     262          if not SBSet.isEmpty(notIdAtomDom) then
     263            Vector.push(notId_dom, notIdAtomDom);
     264            Vector.push(notId_lmap, aux1.lmap[i]);
     265          end if;
    241266        end if;
    242267      end for;
    243     end for;
    244 
    245     outMap := new(Vector.toArray(ress), Vector.toArray(reslm));
     268
     269      notId := new(Vector.toArray(notId_dom), Vector.toArray(notId_lmap));
     270
     271      for i in 1:arrayLength(notId.dom) loop
     272        // kabdelhak: aux1 is map1 in only this first preImage call in the original
     273        //   and i cannot see how it should be correct.
     274        pre := preImage(map1, notId.dom[i]);
     275        if not SBSet.isEmpty(pre) then
     276          for j in 1:arrayLength(aux1.dom) loop
     277            inter := SBSet.intersection(pre, aux1.dom[j]);
     278            if not SBSet.isEmpty(inter) then
     279              new_map := SBLinearMap.compose(notId.lmap[i], aux1.lmap[j]);
     280              Vector.push(new_dom, inter);
     281              Vector.push(new_lmap, new_map);
     282            end if;
     283          end for;
     284        end if;
     285      end for;
     286    else
     287      /* ... */
     288      for i in 1:arrayLength(aux1.dom) loop
     289        for j in 1:arrayLength(aux2.dom) loop
     290          newDom := image(aux2, aux2.dom[j]);
     291          newDom := SBSet.intersection(newDom, aux1.dom[i]);
     292          newDom := preImage(aux2, newDom);
     293          newDom := SBSet.intersection(newDom, aux2.dom[j]);
     294          if not SBSet.isEmpty(newDom) then
     295            new_map   := SBLinearMap.compose(aux1.lmap[i], aux2.lmap[j]);
     296            Vector.push(new_dom, newDom);
     297            Vector.push(new_lmap, new_map);
     298          end if;
     299        end for;
     300      end for;
     301    end if;
     302
     303    res := new(Vector.toArray(new_dom), Vector.toArray(new_lmap));
    246304  end compPW;
     305
     306  function normalize
     307    input SBPWLinearMap map;
     308    output SBPWLinearMap res;
     309  protected
     310    Vector<SBSet> new_dom = Vector.new<SBSet>();
     311    Vector<SBLinearMap> new_lmap = Vector.new<SBLinearMap>();
     312    Integer length = arrayLength(map.dom);
     313    SBSet newDom, noRepeat = SBSet.newEmpty();
     314  algorithm
     315    for i in 1:length loop
     316      newDom := map.dom[i]  ;
     317      if SBSet.isEmpty(SBSet.intersection(map.dom[i], noRepeat)) then
     318        for j in (i+1):length loop
     319          if SBLinearMap.isEqual(map.lmap[j], map.lmap[i]) then
     320            newDom := SBSet.union(newDom, map.dom[j]);
     321          end if;
     322        end for;
     323      end if;
     324
     325      if not SBSet.isEmpty(newDom) then
     326        noRepeat := SBSet.union(noRepeat, newDom);
     327        Vector.push(new_dom, SBSet.normalize(newDom));
     328        Vector.push(new_lmap, map.lmap[i]);
     329      end if;
     330    end for;
     331
     332    res := new(Vector.toArray(new_dom), Vector.toArray(new_lmap));
     333  end normalize;
    247334
    248335  function minInvCompact
  • OMCompiler/Compiler/Util/SBSet.mo

    rcea85cf r51dd041  
    3636protected
    3737  import Array;
     38  import Error;
    3839  import List;
    3940  import Vector;
     
    130131    elseif SBAtomicSet.ndim(aset) == set.ndim then
    131132      UnorderedSet.add(aset, set.asets);
    132     // else
    133     //   Error: Atomic sets should have the same dimension.
     133    else
     134      Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because atomic sets should have the same dimension:\nThe atomic set "
     135        + SBAtomicSet.toString(aset) + " could not be added to " + SBSet.toString(set)});
     136      fail();
    134137    end if;
    135138  end addAtomicSet;
     
    176179  protected
    177180    UnorderedSet<SBAtomicSet> int_res, aux, comp_res;
    178     SBSet new_sets;
     181    SBSet new_sets, test;
    179182  algorithm
    180183    outSet := newEmpty();
    181     SET(asets = int_res) := intersection(set1, set2);
    182 
     184    test := intersection(set1, set2);
     185
     186    SET(asets = int_res) := test;
    183187    if not UnorderedSet.isEmpty(int_res) then
    184188      for as1 in UnorderedSet.toArray(set1.asets) loop
     
    218222    end if;
    219223  end union;
     224
     225  function normalize
     226    input SBSet set;
     227    output SBSet res = copy(set);
     228  protected
     229    Boolean first, stop = false;
     230    SBAtomicSet norm;
     231    list<SBAtomicSet> asets = UnorderedSet.toList(res.asets);
     232    UnorderedSet<SBAtomicSet> toDelete, toInsert;
     233  algorithm
     234    while not stop loop
     235      first := true;
     236      toDelete := UnorderedSet.new(SBAtomicSet.hash, SBAtomicSet.isEqual);
     237      toInsert := UnorderedSet.new(SBAtomicSet.hash, SBAtomicSet.isEqual);
     238      for as1 in asets loop
     239        for as2 in asets loop
     240          if not SBAtomicSet.isEqual(as1, as2) then
     241            norm := SBAtomicSet.normalize(as1, as2);
     242            if not first and SBAtomicSet.isEmpty(norm) then
     243              first := false;
     244              UnorderedSet.add(as1, toDelete);
     245              UnorderedSet.add(as2, toDelete);
     246              UnorderedSet.add(norm, toInsert);
     247            end if;
     248          end if;
     249        end for;
     250      end for;
     251      stop := UnorderedSet.isEmpty(toDelete);
     252    end while;
     253
     254    for del in UnorderedSet.toList(toDelete) loop
     255      UnorderedSet.remove(del, res.asets);
     256    end for;
     257    for ins in UnorderedSet.toList(toInsert) loop
     258      UnorderedSet.add(ins, res.asets);
     259    end for;
     260  end normalize;
    220261
    221262  function card
Note: See TracChangeset for help on using the changeset viewer.