
#      --------oOo--------
#         perm package 
#      --------oOo--------

#        Author: Yves Chiricota  May 1993.
#        email: chiricot@geocub.greco-prog.fr
#        LaBRI,
#        Universite Bordeaux I,
#        351, cours de la Liberation,
#        33405, Talence, Cedex,
#        FRANCE.


# This file contains the definition for the procedure of
# the "perm" package. Moreover, it create the table that 
# contain the "readlib" call to ".m" files (one file for 
# each  procedure).



# Initialisation procedure. The initialisation consist to
# read representative of subgroup conjugacy class of S7.
# This is a table generated by gentabsg and called "tabsg".
# It try to read that table in the library. 
`perm/init` := proc()
   local rd;
   # On definit rd pour que le read soit "trappable"...
   rd:=proc() readlib(tabsg) end:
   if traperror(rd()) = lasterror 
	then printf(`%s`,`* The table "tabsg" is not defined *\n `);

	else printf(`%s`,`* The table "tabsg" is loaded  *\n `);
	fi
end:

# ----------- beginning of proc definitions --------------------


# All permutations are given as word on {1,2,...,n}.

# Inverse of p.
`perm/inv` := proc(p)
   local i,q;
   for i from 1 to nops(p) do	
	q[p[i]]:=i; od;
   [seq(q[i],i=1..nops(p))];
end:

# This procedure check whether p < q in lexicographic order on word .
`perm/minlex` := proc(p,q)
   local i,egaux;
   egaux := true;
   i:=1;
   while (i<=nops(p) and egaux) do 
      if p[i]=q[i] 
         then i:=i+1 
         else egaux := false 
         fi
      od;
   if egaux=true 
      then RETURN(false)
      elif p[i]>q[i]
         then RETURN(false)
         else RETURN(true)
      fi;
end:

# Product of p and q.
`perm/prod` := proc(p,q) local i;
	[seq(p[i],i=q)];
end:

# Sign of p.
`perm/sgn` := proc(p)
   local cyc;
   cyc:=perm[decomp](p);
   RETURN(convert(map(proc(c) (-1)^(nops(c)-1) end,cyc),`*`));
end:


# Conjugate p by g.
`perm/conj` := proc(p,g)
   perm[prod](g,perm[prod](p,perm[inv](g)))
end:


# This procedure returns the successor of p with respect to
# lexicographic order.
`perm/nextperm` := proc(p)
    local pos,n,k,i,pastrouve,U,V;
    n:=nops(p);
    pos:=n; pastrouve:=true;
    while (pastrouve and pos>1) do
        if p[pos]>p[pos-1]
             then pastrouve:=false 
             else pos:=pos-1 fi;
        od;
    if pos=1 then RETURN(perm[Id](n)) fi;
    k:=min(op(map(proc(a,b) 
                     if a>b then a fi end,
                  {p[pos..n]},p[pos-1]))); 
    V:= {p[pos..n]} minus {k};
    RETURN([p[1..pos-2],k,op(sort([p[pos-1],op(V)]))])
end:

# Identity permutation on n points.
`perm/Id` := proc(n)
   [$1..n]
end:

# Cyclic group generated by p.
`perm/grcyc` := proc(p)
   local H,q,Id0;
   Id0:=perm[Id](nops(p));
   if p=Id0    
     then RETURN({p})
     else
        q:=p; H:={p};
        while q<>Id0 do
           q:=perm[prod](q,p);  H:=H union {q}  od;
        RETURN(H)
        fi
end:

# Dihedral group of order n.
`perm/dihedral`:=proc(n) 
   local Cn,i; option remember;
   Cn:=perm[grcyc]([$2..n,1]);
 RETURN(Cn union map(proc(p,q) perm[prod](q,p) end,Cn,[1,seq(n-i,i=0..n-2)]));
end:

# Give the cycle that contain i in p.
`perm/cyc` := proc(i,p)
		local k,cycle;
		cycle:=[i];
		k:=p[i];
		while (i<>k) do cycle:=[op(cycle),k];
																		k:=p[k];
															od;
  RETURN(cycle);
end:

# Return p in disjoints cycle form.
`perm/decomp` := proc(mot)
  if type(mot,table)
    then
       RETURN(map('perm[decomp]',mot));
    fi;
  if type(mot,{set,listlist})
    then map(proc(m) [`perm/decomp/decomp_1`(m,{op(m)})] end,mot)
    else	[`perm/decomp/decomp_1`(mot,{op(mot)})]
    fi;
end:
`perm/decomp/decomp_1` := proc(mot,restant)
   local c;
   if restant<>{} then
	c:=perm[cyc](min(op(restant)),mot);
     `perm/decomp/decomp_1`(mot,restant minus {op(c)}),c
     fi;
end:

# Cyclic type of q.					
`perm/ctype` := proc(q)
			local i,t,lo,M,p;
   p:=perm[decomp](q);
			if nops(p)>0 then
      M:=max(op(map('nops',p)));
						for i from 1 to M do t[i]:=0; od;
						for i from 1 to nops(p) do	lo:=nops(p[i]);	t[lo]:=t[lo]+1;	od;
		 		 RETURN(convert(t,list));
						fi;
end:

# Inject p in Sn (where p is a permutation in Sk with k<=n).
`perm/complete` := proc(p,n)
   [op(p),$nops(p)+1..n]
end:

# Subgroup generated by X.
`perm/gensg` := proc(X,n)
   local Ident,pile,H,sigma,gamma,i,Xn,t;
   Ident:=perm[Id](n);
   Xn:=map(proc(p,n) perm[complete](p,n) end,X,n);
   H:={Ident,op(Xn)};
   pile:=Xn;
   while pile<>[] do
      sigma:=op(1,pile);
      pile:=subsop(1=NULL,pile);
      for i from 1 to nops(Xn) do
         gamma:=[seq(sigma[t],t=op(i,Xn)),$nops(sigma)+1..n];
         if not member(gamma,H)
            then
                pile:=[gamma,op(pile)];
               H:=H union {gamma};
            fi;
         od;
      od;
   RETURN(H);
end:
`perm/gensg` := proc(X,n)
   local Ident,pile,H,sigma,gamma,i,Xn,t,temp;
   Ident:=perm[Id](n);
   Xn:=map(proc(p,n) perm[complete](p,n) end,X,n);
   H:={Ident,op(Xn)};
   pile:=Xn;
   while pile<>[] do
      sigma:=pile[1];
      # pile:=[$('pile[j]','j'=2..nops(pile))];
      # pile:=subsop(1=NULL,pile);
      temp:=NULL;
      for i in Xn do
         # gamma:=perm[complete](perm[prod](sigma,op(i,Xn)),n);
         gamma:=[seq(sigma[t],t=i),$nops(sigma)+1..n];
         if not member(gamma,H)
            then
               temp:=gamma,temp;
               H:=H union {gamma};
            fi;
      od;
      pile:=subsop(1=temp,pile);
   od;
   RETURN(H);
end:


# Lateral class of g with respect to K.
`perm/cllat` := proc(g,K)
   convert(map(proc (x,g) perm[prod](g,x) end,K,g),set);
end:

# Minimum permutation (in the lex. order) of the list lPerm.
`perm/pmin` := proc(lPerm)
   local i,pm;
   pm:=lPerm[1];
   for i from 2 to nops(lPerm) do
      if perm[minlex](lPerm[i],pm)
         then pm:=lPerm[i]
         fi;
      od;
   RETURN(pm);
end:

# Return the set whose elements are orbits of H 
# acting on {1,2,..,|H|}.
`perm/orbits` := proc(K)
    local reste,orbs,classe,H;
    H:=convert(K,set); 
    reste:={$1..nops(op(1,H))};

    orbs:={};
    while reste <> {} do
        classe:=map(proc(p,reste) 
                        perm[action](p,op(1,reste)) 
                     end,
                     H,reste);
        orbs:=orbs union {classe};
        reste:=reste minus classe;
        od;
    RETURN(orbs);
end:

# List of inversions of p.
`perm/inversions` :=proc(p)
    local i,j,L;
    L:=NULL;
    for i from 1 to nops(p) do
        for j from i+1 to nops(p) do
            if p[i]>p[j] then L:=L,[i,j] fi;
            od;
        od;
    RETURN([L]);
end:    

# List of descents ofp.
`perm/desc` := proc(p)
   map(proc(i,p) if p[i]>p[i+1] then i fi end,[$1..nops(p)-1],p);
end:

# Procedure to manipulate combinatorial structures (type ?struct).

# Do a permutation act on a structure.
`perm/action` := proc(sigma,struct)
   eval(`perm/action/action_1`(perm[inv](sigma),struct))
end:
`perm/action/action_1` := proc(sigma,struct)
   map(proc(fact,sigma) 
           if type(fact,integer) 
             then RETURN(sigma[fact])
             else RETURN(`perm/action/action_1`(sigma,fact))
             fi
           end,
        struct,sigma);
end:

# Under lying set of a structure.
`perm/ulset` := proc(s)
   { `perm/ulset/epluche`(s) }
end:
`perm/ulset/epluche` := proc(s)
   if type(s,numeric) 
      then RETURN(s)
      else op(map('`perm/ulset/epluche`',s))
      fi;
end:

# Cardinality or the under lying set of a structure.
`perm/ulcard` :=proc(s)
  nops(perm[ulset](s));
end:

# Use to generate the orbit of s with respect to the action of
# the symmetric group Sn (where n=ulcard(s)).
`perm/genstruct` := proc(s)
   local E,Sn,i;   
   Sn:=combinat[permute](perm[ulcard](s));
   E:={};
   for i from 1 to nops(Sn) do
      E:=E union {perm[action](Sn[i],s)};
      od;
   RETURN(E);
end:

# This procedure is used to "regroup" a structure s with respect to
# a subgroup H of Sn. This operation consists to calculate H.s. This 
# is a way for create new structures from old ones.
`perm/regroup`:=proc(H,s)
    map(proc(g,s) perm[action](g,s) end,convert(H,set),s)
end:

# To create a p-structure (type ?makestruct).
`perm/makestruct` := proc(nom,H) 
   option remember; # A structure don't can be created twice.
  assign(nom,subs({stab=H,nomstruct=nom},
	 proc() 
    	local  sigma,tau,K,i;
	   	   sigma:=`perm/makestruct/permInd`(args);
   		   K:=stab;
   		   tau:=perm[pmin](perm[cllat](sigma,K));
   		   sigma:=perm[prod](perm[inv](sigma),tau);
   		   RETURN(evaln(nomstruct(seq(args[sigma[i]],i=1..nargs))))
		end));
  nom;
  # op(nom);
end:

`perm/makestruct/permInd` := proc()
   local i,m,f,g;
   m:=[seq(min(op(perm[ulset](args[i]))),i=1..nargs)];
   f:=sort(m);
   for i from 1 to nargs do
      g[f[i]]:=i
      od;
   RETURN([seq(g[i],i=m)]);
end:


# Cycle on n points.
`perm/C/makecycle` := proc(n)
   perm[makestruct](C.n,perm[grcyc]([$2..n ,1]))
end:

# Polygon on n points.
`perm/P/makepolyg` :=proc(n)
   perm[makestruct](P.n,perm[dihedral](n))
end:

# Generic cycle.
`perm/C` := proc() option remember;
   if not assigned(C.nargs) 
	then `perm/C/makecycle`(nargs) fi; 
   (C.nargs)(args);
   subs(C.nargs=C,");
end:
   
# Generic polygon.
`perm/P` := proc() option remember;
   if not assigned(P.nargs)
   	then `perm/P/makepolyg`(nargs) fi;
   (P.nargs)(args);
   subs(P.nargs=P,");
end:

# Stabilizer of a structure.
`perm/stab` := proc(s)
   local i,Sn,ensStab;  option remember;
   Sn:=combinat[permute](perm[ulcard](s));
   ensStab:={};
  for i from 1 to nops(Sn) do
      if perm[action](Sn[i],s)=s
         then ensStab:=ensStab union {Sn[i]}
         fi
      od;
   RETURN(ensStab)
end:

# Stabilizer of a structure (second method).
`perm/stabit` := proc(s)
   local p,ident,ensStab;
   ident:=perm[Id](perm[ulcard](s));
   ensStab:={ident};
   p:=perm[nextperm](ident);
   while p<>ident do
      if perm[action](p,s)=s
         then ensStab:=ensStab union {p}
         fi;
      p:=perm[nextperm](p);
      od;
   RETURN(ensStab)
end:


# Conjugacy procedures.

# Subprocedure of grconj
`perm/grconj/ctype` := proc(p)
			local i,t,lo,M;
			if nops(p)>0 then
      M:=max(op(map('nops',p)));
						for i from 1 to M do t[i]:=0; od;
						for i from 1 to nops(p) do	lo:=nops(p[i]);	t[lo]:=t[lo]+1;	od;
		 		 RETURN(convert(t,list));
						fi;
end:

# The next procedure returns a table whose indexes are cyclic type
# of elements of H.
# Notation: t(g) = cyclic type of g (t(g)[i] = number of cycle 
#                  of length i in g).
# - clconj(H)[t(g)] will contain all permutations of type t(g).
# - H is given as a set or permutation.
`perm/grconj/clconj` := proc(H)
   local C,types,i;
   # C = table with type as indexes: C[t(g)] = {perm. of type t(g)}
      # Initialisation.
   types:=map(proc(p) perm[ctype](p) end,H);
   C:=table();
   
   for i from 1 to nops(types) do
      C[op(types[i])] := {}
      od;
   for i from 1 to nops(H) do
      C[op(perm[ctype](H[i]))]:=
         C[op(perm[ctype](H[i]))] union {H[i]}
      od;
   RETURN(op(C));
end:


# Take a set of conjugaison classes and return the set of couples
# [t(C),|C| for each class C.
# Cl is a table whose indexes are cyclic types.
`perm/grconj/indcard` := proc(Cl)
   map(proc(t,card) [t,card[op(t)]] end,
           [indices(Cl)],
           map('nops',Cl));
   RETURN(convert(",set))
end:

# This implement a total order on couples [t(C),|C|].
# I1 and I2 are couples of form [t(C),|C|], (where C is a 
# permutation conjugaison class). Classes are ordered 1) by
# cardinality and 2) by inverse lex. order of cyclic type.
`perm/grconj/ordrecl` := proc(I1,I2)
   local t1,t2,maxl;
   if op(2,I1)<op(2,I2) 
      then RETURN(true)
      elif op(2,I1)>op(2,I2)
         then RETURN(false)
         else
            maxl:=max(nops(op(1,I1)),nops(op(1,I2)));
            t1:=[op(op(1,I1)),0$(maxl-nops(op(1,I1)))];
            t2:=[op(op(1,I2)),0$(maxl-nops(op(1,I2)))];
            RETURN(not minlex(t1,t2));
      fi;
   
end:

# Return index of the smaller class in lindcard, where
# the parameter lindcard is a list of couples (t,c).
`perm/grconj/minlexcl` := proc(lindcard)
  local i,pp;
  pp:=lindcard[1];
  for i from 2 to nops(lindcard) do
     if `perm/grconj/ordrecl`(lindcard[i],pp)
        then pp:=lindcard[i]
        fi
     od;
   RETURN(pp);
end:


# Return true if H1 and h2 are conjugated by g, if not,
# false is returned.
`perm/grconj/permconj` := proc(H1,H2,g)
   local i;
   if nops(H1)<>nops(H2)
      then RETURN(false)
      else i:=1;         
          while i<=nops(H1) do
            if not member(perm[conj](H1[i],g),H2)
               then RETURN(false) fi;
            i:=i+1;
            od;
         RETURN(true);
         fi;
end:


# This procedure find if H1 and H2 are conjugated.
`perm/grconj` := proc(H1,H2)
   local Cl1,Cl2,i,j,indC,clmin,Sn,conjp;
   if H1=H2 then RETURN(true) fi;
   if nops(H1)<>nops(H2) then RETURN(false) fi;
   if `perm/grconj/ctype`(perm[orbits](H1))<>`perm/grconj/ctype`(perm[orbits](H2))
     then RETURN(false) fi;
     
   Cl1:=`perm/grconj/clconj`(H1);
   Cl2:=`perm/grconj/clconj`(H2);

   # If the indexes set associed to H1 and H2 are not identical
   # then H1 and H2 are not conjugated.
   indC:=`perm/grconj/indcard`(op(Cl1)); 
   if {indC}<>{`perm/grconj/indcard`(op(Cl2))}
      then RETURN(false) fi;
   
   # Next, we check if there is a permutation that conjugate
   # the smaller class.   
   indC:=indC minus { `perm/grconj/minlexcl`(indC) };
   Sn:=combinat[permute](nops(H1[1]));
   clmin:=`perm/grconj/minlexcl`(indC);
   indC := convert(indC minus { `perm/grconj/minlexcl`(indC) },list);

   # We search a permutation that conjugate the smaller class of
   # Cl1 and Cl2. If there is a such permutation, we check that
   # it conjugate the others class.
   for i from 1 to nops(Sn) do
      if `perm/grconj/permconj`(Cl1[op(clmin[1])],Cl2[op(clmin[1])],Sn[i])
         then
            conjp:=true;
            j:=1;
            while (conjp and (j<=nops(indC))) do 
               if not `perm/grconj/permconj`(Cl1[op(op(1,indC[j]))],
                               Cl2[op(op(1,indC[j]))],Sn[i])
                  then conjp:=false
                  fi;
               j:=j+1;
               od; # while
             if conjp then RETURN(true) fi;
         fi;
      od; # If

   RETURN(false);
end:


        
# Multiplication in group algebra of Sn.

`convert/and`:=proc(l) 
   local i,A; 
   A:=l[1]; 
   for i from 2 to nops(l) do A:=A and l[i] od;
end:

# Scalar type. 
`type/scal` := proc(p)
    if type(p,{numeric,name,indexed}) then RETURN(true) fi;
    if type(p,`^`) and type(op(1,p),{numeric,name,indexed}) then RETURN(true) fi;
    if type(p,{`*`,`+`}) and
#    if type(p,`*`) and 
	convert(map(proc(x) if type(x,{numeric,name,indexed}) 
		then true else false fi end,[op(p)]),`and`)
	then RETURN(true) fi;
    RETURN(false)
end:

# perm type.
`type/perm` := proc(p)
    if type(p,list) then true
    elif type(p,`^`) and type(op(1,p),list)
    then true else false fi
end:

# Multiplication operator.
`perm/&X` := proc()
local _AA;
#options remember;
     _AA := [args];
    _AA := map(proc(x,pn)
                   if type(x,function) and (op(0,x) = pn) then op(x) else x fi
               end,
        _AA,procname);
    if nops(_AA) = 1 then RETURN(_AA[1]) fi;

    if type(_AA[1],`+`) 
      then RETURN(map(proc(mon,q) mon &X q end,_AA[1],_AA[2])) fi;
    if type(_AA[2],`+`) 
      then RETURN(map(proc(mon,q) q &X mon end,_AA[2],_AA[1])) fi;

    if nargs = 2 then RETURN(eval(`perm/&X/pprod`(_AA[1],_AA[2]))) fi;
    'procname'(op(_AA))
end:

# Product of two permutations.
`perm/&X/pprod`:=proc(p,q) local p1,q1,a1,b1;
    if type(p,perm) and type(q,perm)
        then RETURN(perm[prod](p,q)) fi;
    if (type(p,scal) and type(q,perm)) or (type(p,perm) and type(q,scal))
        or (type(p,scal) and type(q,scal)) then RETURN(p*q) fi;    
    if type(p,`*`) 
        then a1:=select(`type/scal`,p);
             p1:=select(`type/perm`,p)
        elif type(p,scal) 
            then a1:=p; p1:=[]
            else a1:=1; p1:=p;
        fi;
    if type(q,`*`) 
        then b1:=select(`type/scal`,q);
             q1:=select(`type/perm`,q)
        elif type(q,scal) 
            then b1:=q; q1:=[]
            else b1:=1; q1:=q
        fi;
    RETURN(a1*b1*perm[prod](p1,q1))
end:

# Permutation that appears in the polynom P.
`perm/supp` :=proc(P) local Q;
  Q:=expand(P);
  if not type(Q,`+`)
      then if type(Q,perm) 
	        then RETURN({Q}) 
	        else RETURN({select(`type/perm`,Q)})
	        fi;
     fi;
  map(proc(m) if type(m,perm)
                  then RETURN(m) 
                  else RETURN(select(`type/perm`,m))
                  fi
           end,
      convert(Q,set)); 

end:


# The following table contains generator of representative 
# of conjugacy class of S7 subgroups.

`perm/tab_gen`:=table();

# On 7 points.

`perm/tab_gen`[C6c]:=[[2,3,1,5,4,7,6]]:

`perm/tab_gen`[C6C2a]:=[[2,3,1,5,4,6,7],[1,2,3,4,5,7,6]]:

`perm/tab_gen`[S3e]:=[[2,1,3,5,4,7,6],[3,2,1,5,4,7,6]]:

`perm/tab_gen`[D6c]:=[[2,3,1,5,4,6,7],[2,1,3,4,5,6,7]]:

`perm/tab_gen`[D6d]:=[[2,3,1,4,5,7,6],[2,1,3,5,4,6,7]]:

`perm/tab_gen`[D6e]:=[[2,3,1,5,4,7,6],[2,1,3,5,4,6,7]]:

`perm/tab_gen`[S3Ka]:=[[2,1,3,4,5,6,7],[3,2,1,4,5,6,7],[1,2,3,5,4,6,7],[1,2,3,4,5,7,6]]:

`perm/tab_gen`[C10a]:=[[2,3,4,5,1,7,6]]:

`perm/tab_gen`[D5b]:=[[2,3,4,5,1,6,7],[1,5,4,3,2,7,6]]:

`perm/tab_gen`[D10a]:=[[2,3,4,5,1,6,7],[1,5,4,3,2,6,7],[1,2,3,4,5,7,6]]:

`perm/tab_gen`[H5b]:=[[2,3,4,5,1,6,7],[1,3,5,2,4,7,6]]:

`perm/tab_gen`[H5C2a]:=[[2,3,4,5,1,6,7],[1,3,5,2,4,6,7],[1,2,3,4,5,7,6]]:

`perm/tab_gen`[A5C2a]:=[[2,3,4,5,1,6,7],[2,3,1,4,5,6,7],[1,2,3,4,5,7,6]]:

`perm/tab_gen`[S5c]:=[[2,3,4,5,1,6,7],[2,3,4,1,5,7,6]]:

`perm/tab_gen`[S5C2a]:=[[2,3,4,5,1,6,7],[2,3,4,1,5,6,7],[1,2,3,4,5,7,6]]:

`perm/tab_gen`[C12a]:=[[2,3,1,5,6,7,4]]:

`perm/tab_gen`[C6C2b]:=[[2,3,1,5,4,7,6],[1,2,3,6,7,4,5]]:

`perm/tab_gen`[D4C3a]:=[[2,3,1,5,6,7,4],[1,2,3,6,5,4,7]]:

`perm/tab_gen`[A4c]:=[[2,3,1,5,6,4,7],[1,2,3,5,4,7,6]]:

`perm/tab_gen`[A4C3a]:=[[2,3,1,4,5,6,7],[1,2,3,5,6,4,7],[1,2,3,5,4,7,6]]:

`perm/tab_gen`[S4C3a]:=[[2,3,1,5,6,7,4],[1,2,3,5,6,4,7]]:

`perm/tab_gen`[Q6a]:=[[2,3,1,5,4,7,6],[2,1,3,6,7,5,4]]:

`perm/tab_gen`[C4S3a]:=[[2,3,1,5,6,7,4],[2,1,3,4,5,6,7]]:

`perm/tab_gen`[D6f]:=[[2,3,1,5,4,7,6],[2,1,3,6,7,4,5]]:

`perm/tab_gen`[S3Kb]:=[[2,1,3,4,5,6,7],[3,2,1,4,5,6,7],[1,2,3,6,7,4,5]]:

`perm/tab_gen`[D12a]:=[[2,3,1,5,6,7,4],[2,1,3,6,5,4,7]]:

`perm/tab_gen`[D4S3_a]:=[[2,3,1,5,4,7,6],[2,1,3,6,5,4,7]]:

`perm/tab_gen`[D4S3_b]:=[[2,3,1,5,4,6,7],[2,1,3,6,7,4,5]]:

`perm/tab_gen`[D4S3a]:=[[2,3,1,5,6,7,4],[2,1,3,6,5,4,7],[2,1,3,4,5,6,7]]:

`perm/tab_gen`[A4S3a]:=[[2,3,1,5,4,7,6],[2,1,3,5,6,4,7]]:

`perm/tab_gen`[S4e]:=   [[2,1,3,5,6,7,4],[3,1,2,5,6,4,7]]:

`perm/tab_gen`[S4S3_a]:=[[2,1,3,5,6,7,4],[3,1,2,5,6,4,7],[2,3,1,4,5,6,7]]:

`perm/tab_gen`[S4S3a]:= [[2,1,3,5,6,7,4],[3,1,2,5,6,4,7],[2,1,3,4,5,6,7]]:

`perm/tab_gen`[C7a]:=[[2,3,4,5,6,7,1]]:

`perm/tab_gen`[D7a]:=[[2,3,4,5,6,7,1],[1,7,6,5,4,3,2]]:

`perm/tab_gen`[H7_a]:=[[2,3,4,5,6,7,1],[1,3,5,7,2,4,6]]:

`perm/tab_gen`[H7a]:=[[2,3,4,5,6,7,1],[1,4,7,3,6,2,5]]:

`perm/tab_gen`[PSL27a]:=[[2,3,4,5,6,7,1],[2,3,7,5,1,4,6]]:

`perm/tab_gen`[A7a]:=[[2,3,4,5,6,7,1],[2,1,4,3,5,6,7]]:

`perm/tab_gen`[S7a]:=[[2,3,4,5,6,7,1],[2,1,3,4,5,6,7]]:




`perm/tab_gen`[I]:=[[1,2,3,4,5,6,7]]:


# On 6 points.

`perm/tab_gen`[C2c]    :=    [[2,1,4,3,6,5,7]]:

`perm/tab_gen`[Kc]     :=    [[2,1,3,4,5,6,7],[1,2,4,3,6,5,7]]:

`perm/tab_gen`[Kd]     :=    [[2,1,4,3,5,6,7],[2,1,3,4,6,5,7]]:

`perm/tab_gen`[C23a]   :=    [[2,1,3,4,5,6,7],[1,2,4,3,5,6,7],[1,2,3,4,6,5,7]]:

`perm/tab_gen`[C4b]    :=    [[2,3,4,1,6,5,7]]:

`perm/tab_gen`[C4C2a]  :=    [[2,3,4,1,5,6,7],[1,2,3,4,6,5,7]]:

`perm/tab_gen`[Ke]     :=    [[2,1,4,3,5,6,7],[3,4,1,2,6,5,7]]:

`perm/tab_gen`[C23b]   :=    [[2,1,4,3,5,6,7],[3,4,1,2,5,6,7],[1,2,3,4,6,5,7]]:

`perm/tab_gen`[D4b]    :=    [[3,4,2,1,5,6,7],[2,1,3,4,6,5,7]]:

`perm/tab_gen`[D4c]    :=    [[3,4,2,1,6,5,7],[2,1,3,4,5,6,7]]:

`perm/tab_gen`[D4d]    :=    [[3,4,2,1,6,5,7],[2,1,3,4,6,5,7]]:

`perm/tab_gen`[D4C2a]  :=    [[3,4,2,1,5,6,7],[2,1,3,4,5,6,7],[1,2,3,4,6,5,7]]:

`perm/tab_gen`[A4C2a]  :=    [[2,3,1,4,5,6,7],[2,1,4,3,5,6,7],[1,2,3,4,6,5,7]]:

`perm/tab_gen`[S4b]    :=    [[2,3,4,1,6,5,7],[2,3,1,4,5,6,7]]:

`perm/tab_gen`[S4C2a]  :=    [[2,3,4,1,5,6,7],[2,3,1,4,5,6,7],[1,2,3,4,6,5,7]]:

`perm/tab_gen`[C3b]    :=    [[2,3,1,5,6,4,7]]:

`perm/tab_gen`[C32a]   :=    [[2,3,1,4,5,6,7],[1,2,3,5,6,4,7]]:

`perm/tab_gen`[S3C3a]  :=    [[2,1,3,4,5,6,7],[3,2,1,4,5,6,7],[1,2,3,5,6,4,7]]:

`perm/tab_gen`[S3c]    :=    [[2,1,3,5,4,6,7],[3,2,1,6,5,4,7]]:

`perm/tab_gen`[S32_a]  :=    [[2,3,1,4,5,6,7],[1,2,3,5,6,4,7],[2,1,3,5,4,6,7]]:

`perm/tab_gen`[S32a]   :=    [[2,1,3,4,5,6,7],[3,2,1,4,5,6,7],[1,2,3,5,4,6,7],
                   [1,2,3,6,5,4,7]]:

`perm/tab_gen`[C6b]    :=    [[2,3,4,5,6,1,7]]:

`perm/tab_gen`[S3d]    :=    [[4,6,5,1,3,2,7],[5,4,6,2,1,3,7]]:

`perm/tab_gen`[D6b]    :=    [[2,3,4,5,6,1,7],[1,6,5,4,3,2,7]]:

`perm/tab_gen`[A4b]    :=    [[2,3,1,5,6,4,7],[4,5,3,1,2,6,7]]:

`perm/tab_gen`[A4C2b]  :=    [[2,3,1,5,6,4,7],[4,5,3,1,2,6,7],[4,5,6,1,2,3,7]]:

`perm/tab_gen`[S4c]    :=    [[5,1,3,2,4,6,7],[2,3,1,5,6,4,7]]:

`perm/tab_gen`[S4d]    :=    [[6,5,1,3,2,4,7],[2,3,1,5,6,4,7]]:

`perm/tab_gen`[S4C2b]  :=    [[5,1,3,2,4,6,7],[2,3,1,5,6,4,7],[4,5,6,1,2,3,7]]:

`perm/tab_gen`[S3C3b]  :=    [[4,6,5,1,3,2,7],[5,4,6,2,1,3,7],[2,3,1,4,5,6,7],[1,2,3,5,6,4,7]]:

`perm/tab_gen`[S32b]   :=    [[4,6,5,1,3,2,7],[5,4,6,2,1,3,7],[2,1,3,6,5,4,7],
                   [3,2,1,5,4,6,7]]:

`perm/tab_gen`[C2S3_a] :=    [[4,5,6,1,3,2,7],[4,5,6,3,2,1,7]]:

`perm/tab_gen`[C2S3a]  :=    [[2,1,3,4,5,6,7],[3,2,1,4,5,6,7],[4,5,6,1,2,3,7]]:

`perm/tab_gen`[A5b]    :=    [[2,3,4,5,1,6,7],[4,1,5,2,6,3,7]]:

`perm/tab_gen`[S5b]    :=    [[2,3,4,5,1,6,7],[3,2,6,1,5,4,7]]:

`perm/tab_gen`[A6a]    :=    [[2,3,4,5,1,6,7],[2,3,4,1,6,5,7]]:

`perm/tab_gen`[S6a]    :=    [[2,3,4,5,1,6,7],[6,2,3,4,5,1,7]]:

# On 5 points.

`perm/tab_gen`[C6a]    :=    [[2,3,1,5,4,6,7]]:

`perm/tab_gen`[S3b]    :=    [[2,1,3,5,4,6,7],[3,2,1,5,4,6,7]]:

`perm/tab_gen`[D6a]    :=    [[2,3,1,5,4,6,7],[2,1,3,4,5,6,7]]:

`perm/tab_gen`[C5a]    :=    [[2,3,4,5,1,6,7]]:

`perm/tab_gen`[D5a]    :=    [[2,3,4,5,1,6,7],[1,5,4,3,2,6,7]]:

`perm/tab_gen`[H5a]    :=    [[2,3,4,5,1,6,7],[1,3,5,2,4,6,7]]:

`perm/tab_gen`[A5a]    :=    [[2,3,4,5,1,6,7],[2,3,1,4,5,6,7]]:

`perm/tab_gen`[S5a]    :=    [[2,3,4,5,1,6,7],[2,3,4,1,5,6,7]]:

# On less than 4 points.

`perm/tab_gen`[S4a]    :=    [[2,3,4,1,5,6,7],[2,3,1,4,5,6,7]]:

`perm/tab_gen`[A4a]    :=    [[2,3,1,4,5,6,7],[2,1,4,3,5,6,7]]:

`perm/tab_gen`[D4a]    :=    [[3,4,2,1,5,6,7],[2,1,3,4,5,6,7]]:

`perm/tab_gen`[Kb]     :=    [[2,1,4,3,5,6,7],[3,4,1,2,5,6,7]]:

`perm/tab_gen`[C4a]    :=    [[2,3,4,1,5,6,7]]:

`perm/tab_gen`[Ka]     :=    [[2,1,3,4,5,6,7],[1,2,4,3,5,6,7]]:

`perm/tab_gen`[C2b]    :=    [[2,1,4,3,5,6,7]]:

`perm/tab_gen`[S3a]    :=    [[2,1,3,4,5,6,7],[3,2,1,4,5,6,7]]:

`perm/tab_gen`[C3a]    :=    [[2,3,1,4,5,6,7]]:

`perm/tab_gen`[C2a]    :=    [[2,1,3,4,5,6,7]]:


# The next procedure can be used to generate the representatives
# of conjugacy class of Sn with a table containing generators (like
# `perm/tab_gen`). If each element T[gen] is a list of generator,
# then gentabsg(T,n) return a table whose index gen contain the
# set of permutation of the sungroup <gen> (in Sn).
# This procedure can be used to generate once for all the list of subgroup.
`perm/gentabsg` :=proc (T,n)
   local tabPerms;
   map(proc(gen,tabPerm,T,n)
            tabPerm[op(gen)]:=perm[gensg](T[op(gen)],n)
            end,
        [indices(T)],tabPerms,T,n);
   RETURN(op(tabPerms));
end:


# ----------- end of proc definitions --------------------


# ----------- definition of "perm" table ----------------

perm:='perm':
perm['inv']:=eval(`perm/inv`):
perm['prod']:=eval(`perm/prod`):
perm['conj']:=eval(`perm/conj`):
perm['sgn']:=eval(`perm/sgn`):
perm['nextperm']:=eval(`perm/nextperm`):
perm['Id']:=eval(`perm/Id`):
perm['grcyc']:=eval(`perm/grcyc`):
perm['dihedral']:=eval(`perm/dihedral`):
perm['cyc']:=eval(`perm/cyc`):
perm['minlex']:=eval(`perm/minlex`):
perm['cllat']:=eval(`perm/cllat`):
perm['pmin']:=eval(`perm/pmin`):
perm['orbits']:=eval(`perm/orbits`):
perm['inversions']:=eval(`perm/inversions`):
perm['desc']:=eval(`perm/desc`):

perm['decomp']:=eval(`perm/decomp`):
perm['ctype']:=eval(`perm/ctype`):
perm['complete']:=eval(`perm/complete`):
perm['gensg']:=eval(`perm/gensg`):
perm['action']:=eval(`perm/action`):
perm['ulset']:=eval(`perm/ulset`):
perm['ulcard']:=eval(`perm/ulcard`):
perm['genstruct']:=eval(`perm/genstruct`):
perm['regroup']:=eval(`perm/regroup`):
perm['posmin']:=eval(`perm/posmin`):
perm['makestruct']:=eval(`perm/makestruct`):
perm['C']:=eval(`perm/C`):
perm['P']:=eval(`perm/P`):
perm['stab']:=eval(`perm/stab`):
perm['stabit']:=eval(`perm/stabit`):

perm['grconj']:=eval(`perm/grconj`):

perm['`&X`']:=eval(`perm/&X`):
perm['supp']:=eval(`perm/supp`):

perm['gentabsg']:=eval(`perm/gentabsg`):
perm['tab_gen']:=eval(`perm/tab_gen`):




# ---------------- Help texts -------------------------------

`help/text/perm` := TEXT(
`This package contains procedure to manipulate permutations of `,
`{1,2,...,n} from a combinatorial point of view. The permutations`,
`are given as list [x1,x2,...,xn] of integer with xi the`,
`image of i. The procedures can be classified in three parts:`,
``,
`     1) [cllat, complete, conj, ctype, cyc, cyclemax, decomp, `,
`         desc, dihedral, gensg, grcyc, inv, inversions, mctype, `,
`         orbits, nextperm, plpet,  pmin, prod,  sgn, Id]`,
``,
`        General procedures you can use to calculate`,
`        inverses, products, disjoints cycles decomposition`,
`        cyclic type, descents of permutation. There is also`,
`        a procedure returning the elements of the group`,
`        generated by a finite set of permutations.`,
``,
`     2) [action, ulset, ulcard, genstruct, grconj, makestruct,  `,
`         posmin, regroup, stab, stabit, C, P]`,
``,
`        Procedure to do manipulation on combinatorials structures in`,
`        regards of transitive actions of the symmetrics groups.`,
`        You can refer to [Ch1] for a description of the method used`,
`        to represent structures. They are represented by lateral classes`,
`        in Sn of their stabilizers. The implementation is made by procedure`,
`        which calculate class representative. For example, a cycle `,
`        (cyclic graph) on {1,2,3,4} will be represented by C(1,3,2,4).`,
`        This represents the cycle (1->3, 3->2, 2->4, 4->1). With this method,`,
`        it is possible to represent a cycle whose vertices are disjoints sets,`,
`        it is sufficient to write, for example, C({1,3},{2,5},{2,6}).`,
`        Next, you can  calculate the stabilizer. Notes that graphs just need`,
`        "{}[]" to be constructed. Type ?struct for details about construction`,
`        of structures.`,
`        There is procedure use to make a permutation act on a structure;`,
`        another use to generate the orbits of a structure (with respect to`,
`        the action of Sn); a procedure can create a procedure to represents`,
`        a structure from a subgroup of Sn.`,
``,
`        3) [&X, supp]`,
``,
`           Here we find procedure to do multiplication in Sn algebra.`,
`           This is a infix operator whose arguments are polynoms whose variable`,
`           are the permutations. The coefficient can be numeric, indexed or `,
`           name. You also can use sum of these as coefficients.`,
``,
`There is also a table named ``perm/tab_gen`` containing the generators of `,
`conjugacy class representatives of subgroups of symmetric groups up to S7,`,
`and a procedure named "gentabsg" that can generate these representatives.`,
`The indices of this table are the name of the representatives`,
`according to Wensley terminology (see [We]).`,
`To create the sets of permutations of each representative, `,
`type tabsg:=gentabsg(op(``perm/tab_gen``),7). Note that you can`,
`launch a background task under UNIX for create the table. It suffices to put the `,
`following lines in a file named, tabsgfile:`,
``,
`  with(perm);`,
`  tabsg:=gentabsg(op(``perm/tab_gen``),7);`,
`  save tabsg,``tabsg.m``;`,
`  quit;`,
``,
`And then, under UNIX, type:  nice -20 maple -q <tabsgfile >typeout &.   Once the`,
`table is saved, you can recall this with maple "read" function or include`,
`this in perm package itself.`,
``,
`Note that if there is a file tabsg.m in the library directory, it is automaticaly `,
`loaded with the package.`,
``,
`GLOBALS Variables: The code uses the following names:`,
``,
` H5C2a, C2b, Ka, Ke, A4S3a, A4C2b, C2S3a, S4d, S4e, D5a, D4C2a, PSL27a, C6C2a,

    S32a, A4c, D7a, S3c, D4b, S6a, Kd, S3Ka, C23b, C6b, D4a, S4c, C3b, S3Kb,

    C32a, Q6a, C23a, S4C2a, D4c, S4a, D4d, C10a, S3C3a, S4S3_a, C4b, A4a, C3a,

    D10a, C12a, H5a, C5a, S32b, S4S3a, D4S3_a, C2a, S5b, C2S3_a, S4C3a, H7_a,

    S5a, D4S3a, A7a, D4C3a, S5c, A5C2a, D12a, D6f, S5C2a, D6b, S3a, A5a, I,

    C6a, C4S3a, S4C2b, C6C2b, C4a, D5b, H7a, S7a, A4C2a, S3b, H5b, A6a, A4b,

    A4C3a, Kb, C4C2a, S3e, Kc, S4b, C6c, S3C3b, C7a, A5b, D6c, D6d, C2c,

    D4S3_b, S32_a, S3d, D6e, D6a `,
``,
`BIBLIOGRAPHY`,
``,
` [Ch1] Chiricota, Y., "Representation de structures combinatoires en Maple",`,
` 	J. of Theorical Computer Sc., vol 117, 1993`,
``,
` [Ch1] Chiricota, Y., "Classification des especes moleculaires de degre 6 et 7",`,
` 	to appear in Ann. des Sc. Math. du Quebec.`,
``,
` [Jl]  Labelle, J., "Quelques especes sur les ensembles de petites cardinalite",`,
`	Ann. des Sc. Math. du Quebec, 7, no. 1, 59-94.`,
``,
` [We]	Wensley, C.D., "The super character table of the symmetric group S7",`,
`	U.C.N.W., Pure Math. preprint,Bangor, U.K.`,
``):





`help/perm/text/inv` := TEXT(
`FUNCTION: inv - inverse of a permutation`,
``,
`CALLING SEQUENCE:   inv(p);`,
``,
`PARAMETERS: p - permutation`,
``,
`SYNOPSIS:`,
`- The call inv(p); return the inverse of permutation p.`,
``,
`EXAMPLE:`,
``,
`> inv([2,3,1,5,4]);`,
``,
`                    [3,1,2,5,4]`
):

`help/perm/text/prod` := TEXT(
`FUNCTION: prod - product of permutations`,
``,
`CALLING SEQUENCE: prod(p,q);`,
``,
`PARAMETERS: p,q - permutations`,
``,
`SYNOPSIS:`,
`- This procedure calculate the product of permutations p and q.`,
``,
`EXAMPLE:`,
``,
`> prod([2,1,4,3,6,5],[2,3,4,1,6,5]);`,
``,
`                    [1, 4, 3, 2, 5, 6]`
):

`help/perm/text/conj` := TEXT(
`FUNCTION: conj - conjugate permutations`,
``,
`CALLING SEQUENCE: conj(p,q)  ;`,
``,
`PARAMETERS: p,q - permutations`,
``,
`SYNOPSIS:`,
`- Return the conjugate of p by q (i.e. $q p q^{-1}$).`,
``,
`EXAMPLE:`,
``,
`> conj([2,3,1,5,6,4],[2,3,4,5,6,1]);`,
``,
`                    [5, 3, 4, 2, 6, 1]`
):


`help/perm/text/sgn` := TEXT(
`FUNCTION: sgn - signature`,
``,
`CALLING SEQUENCE: sgn(p);`,
``,
`PARAMETERS: p - permutation`,
``,
`SYNOPSIS:`,
`- Calculate the signature of p.`,
``,
`EXAMPLE:`,
``,
`> sgn([2,1,4,3,6,5]);`,
``,
`                   -1 `
):


`help/perm/text/nextperm` := TEXT(
`FUNCTION: nextperm - generate next permutation in lexicographic order.`,
``,
`CALLING SEQUENCE: nextperm(p);`,
``,
`PARAMETERS: p - permutation`,
``,
`SYNOPSIS:`,
`- The call nextperm(p) return the permutation that is the successor`,
`  of p in the lexicographic order.`,
`- By convention, the successor of [n, n-1, ..., 2, 1] is [1,2, ..., n].`,
``,
`EXAMPLE:`,
``,
`> nextperm([1,2,3,4]);`,
``,
`                   [1,2,4,3]`
):


`help/perm/text/Id` := TEXT(
`FUNCTION: Id - identity permutation`,
``,
`CALLING SEQUENCE: Id(n);`,
``,
`PARAMETERS: n - integer`,
``,
`SYNOPSIS:`,
`- Id(n) is a sort cut for [1,2,...,n].`,
``,
`EXAMPLE:`,
``,
`> Id(5);`,
``,
`                    [1,2,3,4,5]`
):


`help/perm/text/grcyc` := TEXT(
`FUNCTION: grcyc - cyclic group generated by a permutation`,
``,
`CALLING SEQUENCE: grcyc(p);`,
``,
`PARAMETERS: p - permutation`,
``,
`SYNOPSIS:`,
`- This procedure generate a set whose members are the permutations that `,
`  are the powers of p.`,
``,
`EXAMPLE:`,
``,
`> grcyc([3,2,5,4,1]);`,
``,
`                   {[1, 2, 3, 4, 5], [3, 2, 5, 4, 1], [5, 2, 1, 4, 3]} `
):


`help/perm/text/dihedral` := TEXT(
`FUNCTION: dihedral - generate the n-th dihedral group`,
``,
`CALLING SEQUENCE: dihedral(n);`,
``,
`PARAMETERS: n - integer`,
``,
`SYNOPSIS:`,
`- This procedure generate the set of permutations belonging to the`,
`  n-th dihedral group.`,
``,
`EXAMPLE:`,
``,
`>  dihedral(4);`,
``,
`         {[1, 4, 3, 2], [3, 2, 1, 4], [4, 1, 2, 3], [4, 3, 2, 1], `,
``,
`           [2, 1, 4, 3], [2, 3, 4, 1], [1, 2, 3, 4], [3, 4, 1, 2]}`,
``
):

`help/perm/text/cyc` := TEXT(
`FUNCTION: cyc - cycle to which belong a integer in a permutation`,
``,
`CALLING SEQUENCE: cyc(i,p);`,
``,
`PARAMETERS: i - integer`,
`            p - permutation`,
``,
`SYNOPSIS:`,
`- The call cyc(i,p); return a list whose elements are integer member`,
`  of the cycle of p that contain i.`,
`- The returned list is such that the integer in the k-th position is `,
`  the image by p of preceding one.`,
`EXAMPLE:`,
``,
`> cyc(3,[2,3,4,1,6,5]);`,
``,
`                   [3, 4, 1, 2]`
):

`help/perm/text/decomp` := TEXT(
`FUNCTION: decomp - decomposition of p in disjoints cycles`,
``,
`CALLING SEQUENCE: decomp(p);`,
``,
`PARAMETERS: p - permutation`,
``,
`SYNOPSIS:`,
`- Return the decomposition of a permutation p as list of list`,
`  representing disjoints cycles.`,
`- A list representing a cycle is writen with de minimum interger in first`,
`  position. Lists are ordered by decreasing order of minimun of cycles.`,
``,
`EXAMPLE:`,
``,
`> decomp([4,6,5,1,7,2,8,3]);`,
``,
`                    [[3, 5, 7, 8], [2, 6], [1, 4]]`
):

`help/perm/text/plpet` := TEXT(
`FUNCTION: plpet - minimun of two permutation in lexical order`,
``,
`CALLING SEQUENCE: plpet(p,q);`,
``,
`PARAMETERS: p,q - permutations`,
``,
`SYNOPSIS:`,
`- This preocedure return "true" if p is a permutation who come before q `,
`  in the lexical order, and else return "false".`,
``,
`EXAMPLE:`,
``,
`> plpet([2,1,3,4,5],[2,1,4,3,5]);`,
``,
`                   true`
):

`help/perm/text/ctype` := TEXT(
`FUNCTION: ctype - permutation cyclic type`,
``,
`CALLING SEQUENCE: ctype(p);`,
``,
`PARAMETERS: p - permutation`,
``,
`SYNOPSIS:`,
`- The call ctype(p) return a list whose i-th element is the number`,
`  of cycle of lenght i in the canonical cyclic decomposition of p.`,
``,
`EXAMPLE:`,
``,
`> ctype([2,1,4,3,7,8,5,6,9]);`,
``,
`                    [1,4]`
):

`help/perm/text/complete` := TEXT(
`FUNCTION: complete - ajust the lenght of a permutation`,
``,
`CALLING SEQUENCE: complete(p,n);`,
``,
`PARAMETERS: p - permutation`,
`            n - integer`,
``,
`SYNOPSIS:`,
`- If p is a permutation of k integer, this procedure return the`,
`  image by the canonical injection of p in Sn (where n>=k).`,
``,
`EXAMPLE:`,
``,
`> complete([4,3,2,1],6);`,
``,
`                    [4, 3, 2, 1, 5, 6]`
):

`help/perm/text/gensg` := TEXT(
`FUNCTION: gensg - generate a subgroup of Sn`,
``,
`CALLING SEQUENCE: gensg(X,n);`,
``,
`PARAMETERS: X - list of permutation`,
`            n - integer`,
``,
`SYNOPSIS:`,
`- This procedure use a variant of the Todd-Coxeter algorithm to calculate`,
`  the subgroup of Sn generated by the permutation of the list X.`,
`- The list must contain permutation of length smalleror equal to n.`,
`EXAMPLE:`,
``,
`> gensg([[2,1],[1,2,4,3]],5);`,
``,
`     {[1, 2, 4, 3, 5], [2, 1, 4, 3, 5], [1, 2, 3, 4, 5], [2, 1, 3, 4, 5]}`,
``
):

`help/perm/text/cllat` := TEXT(
`FUNCTION: cllat - lateral class`,
``,
`CALLING SEQUENCE: cllat(p,K);`,
``,
`PARAMETERS: p - permutation`,
`            K - set of permutation`,
``,
`SYNOPSIS:`,
`- This procedure return the lateral class pK.`,
``,
`EXAMPLE:`,
``,
`> cllat([2,1,4,3],gensg([[2,1,3,4],[1,2,4,3]],4));`,
``,
`         {[1, 2, 3, 4], [1, 2, 4, 3], [2, 1, 3, 4], [2, 1, 4, 3]}`
):

`help/perm/text/pmin` := TEXT(
`FUNCTION: pmin - smaller lpermutation of a list`,
``,
`CALLING SEQUENCE: pmin(X);`,
``,
`PARAMETERS: X - list or set of permutation`,
``,
`SYNOPSIS:`,
`- Return the smaller (with respect to lexical order) permutation of a list.`,
``,
`EXAMPLE:`,
``,
`> pmin({[2,1,3,4],[2,1,4,3],[1,3,2,4]});`,
``,
`            [1,3,2,4]`
):

`help/perm/text/orbits` := TEXT(
`FUNCTION: orbits - orbits of a subgroup of permutation`,
``,
`CALLING SEQUENCE: orbits(K);`,
``,
`PARAMETERS: K - list or set of permutation`,
``,
`SYNOPSIS:`,
`- This procedure calculate the orbits of a subgroup of Sn.`,
`- The orbits are returned as a set of sets.`,
``,
`EXAMPLE:`,
``,
`> orbits(gensg([[2,1,3,4,5],[1,2,4,3,5]],5));`,
``,
`                    {{3, 4}, {1, 2}, {5}}`
):


`help/perm/text/inversions` := TEXT(
`FUNCTION: inversions - inversions of a permutation`,
``,
`CALLING SEQUENCE: inversions(p);`,
``,
`PARAMETERS: p - permutation`,
``,
`SYNOPSIS:`,
`- This procedure return a list of pair of integers giving the positions`,
`  where inversions occur in p.`,
``,
`EXAMPLE:`,
``,
`> inversions([2,1,6,5,4,3]);`,
``,
`           [[1, 2], [3, 4], [3, 5], [3, 6], [4, 5], [4, 6], [5, 6]] `
):

`help/perm/text/desc` := TEXT(
`FUNCTION: desc - descents of a permutation`,
``,
`CALLING SEQUENCE: desc(p);`,
``,
`PARAMETERS: p - permutation`,
``,
`SYNOPSIS:`,
`- The call desc(p) return a the set of descents of p, that is, the`,
`  set of positions i where p[i]>p[i+1].`,
``,
`EXAMPLE:`,
``,
`> desc([2,1,6,4,5,3]);`,
``,
`                    [1, 3, 5]`
):

`help/perm/text/action` := TEXT(
`FUNCTION: action - make a permutation act on a structure`,
``,
`CALLING SEQUENCE: action(p,s);`,
``,
`PARAMETERS: p - permutation`,
`            s - structure`,
``,
`SYNOPSIS:`,
`- This procedure does the calculation p.s, that is, the action of p on the`,
`  structure s. This action is made by relabelling of the point of s according`,
`  to p.`,
`- The structures are recursively defined by mean of [], {} or by a procedure created`,
`  by makestruct (which we call a p-structure). It is a list (resp. set or `,
`  p-structure) of list or set or p-structure.`,
`- Type ?perm,makestruct; for a definition of p-structures.`,
``,
`See also: gensg, makestruct, genstruct, regroup, stab.`,
``,
`EXAMPLES:`,
``,
`# C is a p-structure representing a cycle. In this example, the permutation`,
`# act on a linear order formed with two cycle of length three.`,
`action([4,5,6,1,2,3],[C(1,2,3),C(4,5,6)]);`,
``,
`             [C(4, 5, 6), C(1, 2, 3)]`,
``,
`# P is a p-structure representing a polygon. P(1,2,3,4) represent the `,
`# polygon whose stabilizer is generated by {[2,3,4,1],[2,1,4,3]} (dihedral`,
`# group of order 4).`,
`> action([4,2,3,1],P(1,2,3,4));`,
``,
`                 P(1, 3, 2, 4)`,
``,
`# The next line create a p-structure representing a oriented simplex on four`,
`# points. Note that the group generated by {[2,3,1,4],[2,1,4,3]} is the `,
`# alternated group of order four.`,
`> makestruct(OrSet,gensg([[2,3,1,4],[2,1,4,3]],4));`,
``,
`                    OrSet`,
``,
`# The result of the next line is true because [4,3,2,1] is a odd permutation.`,
`> evalb(action([4,3,2,1],OrSet(2,1,4,3)) = OrSet(2,1,4,3));`,
``,
`                         true`,
``
):

`help/perm/text/ulset` := TEXT(
`FUNCTION: ulset - underlying set of a structure`,
``,
`CALLING SEQUENCE:  ulset(s);`,
``,
`PARAMETERS: s - structure`,
``,
`SYNOPSIS:`,
`- Returns the underlying set of a structure.`,
``,
`EXAMPLE:`,
``,
`> ulset({C([4,5],[2,1],[8,9]),C([10,3],[11,7],[6,12])});`,
``,
`             {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}`
):

`help/perm/text/ulcard` := TEXT(
`FUNCTION: ulcard - cardinality of the underlying  set of a structure`,
``,
`CALLING SEQUENCE: ulcard(s);`,
``,
`PARAMETERS: s - structure`,
``,
`SYNOPSIS:`,
`- Return the underlying cardinality of a structure s.`,
``,
`EXAMPLE:`,
``,
`> ulcard(C({1,2},{3,4},{5,6}));`,
``,
`                   6`
):

`help/perm/text/genstruct` := TEXT(
`FUNCTION: genstruct - generate structure by transitive action of Sn`,
``,
`CALLING SEQUENCE: genstruct(s);`,
``,
`PARAMETERS: s - structure`,
``,
`SYNOPSIS:`,
`- Essentially, the call esgenstruct(s) do a map of procedure action on s`,
`  with all the permutation in the symmetric group of order equal to the`,
`  cardinality of the underlying set of s.`,
``,
`See also: action, makestruct`,
``,
`EXAMPLE:`,
``,
`> genstruct([{1,2},C(3,4,5)]);`,
``,
` {[{2, 3}, C(1, 4, 5)], [{3, 5}, C(1, 2, 4)], [{4, 5}, C(1, 3, 2)],`,
``,
`  [{1, 5}, C(2, 3, 4)], [{2, 3}, C(1, 5, 4)],  [{1, 4}, C(2, 3, 5)],`,
``,
`  [{1, 5}, C(2, 4, 3)],  [{1, 2}, C(3, 4, 5)], [{1, 4}, C(2, 5, 3)], `,
``,
`  [{2, 4}, C(1, 3, 5)], [{2, 5}, C(1, 3, 4)],  [{1, 3}, C(2, 4, 5)],`,
``,
`  [{4, 5}, C(1, 2, 3)],   [{2, 4}, C(1, 5, 3)], [{2, 5}, C(1, 4, 3)], `,
``,
`  [{1, 3}, C(2, 5, 4)], [{3, 4}, C(1, 5, 2)],   [{1, 2}, C(3, 5, 4)],`,
``,
`  [{3, 4}, C(1, 2, 5)], [{3, 5}, C(1, 4, 2)] }`,
``
):

`help/perm/text/regroup` := TEXT(
`FUNCTION: regroup - make new structures from old ones`,
``,
`CALLING SEQUENCE: regroup(K,s);`,
``,
`PARAMETERS: K - subgroup of Sn (set of permutations)`,
`            s - structure`,
``,
`SYNOPSIS:`,
`- This procedure does the calculation K.s. This is a way to create new`,
`  structures with known ones.`,
`- Note that if H=stab(s), then stab(K.s) will be HK if H and K commute (see`,
`  for example [Yc2] (for bibliography, type ?perm).`,
``,
`EXAMPLE:`,
``,
`# In this example, t is assigned a structure obtained by a action of the`,
`# cyclic group of arder two on a cycle. This action is by a inversion`,
`# of the orientation of the cycle. In fact, the result is a polygon. This is`,
`# what we check next. The stab of t and P(1,2,3,4) are conjugated.`,
`> t:=regroupe(gensg([[2,1,4,3]],4),C(1,2,3,4));`,
``,
`              t := {C(1, 2, 3, 4), C(1, 4, 3, 2)}`,
``,
`> grconj(stab(t),dihedral(4));`,
``,
`                            true`,
``
):



`help/perm/text/makestruct` := TEXT(
`FUNCTION:  - `,
``,
`CALLING SEQUENCE: makestruct(name,K);`,
``,
`PARAMETERS: name - string`,
`            K    - permutation list`,
``,
`SYNOPSIS:`,
`- This procedure create a p-structure. That is, a structure that is`,
`  represented by a procedure. The parametre "name" is the name of the`,
`  structure and K is a list (group) of permutations. This list is in fact`,
`  the stabilizer of the structure to be created. For example, if K is`,
`  the group generated by {[2,3,4,1],[2,1,4,3]} (dihedral group), the`,
`  call makestruct(polyg4,K) create a procedure called polyg4 and such`,
`  that stab(polyg4(1,2,3,4)) return K.`,
`- The created procedure can be used to define other structure by `,
`  substitution. For example, polyg({3,5},{2,6},{,1,7},{4,8}) represents`,
`  a polygon on four vertex that are themself two elements set.`,
``,
`See also: action, gensg, genstruct, regroup, stab.`,
``,
`EXAMPLE:`,
``,
`# Create a Pbic4 structure, that is, a bicolored polygon of four vertex:`,
``,
`#                     1 O=====O 2`,
`#                       |     |`,
`#                       |     |`,
`#                     4 O=====O 3`,
``,
`> makestruct(Pbic4,gensg([[2,1,4,3],[3,4,1,2]],4));`,
``,
`                    Pbic4 `,
``,
`# Action of permutation [4,2,3,1] on a Pbic4-structure.`,
`> action([4,2,3,1],Pbic4(1,2,3,4));`,
``,
`              Pbic4(1, 3, 2, 4)`,
``,
`# The next call generate the six Pbic4-structures.`,
`> genstruct(Pbic4(1,2,3,4));`,
``,
`     {Pbic4(1, 2, 3, 4), Pbic4(1, 3, 2, 4), Pbic4(1, 2, 4, 3), `,
``,
`      Pbic4(1, 4, 2, 3), Pbic4(1, 3, 4, 2), Pbic4(1, 4, 3, 2)} `,
``
):


`help/perm/text/C` := TEXT(
`FUNCTION: C - cycle structure`,
``,
`CALLING SEQUENCE: C(s1,...,sk);`,
``,
`PARAMETERS: s1,..,sk - structures`,
``,
`SYNOPSIS:`,
`- This procedure illustrate how makestruct can be used to represent generic`,
`  structure like cycles.`,
`- The call C(s1,...,sk) represents a cycle of length k on the structures`,
`  s1,...,sk. This automaticaly create a procedure Ck that represents a`,
`  cycle of length k and evaluate it with the arguments s1,...,sk.`,
``,
`See also: makestruct`,
``,
`EXAMPLE:`,
``,
`> C({3,4},{1,2},{5,6});`,
``,
`                    C({1, 2}, {5, 6}, {3, 4})`
):


`help/perm/text/P` := TEXT(
`FUNCTION: P - polygon structure`,
``,
`CALLING SEQUENCE: P(s1,...,sk);`,
``,
`PARAMETERS: s1,..,sk - structures`,
``,
`SYNOPSIS:`,
`- This procedure illustrate how makestruct can be used to represent generic`,
`  structure like polygons.`,
`- The call P(s1,...,sk) represents a polygon on k vertex that are the structures`,
`  s1,...,sk. This automaticaly create a procedure Pk that represents a`,
`  polygon on k vertex and evaluate it with the arguments s1,...,sk.`,
``,
`See also: makestruct.`,
``,
`EXAMPLE:`,
``,
`> P({3,4},{1,2},{5,6});`,
``,
`                    P({1, 2}, {5, 6}, {3, 4})`
):

`help/perm/text/stab` := TEXT(
`FUNCTION: stab, stabit  - stabilizer of a structure`,
``,
`CALLING SEQUENCE: stab(s); or stabit(s);`,
``,
`PARAMETERS: s - a structure`,
``,
`SYNOPSIS:`,
`- The call stab(s) return the permutation that fixes s. The procedure`,
`  stab generate the set of permutation of Sn, where n is equal to ulcard(s),`,
`  and then check which one fixe s.`,
`- The procedure stabit use nextperm to iteratively figure out which permutations`,
`  fixe s.`,
``,
`EXAMPLE:`,
``,
`> stab(C({1,2},{3,4},{5,6}));`,
``,
`          {[1, 2, 3, 4, 5, 6], [3, 4, 5, 6, 1, 2], [3, 4, 5, 6, 2, 1],`,
``,
`            [3, 4, 6, 5, 1, 2], [3, 4, 6, 5, 2, 1], [1, 2, 3, 4, 6, 5],`,
``,
`            [4, 3, 5, 6, 1, 2], [4, 3, 5, 6, 2, 1], [4, 3, 6, 5, 1, 2],`,
``,
`            [4, 3, 6, 5, 2, 1], [1, 2, 4, 3, 5, 6], [1, 2, 4, 3, 6, 5],`,
``,
`            [2, 1, 4, 3, 6, 5], [2, 1, 4, 3, 5, 6], [2, 1, 3, 4, 6, 5],`,
``,
`            [2, 1, 3, 4, 5, 6], [5, 6, 1, 2, 3, 4], [5, 6, 1, 2, 4, 3],`,
``,
`            [5, 6, 2, 1, 3, 4], [5, 6, 2, 1, 4, 3], [6, 5, 1, 2, 3, 4],`,
``,
`            [6, 5, 1, 2, 4, 3], [6, 5, 2, 1, 3, 4], [6, 5, 2, 1, 4, 3]}`,
` `,
``,
`> stabit([{1,2},{3,4}]);`,
``,
`	 {[2, 1, 3, 4], [1, 2, 4, 3], [2, 1, 4, 3], [1, 2, 3, 4]}`
):

`help/perm/text/stabit`:=`help/text/perm/stab`:

`help/text/perm/grconj` := TEXT(
`FUNCTION: grconj - figure out whether two subsgroup of Sn are conjugated or not`,
``,
`CALLING SEQUENCE:  grconj(H1,H2);`,
``,
`PARAMETERS: H1,H2 - subgroup (set) of Sn`,
``,
`SYNOPSIS:`,
`- Given two subgroup of Sn (for a certain n), this procedure return "true"`,
`  if they are conjugated.`,
`- The permutations in H1 and H2 must be of same length n.`,
`  Rem.: if the stabilizer of two structures s1 and s2 are conjugated, this `,
`        means that the transitive action of Sn on the sets E1=genstract(s1)`,
`        and E2:=genstruct(s2) are isomorphics.`,
``,
`See also: action, regroup, genstruct`,
``,
`EXAMPLE:`,
``,
`> grconj(gensg([[2,1,4,3]],4),gensg([[4,3,2,1]],4));`,
``,
`                    true`,
`# With the line, we calculate a structure obtained by the action of the`,
`# group generated by the permutation [3,4,1,2] on a linear order formed `,
`# by two 2-sets.`,
`> regroup(gensg([[3,4,1,2]],4),[{1,2},{3,4}]);`,
``,
`             {[{1, 2}, {3, 4}], [{3, 4}, {1, 2}]}`,
``,
`# And then, we verify that this structure is in fact a 2-set of 2-sets. `,
`# This mean that the transitive actions of S4 on the sets E1 and E2 formed `,
`# by letting S4 act on the first ans second structures are isomorphics.`,
`> grconj(stab({{1,2},{3,4}}),stab(");`,
``,
`                    true`,
``,
`# The next example show that the action of S5 on the set `,
``,
`		genstruct({{1,5},{1,2},{1,3},{1,4}}) `,
``,
`# is isomorphic to the action on genstruct([1,{2,3,4,5}]). This means`,
`# that (under this action) the star graphs on five vertices are like`,
`# linear order of length 2 in which first element is a point and second`,
`# is a 4-set.`,
`> grconj(stab({{1,5}, {1,2}, {1,3}, {1,4}}),stab([1, {2,3,4,5}]));`,
``,
`			true`,
``
):


`help/perm/text/supp` := TEXT(
`FUNCTION: supp - support of a element of the group algebra of Sn`,
``,
`CALLING SEQUENCE: supp(P);`,
``,
`PARAMETERS: P  - a polynom whose variables are permutations`,
``,
`SYNOPSIS:`,
`- The call supp(P) return a set that contains permutation appearing`,
`  in P.`,
``,
`See also: &X`,
``,
`EXAMPLE:`,
``,
`> supp((1+q)*[2,1,3]+(1+q+q^2)*[3,2,1]+(1+q+q^2+q^3)*[3,1,2]);`,
``,
`                {[2, 1, 3], [3, 1, 2], [3, 2, 1]}`
):

`help/perm/text/&X` := TEXT(
`FUNCTION: &X - multiplication in the group algebra of Sn.`,
``,
`CALLING SEQUENCE: P &X Q;`,
``,
`PARAMETERS: P,Q - polynoms whose variable are permutations`,
``,
`SYNOPSIS:`,
`- This is an implementation of the multiplication in the group algbegra of`,
`  Sn. The polynom have the form  a1*p1 + .. + ak*pk, where p.i is permutation`,
`  in Sn and a.i is coefficients. The coefficients can be integer, strings, `,
`  indexeds, or a sum of these.`,
`- This operation as priority on `+`.`,
``,
`EXAMPLE:`,
``,
`> ((a+b)*[4,3,1,2] + 3*a*b*[1,2,3,4]) &X (6*a*b*[4,3,1,2]+9*a^2*b^2*[1,2,3,4]);`,
``,
`                                             2  2`,         
`     6 (a + b) a b [2, 1, 4, 3] + 9 (a + b) a  b  [4, 3, 1, 2]`,
``,
`                  2  2                    3  3             `,
`            + 18 a  b  [4, 3, 1, 2] + 27 a  b  [1, 2, 3, 4]`,
``
):





`help/perm/text/struct` := TEXT(
`DEFINITION OF STRUCTURES.`,
``,
`  A structure is recursively defined with {},[] or p-structures. A p-structure`,
`  is a structure represented by a procedure (type ?makestruct for details).`,
`  The procedure makestruct can be used to define a p-structure. This is done`,
`  by giving a name for the structure and a stabilizer.`,
``,
`  So, a structure is a call of a form:`,
``,
`              -  {s1,s2,...,sk}`,
``,
`              -  [s1,s2,...,sk]`,
``,
`              -  S(s1,s2,...,sk)`,
``,
`  where S is a p-structure, the s.i are structures or integer.`,
``,
`See also: action, genstruct, makestruct, regroup`,
``,
`Example of structures:`,
``,
`# A linear order of 3-cycles.`,
`> [C(3,2,1),C(4,5,6)];`,
``,
`# The p-structure E2_X3 represents a 2-sets of linear order of length 3.`,
`  makestruct(E2_X3,gensg([[2,1,4,3,6,5]],6));`,
``,
``,
`# A graph.`,
`  {{1,2},{1,3},{1,4},{1,5}}`,
``
):








# save `perm.m`;
# quit;
