[BACK]Return to symmetric_set_structure.adb CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / PHC / Ada / Root_Counts / Symmetry

Annotation of OpenXM_contrib/PHC/Ada/Root_Counts/Symmetry/symmetric_set_structure.adb, Revision 1.1.1.1

1.1       maekawa     1: with unchecked_deallocation;
                      2: with text_io,integer_io;                 use text_io,integer_io;
                      3: with Generic_Lists;
                      4: with Standard_Natural_Vectors;           use Standard_Natural_Vectors;
                      5: with Standard_Natural_Vectors_io;        use Standard_Natural_Vectors_io;
                      6: with Set_Structure;                      use Set_Structure;
                      7: with Permutations,Permute_Operations;    use Permutations,Permute_Operations;
                      8: with Templates;                          use Templates;
                      9:
                     10: package body Symmetric_Set_Structure is
                     11:
                     12: -- DATASTRUCTURES :
                     13:
                     14:   type set is array (natural range <>) of boolean;
                     15:   type boolean_array is array (natural range <>) of boolean;
                     16:   type link_to_boolean_array is access boolean_array;
                     17:   procedure free is new unchecked_deallocation(boolean_array,
                     18:                                                link_to_boolean_array);
                     19:   type boolean_matrix is array (natural range <>) of link_to_boolean_array;
                     20:   type link_to_boolean_matrix is access boolean_matrix;
                     21:   procedure free is new unchecked_deallocation(boolean_matrix,
                     22:                                                link_to_boolean_matrix);
                     23:   type set_coord is record
                     24:     k,l : natural;
                     25:   end record;
                     26:   type Dependency_Structure is array (natural range <>) of set_coord;
                     27:   type Link_to_Dependency_Structure is access Dependency_Structure;
                     28:   procedure free is new unchecked_deallocation(Dependency_Structure,
                     29:                                               Link_to_Dependency_Structure);
                     30:
                     31:   package Lists_of_Dependency_Structures
                     32:     is new Generic_Lists (Link_to_Dependency_Structure);
                     33:   type Covering is new Lists_of_Dependency_Structures.List;
                     34:
                     35: -- INTERNAL DATA :
                     36:
                     37:   cov : Covering;  -- covering of the set structure
                     38:   lbm : link_to_boolean_matrix;
                     39:     -- auxiliary data structure for bookeeping during the construction
                     40:     -- of the covering,
                     41:     -- to remember which sets have already been treated.
                     42:
                     43: -- AUXILIARY ROUTINES FOR CONSTRUCTING THE COVERING :
                     44:
                     45:   function Give_Set ( n,i,j : natural ) return set is
                     46:
                     47:   -- DESCRIPTION :
                     48:   --   Returns the (i,j)-th set out of the set structure.
                     49:
                     50:     s : set(1..n);
                     51:
                     52:   begin
                     53:     for k in 1..n loop
                     54:       s(k) := Is_In(i,j,k);
                     55:     end loop;
                     56:     return s;
                     57:   end Give_Set;
                     58:
                     59:   function Equal ( s1,s2 : set ) return boolean is
                     60:
                     61:   -- DESCRIPTION :
                     62:   --   Returns true if both sets are equal.
                     63:
                     64:   begin
                     65:     for i in s1'range loop
                     66:       if s1(i) /= s2(i)
                     67:        then return false;
                     68:       end if;
                     69:     end loop;
                     70:     return true;
                     71:   end Equal;
                     72:
                     73:   function Find ( i,n : natural; s : set ) return natural is
                     74:
                     75:   -- DESCRIPTION :
                     76:   --   Returns the first occurence of the set s in the i-th row
                     77:   --   of the set structure;
                     78:   --   returns zero if the set does not occur in the i-th row.
                     79:
                     80:   begin
                     81:     for j in 1..Number_Of_Sets(i) loop
                     82:       if not lbm(i)(j) and then Equal(s,Give_Set(n,i,j))
                     83:        then return j;
                     84:       end if;
                     85:     end loop;
                     86:     return 0;
                     87:   end Find;
                     88:
                     89:   function Apply ( p : Permutation; s : set ) return set is
                     90:
                     91:   -- DESCRIPTION :
                     92:   --   Returns the result after application of p on the set s.
                     93:
                     94:     r : set(s'range);
                     95:   begin
                     96:     for i in p'range loop
                     97:       r(i) := s(p(i));
                     98:     end loop;
                     99:     return r;
                    100:   end Apply;
                    101:
                    102:   procedure Init_Covering ( n : in natural ) is
                    103:
                    104:   -- DESCRIPTION :
                    105:   --   Initialization of lbm.
                    106:
                    107:   begin
                    108:     lbm := new boolean_matrix(1..n);
                    109:     for i in 1..n loop
                    110:       lbm(i) := new boolean_array'(1..Number_of_Sets(i) => false);
                    111:     end loop;
                    112:   end Init_Covering;
                    113:
                    114:   procedure Update ( dps : Dependency_Structure ) is
                    115:
                    116:   -- DESCRIPTION :
                    117:   --   All pairs in dps are marked in lbm.
                    118:
                    119:   begin
                    120:     for i in dps'range loop
                    121:       lbm(dps(i).k)(dps(i).l) := true;
                    122:     end loop;
                    123:   end Update;
                    124:
                    125:   procedure Search ( n : in natural; i,j : out natural;
                    126:                      empty : out boolean ) is
                    127:
                    128:   -- DESCRIPTION :
                    129:   --   Searches in lbm the first (i,j)-th free set;
                    130:   --   returns empty if all sets have already been used.
                    131:
                    132:   begin
                    133:     for k in 1..n loop
                    134:       for l in lbm(k)'range loop
                    135:         if not lbm(k)(l)
                    136:          then i := k; j := l; empty := false;
                    137:               return;
                    138:         end if;
                    139:       end loop;
                    140:     end loop;
                    141:     empty := true;
                    142:   end Search;
                    143:
                    144: -- CONSTRUCTOR FOR DEPENDENCY STRUCTURE AND COVERING :
                    145:
                    146:   procedure Construct_Dependency_Structure
                    147:                 ( n,m : in natural; v,w : in List_Of_Permutations;
                    148:                  i,j : in natural; dps : in out Dependency_Structure;
                    149:                  fail : out boolean ) is
                    150:
                    151:   -- DESCRIPTION :
                    152:   --   A dependency structure will be constructed.
                    153:
                    154:   -- ON ENTRY :
                    155:   --   n         the dimension;
                    156:   --   m         number of elements in dps,v and w;
                    157:   --   v,w       matrix representations;
                    158:   --   i,j       coordinates of a set in the dependency structure.
                    159:
                    160:   -- ON RETURN :
                    161:   --   dps       the dependency structure;
                    162:   --   fail      is true if the set structure is not symmetric.
                    163:
                    164:     s : set(1..n) := Give_Set(n,i,j);
                    165:     lv,lw : List_Of_Permutations;
                    166:     pv,pw : Permutation(1..n);
                    167:     ps : set(1..n);
                    168:     res : natural;
                    169:
                    170:   begin
                    171:     lv := v;  lw := w;
                    172:     for x in 1..m loop
                    173:       pw := Permutation(Head_Of(lw).all);
                    174:       dps(x).k := pw(i);
                    175:       pv := Permutation(Head_Of(lv).all);
                    176:       ps := Apply(pv,s);
                    177:       res := Find(dps(x).k,n,ps);
                    178:       exit when (res = 0);
                    179:       dps(x).l := res;
                    180:       lv := Tail_Of(lv);
                    181:       lw := Tail_Of(lw);
                    182:     end loop;
                    183:     fail := (res = 0);
                    184:   end Construct_Dependency_Structure;
                    185:
                    186:   procedure Construct_Covering
                    187:                 ( n,m : in natural; v,w : in List_Of_Permutations;
                    188:                   fail : out boolean ) is
                    189:
                    190:   -- DESCRIPTION :
                    191:   --   A covering of the set structure will be constructed.
                    192:
                    193:   -- EFFECT :
                    194:   --   Initially, all entries in lbm are false;
                    195:   --   at the end, all entries in lbm are true (if not fail).
                    196:
                    197:     dps : Dependency_Structure(1..m);
                    198:     ldps : Link_to_Dependency_Structure;
                    199:     empty,fl : boolean;
                    200:     i,j : natural;
                    201:
                    202:   begin
                    203:     Init_Covering(n);
                    204:     Search(n,i,j,empty);
                    205:     while not empty loop
                    206:       Construct_Dependency_Structure(n,m,v,w,i,j,dps,fl);
                    207:       exit when fl;
                    208:       Update(dps);
                    209:       ldps := new Dependency_Structure(1..m);
                    210:       ldps.all := dps;
                    211:       Construct(ldps,cov);
                    212:       Search(n,i,j,empty);
                    213:     end loop;
                    214:     fail := fl;
                    215:   end Construct_Covering;
                    216:
                    217: -- OUTPUT PROCEDURES FOR COVERING :
                    218:
                    219:   procedure Write_Set ( n,i,j : natural ) is
                    220:
                    221:   -- DESCRIPTION :
                    222:   --   Writes the (i,j)-th set on the standard output.
                    223:
                    224:   begin
                    225:     put('{');
                    226:     for k in 1..n loop
                    227:       if Is_In(i,j,k)
                    228:        then put(' '); put('x'); put(k,1);
                    229:       end if;
                    230:     end loop;
                    231:     put(" }");
                    232:   end Write_Set;
                    233:
                    234:   procedure Write_Coord ( k,l : in natural ) is
                    235:   begin
                    236:     put('['); put(k,1); put(' '); put(l,1); put(']');
                    237:   end Write_Coord;
                    238:
                    239:   procedure Write_Covering is
                    240:     tmp : Covering := cov;
                    241:     ldps : Link_to_Dependency_Structure;
                    242:   begin
                    243:     put_line("The covering :");
                    244:     while not Is_Null(tmp) loop
                    245:       ldps := Head_Of(tmp);
                    246:       declare
                    247:        nb : natural := 0;
                    248:       begin
                    249:         for i in ldps'range loop
                    250:          Write_Coord(ldps(i).k,ldps(i).l);
                    251:          nb := nb+1;
                    252:          if nb > 7
                    253:           then new_line;
                    254:                nb := 0;
                    255:           end if;
                    256:         end loop;
                    257:         new_line;
                    258:       end;
                    259:       tmp := Tail_Of(tmp);
                    260:     end loop;
                    261:   end Write_Covering;
                    262:
                    263:   procedure Write_Coord ( file : in file_type; k,l : in natural ) is
                    264:   begin
                    265:     put(file,'['); put(file,k,1); put(file,' '); put(file,l,1); put(file,']');
                    266:   end Write_Coord;
                    267:
                    268:   procedure Write_Covering ( file : in file_type ) is
                    269:     tmp : Covering := cov;
                    270:     ldps : Link_to_Dependency_Structure;
                    271:   begin
                    272:     put_line(file,"The covering :");
                    273:     while not Is_Null(tmp) loop
                    274:       ldps := Head_Of(tmp);
                    275:       declare
                    276:         nb : natural := 0;
                    277:       begin
                    278:         for i in ldps'range loop
                    279:           Write_Coord(file,ldps(i).k,ldps(i).l);
                    280:           nb := nb+1;
                    281:           if nb > 7
                    282:            then new_line(file);
                    283:                 nb := 0;
                    284:           end if;
                    285:         end loop;
                    286:         new_line(file);
                    287:       end;
                    288:       tmp := Tail_Of(tmp);
                    289:     end loop;
                    290:   end Write_Covering;
                    291:
                    292: -- CONSTRUCTION OF TEMPLATES :
                    293:
                    294:   procedure Init_Template ( n : in natural ) is
                    295:
                    296:   -- DESCRIPTION :
                    297:   --   Initialization of the template.
                    298:
                    299:     h : Standard_Natural_Vectors.Vector(0..n) := (0..n => 0);
                    300:
                    301:   begin
                    302:     Templates.Create(n);
                    303:     for i in 1..n loop
                    304:       for j in 1..Number_Of_Sets(i) loop
                    305:         Templates.Add_Hyperplane(i,h);
                    306:       end loop;
                    307:     end loop;
                    308:   end Init_Template;
                    309:
                    310:   procedure First_Equivariant_Template
                    311:                 ( n : in natural; cnt : in out natural ) is
                    312:
                    313:   -- DESCRIPTION :
                    314:   --   Constructs the first equation of the template, for an equivariant
                    315:   --   linear product system system
                    316:
                    317:   -- ON ENTRY :
                    318:   --   n          the dimension;
                    319:   --   cnt        counts the number of free coefficients.
                    320:
                    321:     h : Standard_Natural_Vectors.Vector(0..n);
                    322:
                    323:   begin
                    324:     for j in 1..Templates.Number_of_Hyperplanes(1) loop
                    325:       Templates.Get_Hyperplane(1,j,h);
                    326:       cnt := cnt + 1; h(0) := cnt;
                    327:       for k in 1..n loop
                    328:         if Set_Structure.Is_In(1,j,k)
                    329:          then if cnt = h(0)
                    330:                then cnt := cnt + 1;
                    331:               end if;
                    332:               h(k) := cnt;
                    333:         end if;
                    334:       end loop;
                    335:       Templates.Change_Hyperplane(1,j,h);
                    336:     end loop;
                    337:   end First_Equivariant_Template;
                    338:
                    339:   function Action ( i,n : natural ; g : List_of_Permutations )
                    340:                   return Permutation is
                    341:
                    342:   -- DESCRIPTION :
                    343:   --   Returns the group action from the list g that permutes the first
                    344:   --   array of sets into the ith one.
                    345:
                    346:     p : Permutation(1..n);
                    347:     first,second : Standard_Natural_Vectors.Vector(1..n);
                    348:     tmp : List_of_Permutations := g;
                    349:
                    350:   begin
                    351:     for k in 1..n loop
                    352:       if Set_Structure.Is_In(1,1,k)
                    353:        then first(k) := 1;
                    354:        else first(k) := 0;
                    355:       end if;
                    356:       if Set_Structure.Is_In(i,1,k)
                    357:        then second(k) := 1;
                    358:        else second(k) := 0;
                    359:       end if;
                    360:     end loop;
                    361:     while not Is_Null(tmp) loop
                    362:       p := Permutation(Head_Of(tmp).all);
                    363:       if second = p*first
                    364:        then return p;
                    365:       end if;
                    366:       tmp := Tail_Of(tmp);
                    367:     end loop;
                    368:     p := (p'range => 0);
                    369:     return p;
                    370:   end Action;
                    371:
                    372:   procedure Propagate_Equivariant_Template
                    373:                    ( n : in natural; g : in List_of_Permutations;
                    374:                      fail : out boolean ) is
                    375:
                    376:   -- DESCRIPTION :
                    377:   --   Given a template whose first equation is already constructed,
                    378:   --   the rest of the template will be constructed, with the aid of the
                    379:   --   list of generating permutations.
                    380:
                    381:     h : Standard_Natural_Vectors.Vector(0..n);
                    382:     p : Permutation(1..n);
                    383:
                    384:   begin
                    385:     for i in 2..n loop
                    386:       p := Action(i,n,g);
                    387:       if p = (p'range => 0)
                    388:        then fail := true; return;
                    389:       end if;
                    390:       for j in 1..Templates.Number_of_Hyperplanes(i) loop
                    391:         Templates.Get_Hyperplane(1,j,h);
                    392:         h(1..n) := p*h(1..n);
                    393:         Templates.Change_Hyperplane(i,j,h);
                    394:       end loop;
                    395:     end loop;
                    396:     fail := false;
                    397:   end Propagate_Equivariant_Template;
                    398:
                    399:   procedure Construct_Part_of_Template
                    400:                 ( n,m : in natural; v : in List_Of_Permutations;
                    401:                   dps : in Dependency_Structure; invpv1 : in Permutation;
                    402:                   cnt : in out natural ) is
                    403:
                    404:   -- DESCRIPTION :
                    405:   --   This procedure constructs the coefficients of the hyperplanes
                    406:   --   associated with the sets in the dependency structure dps.
                    407:   --   cnt counts the number of free coefficients.
                    408:
                    409:     lv : List_Of_Permutations;
                    410:     pv : Permutation(1..n);
                    411:     h : Standard_Natural_Vectors.Vector(0..n);
                    412:     indi : natural;
                    413:
                    414:   begin
                    415:    -- GENERATE CONSTANT COEFFICIENT :
                    416:     cnt := cnt+1;
                    417:     for j in 1..m loop
                    418:       Templates.Get_Hyperplane(dps(j).k,dps(j).l,h);
                    419:       h(0) := cnt;
                    420:       Templates.Change_Hyperplane(dps(j).k,dps(j).l,h);
                    421:     end loop;
                    422:    -- GENERATE THE OTHER COEFFICIENTS :
                    423:     for i in 1..n loop
                    424:      -- GENERATE :
                    425:       if Is_In(dps(1).k,dps(1).l,i)
                    426:        then Templates.Get_Hyperplane(dps(1).k,dps(1).l,h);
                    427:             if h(i) = 0
                    428:              then cnt := cnt + 1;
                    429:                 -- PROPAGATE :
                    430:                 --put("PROPAGATING "); put(i,1);
                    431:                 --put_line("-th coefficient :");
                    432:                   lv := v;
                    433:                   for j in 1..m loop
                    434:                     pv := Permutation(Head_Of(lv).all);
                    435:                    indi := 0;
                    436:                    for l in 1..n loop
                    437:                      if pv(l) = invpv1(i)
                    438:                       then indi := l;
                    439:                            exit;
                    440:                       end if;
                    441:                     end loop;
                    442:                    --Write_Coord(dps(j).k,dps(j).l); put(" : ");
                    443:                    --Write_Set(n,dps(j).k,dps(j).l);
                    444:                    --put(" indi : "); put(indi,1); new_line;
                    445:                     Templates.Get_Hyperplane(dps(j).k,dps(j).l,h);
                    446:                     h(indi) := cnt;
                    447:                     Templates.Change_Hyperplane(dps(j).k,dps(j).l,h);
                    448:                     lv := Tail_Of(lv);
                    449:                   end loop;
                    450:                   --put_line("RANDOM PRODUCT SYSTEM AFTER PROPAGATION :");
                    451:                   --Write_RPS(n,2,4,3);
                    452:                   --for l in 1..75 loop put("+"); end loop; new_line;
                    453:             end if;
                    454:       end if;
                    455:     end loop;
                    456:   end Construct_Part_of_Template;
                    457:
                    458:   procedure Construct_Template
                    459:                ( n,m : in natural; v : in List_Of_Permutations;
                    460:                  nbfree : out natural ) is
                    461:
                    462:   -- DESCRIPTION :
                    463:   --   Given a covering of the set structure,
                    464:   --   the data of the package Random_Product_System will be filled.
                    465:
                    466:   -- ON ENTRY :
                    467:   --   n          the dimension of the vectors
                    468:   --   m          the number of entries in v
                    469:   --   v          matrix representations of the group
                    470:
                    471:   -- ON RETURN :
                    472:   --   nbfree     the number of free coefficients
                    473:
                    474:     tmp : Covering := cov;
                    475:     ldps : Link_to_Dependency_Structure;
                    476:     invpv1 : Permutation(1..n);
                    477:     cnt : natural;
                    478:
                    479:   begin
                    480:     Init_Template(n);
                    481:     cnt := 0;
                    482:     -- CONSTRUCT THE BASE SET OF dps :
                    483:     invpv1 := inv(Permutation(Head_Of(v).all));
                    484:       -- then for each pv in v: permutation of the base set
                    485:       -- is defined as pv*invpv1.
                    486:      --put("invpv1 : "); Put(invpv1); new_line;
                    487:     while not Is_Null(tmp) loop
                    488:       ldps := Head_Of(tmp);
                    489:       Construct_Part_of_Template(n,m,v,ldps.all,invpv1,cnt);
                    490:       tmp := Tail_Of(tmp);
                    491:     end loop;
                    492:     nbfree := cnt;
                    493:   end Construct_Template;
                    494:
                    495:   procedure Construct_Equivariant_Template
                    496:                  ( n : in natural; g : in List_of_Permutations;
                    497:                    cntfree : in out natural; fail : out boolean ) is
                    498:
                    499:   -- DESCRIPTION :
                    500:   --   Constructs a template for an equivariant system.  The list g contains
                    501:   --   the generating elements of the group.  The variable cntfree counts the
                    502:   --   number of free coefficients.
                    503:
                    504:   begin
                    505:     Init_Template(n);
                    506:     First_Equivariant_Template(n,cntfree);
                    507:     Propagate_Equivariant_Template(n,g,fail);
                    508:   end Construct_Equivariant_Template;
                    509:
                    510:   procedure Write_Templates ( n : in natural ) is
                    511:   begin
                    512:     Write_Templates(Standard_Output,n);
                    513:   end Write_Templates;
                    514:
                    515:   procedure Write_Templates ( file : in file_type; n : in natural ) is
                    516:
                    517:     h : Standard_Natural_Vectors.Vector(0..n);
                    518:
                    519:   begin
                    520:     put_line(file,"The templates :");
                    521:     for i in 1..n loop
                    522:       for j in 1..Number_of_Hyperplanes(i) loop
                    523:         put(file,"("); put(file,i,1); put(file,","); put(file,j,1);
                    524:         put(file,") : "); Get_Hyperplane(i,j,h); put(file,h); new_line(file);
                    525:       end loop;
                    526:     end loop;
                    527:   end Write_Templates;
                    528:
                    529: -- CONSTRUCTION OF START SYSTEMS :
                    530:
                    531:   procedure Equivariant_Start_System
                    532:                   ( n : in natural; g : in List_of_Permutations;
                    533:                     fail : out boolean ) is
                    534:
                    535:     nbfree : natural := 0;
                    536:     fl : boolean := false;
                    537:
                    538:   begin
                    539:     Construct_Equivariant_Template(n,g,nbfree,fl);
                    540:     if not fl
                    541:      then Templates.Polynomial_System(n,nbfree);
                    542:     end if;
                    543:     fail := fl;
                    544:   end Equivariant_Start_System;
                    545:
                    546:   procedure Symmetric_Start_System
                    547:                ( n,bb : in natural; lp : in List;
                    548:                  v,w : in List_Of_Permutations;
                    549:                  notsymmetric,degenerate : out boolean ) is
                    550:
                    551:     m : natural := Number(v);
                    552:     fl : boolean;
                    553:     nbfree : natural;
                    554:
                    555:   begin
                    556:     Construct_Covering(n,m,v,w,fl);
                    557:    -- Write_Covering;
                    558:     for i in lbm'range loop
                    559:       free(lbm(i));
                    560:     end loop;
                    561:     free(lbm);
                    562:     if fl
                    563:      then notsymmetric := true;
                    564:          -- put_line("The set structure is not (G,V,W)-symmetric.");
                    565:      else notsymmetric := false;
                    566:           -- put_line("The set structure is (G,V,W)-symmetric.");
                    567:          -- Templates.Create(n);
                    568:            Construct_Template(n,m,v,nbfree);
                    569:           -- Write_Templates(n);
                    570:           -- vb := Templates.Verify(n,lp);
                    571:           -- put("The bound of Templates.Verify : "); put(vb,1); new_line;
                    572:          -- if bb /= vb
                    573:          --  then degenerate := true;
                    574:           --       put_line("The set structure is degenerate.");
                    575:          --  else
                    576:                  degenerate := false;
                    577:           --       put_line("The set structure is not degenerate.");
                    578:                 Templates.Polynomial_System(n,nbfree);
                    579:           -- end if;
                    580:     end if;
                    581:   end Symmetric_Start_System;
                    582:
                    583: -- DESTRUCTOR :
                    584:
                    585:   procedure Clear is
                    586:
                    587:     use Lists_of_Dependency_Structures;
                    588:     tmp : Covering := cov;
                    589:     elem : Link_to_Dependency_Structure;
                    590:
                    591:   begin
                    592:     while not Is_Null(tmp) loop
                    593:       elem := Head_Of(tmp);
                    594:       free(elem);
                    595:       tmp := Tail_Of(tmp);
                    596:     end loop;
                    597:     Clear(cov);
                    598:     Templates.Clear;
                    599:   end Clear;
                    600:
                    601: end Symmetric_Set_Structure;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>