Annotation of OpenXM_contrib/PHC/Ada/Root_Counts/Symmetry/symmetric_set_structure.adb, Revision 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>