Help:=proc() if args=NULL then print(`Wilfseq.txt -- a maple package to organize data about Wilf classes`): print(` `): print(`contains the procedures:`): print(`SeqsListp(Li,l), SeqsList(Li,l), FLsets(Li), FLrun(Li), FLrunp(Li)`): print(`For help with a specific procedure, type Help(procedure_name)`): fi: if nops([args])=1 and op(1,[args])=SeqsListp then print(`SeqsListp(Li,l): same as SeqsList(Li,l), but`): print(`prints results to screen before returning the two lists`): fi: if nops([args])=1 and op(1,[args])=SeqsList then print(`SeqsList(Li,l): SeqsList(Li,l): inputs a list Li and a positive integer l`): print(`and returns two lists, Seques and repsets`): print(` `): print(`Seques is the list of the first l terms of all sequences of sizes of Wilf classes`): print(`which avoid sets of patterns with one pattern of each size in list Li`): print(` `): print(`repsets[i] returns a representative of each equivalence class (under the dihedral group)`): print(`of permutations with sequence Seques[i]`): print(` `): print(`for example SeqsList([2,3],5) returns`): print(`[[1, 1, 0, 0, 0], [1, 1, 1, 1, 1]], [{{[3, 2, 1], [1, 2]}}, {{[1, 3, 2], [1, 2]}, {[2, 3, 1], [1, 2]}, {[1, 2], [1, 2, 3]}}]`): fi: if nops([args])=1 and op(1,[args])=FLsets then print(`FLsets(Li): given a list of integer permutation lengths, finds all sets of permutations`): print(`with one of each length in the list`): print(`that have one permutation of the form 1,2,...,j,n,j+1,...,n-1`): print(`and one permutation of the form m-1,...,k+1,m,k,...1`): print(`i.e. these are the sets that FINLABEL can enumerate`): fi: if nops([args])=1 and op(1,[args])=FLrun then print(`FLrun(Li): runs FINLABEL on all sets of permutations which have one`): print(`permutation of each length in Li and do not cause FINLABEL to fail `): print(`WARNING: must first load FINLABEL`): fi: if nops([args])=1 and op(1,[args])=FLrunp then print(`FLrump(Li): same as FLrun, but prints info to screen as it runs`): fi: if nops([args])=1 and op(1,[args])=Seqsprint then print(`Seqsprint(n,k,l): same as Seqs(n,k,l), but`): print(`prints results to screen before returning the two lists `): fi: if nops([args])=1 and op(1,[args])=Seqs then print(`Seqs(n,k,l): returns two lists, Seques and repsets`): print(`Seques is the list of the first l terms of all sequences of sizes of Wilf classes`): print(` which avoid exactly k patterns chosen from the permutations on n letters`): print(`repsets[i] returns a representative of each equivalence class (under the dihedral group)`): print(` of permutations with sequence Seques[i]`): print(`for example: Seqs(3,2,5) returns [[1, 2, 4, 8, 16], [1, 2, 4, 7, 11], [1, 2, 4, 4, 0]],`): print(` [{{[1, 2, 3], [1, 3, 2]}, {[1, 3, 2], [2, 1, 3]}, {[1, 3, 2], [2, 3, 1]}}, {{[1, 2, 3], [2, 3, 1]}}, {{[1, 2, 3], [3, 2, 1]}}]`): print(` where the number of permutations of length i avoiding {[1,2,3],[1,3,2]} is 1,2,4,8,16,...., etc.`): fi: if nops([args])=1 and op(1,[args])=ksets then print(`ksets(n,k): returns the set of k-sets of permutations of length n`): print(`put into subsets via dihedral action equivalence`): fi: if nops([args])=1 and op(1,[args])=lsets then print(`lsets(Li): the set of sets of permutations with one permutation`): print(`of length equal to each list entry`): print(`e.g. lsets([3,4]) returns all sets of a permutation of length 3`): print(`and a permutation of length 4`): fi: if nops([args])=1 and op(1,[args])=lSymm then print(`lSymm(n): the set of all symmetry classes of Sn under the dihedral group`): print(`for example: lSymm(3) returns {{[1,3,2],[2,1,3],[2,3,1],[3,1,2]},{[1,2,3],[3,2,1]}}`): fi: if nops([args])=1 and op(1,[args])=opposset then print(`opposset(permset): the opposite of each permutation in permset`): fi: if nops([args])=1 and op(1,[args])=reversset then print(`reversset(permset): The reverse of each permutation in permset`): fi: if nops([args])=1 and op(1,[args])=inversset then print(`inversset(permset): The inverse of each permutation in permset`): fi: if nops([args])=1 and op(1,[args])=khaverimset then print(`khaverimset(permet): all the images of the permutation permset`): print(`under the group generated by reversal, opposite, and inverse`): fi: if nops([args])=1 and op(1,[args])=oppos then print(`oppos(perm): The opposite of a permutation`): print(`for example: oppos([3,2,4,1]) returns [2,3,1,4]`): fi: if nops([args])=1 and op(1,[args])=revers then print(`revers(perm): The reverse of a permutation`): print(`for example: invers([3,2,4,1]) returns [1,4,2,3]`): fi: if nops([args])=1 and op(1,[args])=invers then print(`invers(perm): the inverse of a permutation`): print(`for example: invers([3,2,4,1]) returns [4,2,1,3]`): fi: end: with(combinat): with(ListTools): writeBook:=proc(Li,seql) local L, L2,n,n2,i,dat,S,j,p,k,FL,tot,Rej: L:=lsets(Li): n:=nops(L): L2:={}: for i from 1 to nops(L) do L2:=L2 union L[i]: od: n2:=nops(L2): print("This is a systematic study of permutations avoiding ", Li, "pattern sets:"): print("There are ", n2 , "pattern sets in all"): print("They can be trivially divided into", n," symmetry classes"): print(): print("sorting sets with FINLABEL............"): L:=FLsort(Li): print(): print("sorting sets with WILF (SchemeF)............"): dat:=Wilfsort(Li, seql): print("------------------------------------------------------"): S:={}: j:=0: for i from 1 to nops(L) do S:=S union {L[i][2]}: od: if S={"no generating function"} then print("no symmetry classes were counted by FINLABEL"): else print("symmetry classes counted with FINLABEL:"): for i from 1 to nops(S) do if (type(S[i], algebraic)) then print("------------------------------------------------------"): print("generating function:", S[i]): print("sequence to 30 terms: ", seq(coeftayl(S[i], x=0, m),m=1..30)): print("symmetry classes with this sequence are: "): p:=0: for k from 1 to nops(L) do if L[k][2]=S[i] then print(L[k][1]): p:=p+1: fi: od: print("there are ", p, " such symmetry classes"): fi: od: fi: print("------------------------------------------------------"): print("symmetry classes counted with WILF (SchemeF):"): L:=dat[1]: FL:=dat[2]: tot:=dat[3]: S:={}: j:=0: for i from 1 to nops(L) do S:=S union {L[i][2]}: od: print(S): for i from 1 to nops(S) do if (type(S[i], list)) then print("------------------------------------------------------"): print("sequence to ", seql, " terms:", S[i]): print("symmetry classes with this sequence are: "): p:=0: for k from 1 to nops(L) do if L[k][2]=S[i] then print(L[k][1]): p:=p+1: fi: od: print("there are ", p, " such symmetry classes"): print(" "): else Rej:=S[i]: fi: od: print( ): print("------------------------------------------------------"): print("symmetry classes uncounted by FINLABEL and WILF (SchemeF):"): for k from 1 to nops(L) do if L[k][2]=Rej then print(L[k][1]): j:=j+1: fi: od: print("there are ", j, " such symmetry classes"): print(" "): print("------------------------------------------------------"): print("summarizing results for ", Li, " pattern sets"): print("there are ", tot, " symmetry classes in all"): print(FL, "of them can be counted by FINLABEL"): print("that's ", evalf((FL*100)/tot), "%"): print("of the remaining ones", nops(L)-j, "of them can be counted by WILF (SchemeF)"): print("that's ", evalf(((nops(L)-j)*100)/tot), "%"): print("thus ", evalf((((nops(L)-j)+FL)*100)/tot), "% of the total symmetry classes can be counted by either FINLABEL or WILF (SchemeF)"): end: #inputs Li and sequence length Wilfprettyprint:=proc(Li, seql) local L, S, i, p, k, j, dat, FL, tot: dat:=Wilfsort(Li, seql): L:=dat[1]: FL:=dat[2]: tot:=dat[3]: S:={}: j:=0: for i from 1 to nops(L) do S:=S union {L[i][2]}: od: for i from 1 to nops(S) do if (type(S[i], list)) then print("sequence to 30 terms:", S[i]): print("symmetry classes with this sequence are: "): p:=0: for k from 1 to nops(L) do if L[k][2]=S[i] then print(L[k][1]): p:=p+1: fi: od: print("there are ", p, " such symmetry classes"): print(" "): else print("symmetry classes with no scheme from WILFPLUS"): for k from 1 to nops(L) do if L[k][2]=S[i] then print(L[k][1]): j:=j+1: fi: od: print(" "): fi: od: print("summarizing results for ", Li, " pattern sets"): print("there are ", tot, " symmetry classes in all"): print(FL, "of them can be counted by FINLABEL"): print("that's ", (FL*100)/tot, "%"): print("of the remaining ones", nops(L)-j, "of them can be counted by WILFPLUS"): print("that's ", ((nops(L)-j)*100)/tot, "%"): print("thus ", (((nops(L)-j)+FL)*100)/tot, "% of the total symmetry classes can be counted by either FINLABEL or WILFPLUS"): end: FLprettyprint:=proc(Li) local L, S, j, i, p, k, m: print("testing ", Li, " sets..."): L:=FLsort(Li): S:={}: j:=0: for i from 1 to nops(L) do S:=S union {L[i][2]}: od: for i from 1 to nops(S) do print("generating function:", S[i]): if (type(S[i], algebraic)) then print("sequence to 30 terms: ", seq(coeftayl(S[i], x=0, m),m=1..30)): print("symmetry classes with this sequence are: "): p:=0: for k from 1 to nops(L) do if L[k][2]=S[i] then print(L[k][1]): p:=p+1: fi: od: print("there are ", p, " such symmetry classes"): else print("symmetry classes with no generating function from FINLABEL"): for k from 1 to nops(L) do if L[k][2]=S[i] then print(L[k][1]): j:=j+1: fi: od: fi: od: print("summarizing results for ", Li, " pattern sets"): print("there are ", nops(L), " symmetry classes in all"): print(nops(L)-j, "of them can be counted by FINLABEL"): print("that's ", ((nops(L)-j)*100)/nops(L), "%"): end: FLprettyprint2:=proc(Li) local L, S, j, i, p, k, m: L:=FLsort(Li): S:={}: j:=0: for i from 1 to nops(L) do S:=S union {L[i][2]}: od: for i from 1 to nops(S) do if (type(S[i], algebraic)) then print("------------------------------------------------------"): print("generating function:", S[i]): print("sequence to 30 terms: ", seq(coeftayl(S[i], x=0, m),m=1..30)): print("symmetry classes with this sequence are: "): p:=0: for k from 1 to nops(L) do if L[k][2]=S[i] then print(L[k][1]): p:=p+1: fi: od: print("there are ", p, " such symmetry classes"): fi: od: end: #Wilfsort(Li): runs WILFPLUS on all sets of permutations which have one #permutation of each length in Li and do not cause FINLABEL to fail #WARNING: must first load FINLABEL Wilfsort:=proc(Li,seql) local i, L, R, S, Results, AL, currclass, listed, temp, curr, Rep, FL, tot: AL:=lsets(Li): #print("AL", AL): L:=FLsets(Li): #print("L", L): Rep:={}: while(L<>{}) do Rep:=Rep union {khaverimset(L[1])}: L:=L minus khaverimset(L[1]): od: #print("rep", Rep): FL:=nops(Rep): tot:=nops(AL): AL:=AL minus Rep: Results:={}: for i from 1 to nops(AL) do currclass:=AL[i]: # print("currclass", currclass): temp:=currclass: listed:=false: while (temp<>{}) and (not listed) do curr:=temp[1]: # print("curr", curr): temp:=temp minus {curr}: R:=SchemeF(curr,6): if R<>0 then S:=[seq(Miklos(i,R[3]),i=1..seql)]: fi: listed:=true: od: if R=0 then Results:=Results union {[currclass,"no scheme found"]}: else Results:=Results union {[currclass,S]}: fi: od: Results, FL, tot: end: #FLrun(Li): runs FINLABEL on all sets of permutations which have one #permutation of each length in Li and do not cause FINLABEL to fail #WARNING: must first load FINLABEL FLsort:=proc(Li) local i, L, R, f, Results, AL, currclass, listed, temp, curr: AL:=lsets(Li): #print("AL", AL): L:=FLsets(Li): #print("L", L): Results:={}: for i from 1 to nops(AL) do currclass:=AL[i]: # print("currclass", currclass): temp:=currclass: listed:=false: while (temp<>{}) and (not listed) do curr:=temp[1]: # print("curr", curr): if member(curr,L) then if (member([1,2,3,4], curr)) and (member([4,3,2,1], curr)) then temp:=temp minus {curr}: else R:=finlabel(curr): f:=rules2gf(R,x): listed:=true: fi: else temp:=temp minus {curr}: fi: od: if (not listed) then Results:=Results union {[currclass,"no generating function"]}: else Results:=Results union {[currclass,f]}: fi: od: Results: end: #FLrun(Li): runs FINLABEL on all sets of permutations which have one #permutation of each length in Li and do not cause FINLABEL to fail #WARNING: must first load FINLABEL FLrun:=proc(Li) local i, L, R, f, Results: L:=FLsets(Li): Results:={}: for i from 1 to nops(L) do R:=finlabel(L[i]): f:=rules2gf(R,x): Results:=Results union {[L[i],f]}: od: Results: end: #FLrunp(Li): same as FLrun, but prints info to screen as it runs FLrunp:=proc(Li) local i, L, R, f, Results: L:=FLsets(Li): Results:={}: for i from 1 to nops(L) do R:=finlabel(L[i][1]): f:=rules2gf(R,x): print("generating function for avoiding ", L[i], " is ", f): Results:=Results union {[L[i][1],f]}: od: Results: end: #SeqsListp(Li,l): same as SeqsList(Li,l), but #prints results to screen before returning the two lists SeqsListp:=proc(Li,l) local L, Seques, Reps, i ,j: L:=SeqsList(Li,l): Seques:=L[1]: Reps:=L[2]: for i from 1 to nops(Seques) do: lprint(`Permutations with the sequence `, op(Seques[i])): for j from 1 to nops(Reps[i]) do print(khaverimset(Reps[i][j])): od: od: return(Seques, Reps): end: #SeqsList(Li,l): Seqs(Li,l): returns two lists, Seques and repsets #Seques is the list of the first l terms of all sequences of sizes of Wilf classes #which avoid sets of patterns with one pattern of each size in list Li #repsets[i] returns a representative of each equivalence class (under the dihedral group) #of permutations with sequence Seques[i] SeqsList:=proc(Li,l) local Rep, i, j, Seqs, se, repsets, saved, m: Rep:=lsets(Li): Seqs:=[]: repsets:=[]: for i from 1 to nops(Rep) do se:=seq(nops(Wilf(j,Rep[i][1])),j=1..l): saved:=false: for m from 1 to nops(Seqs) do if evalb([se] = Seqs[m]) then repsets[m]:=repsets[m] union {Rep[i][1]}: saved:=true: fi: od: if not saved then repsets:=[op(repsets), {Rep[i][1]}]: Seqs:=[op(Seqs), [se]]: fi: if nops(Seqs) = 0 then repsets:=[{Rep[i][1]}]: Seqs:=[op(Seqs), [se]]: fi: od: Seqs, repsets: end: #Seqsprint(n,k,l): same as Seqs(n,k,l), but #prints results to screen before returning the two lists Seqsprint:=proc(n,k,l) local L, Seques, Reps, i ,j: L:=Seqs(n,k,l): Seques:=L[1]: Reps:=L[2]: for i from 1 to nops(Seques) do: lprint(`Permutations with the sequence `, op(Seques[i])): for j from 1 to nops(Reps[i]) do print(khaverimset(Reps[i][j])): od: od: return(Seques, Reps): end: #Seqs(n,k,l): Seqs(n,k,l): returns two lists, Seques and repsets #Seques is the list of the first l terms of all sequences of sizes of Wilf classes #which avoid exactly k patterns chosen from the permutations on n letters #repsets[i] returns a representative of each equivalence class (under the dihedral group) #of permutations with sequence Seques[i] Seqs:=proc(n,k,l) local Rep, i, j, Seqs, se, repsets, saved, m: Rep:=ksets(n,k): Seqs:=[]: repsets:=[]: for i from 1 to nops(Rep) do se:=seq(nops(Wilf(j,Rep[i][1])),j=1..l): saved:=false: for m from 1 to nops(Seqs) do if evalb([se] = Seqs[m]) then repsets[m]:=repsets[m] union {Rep[i][1]}: saved:=true: fi: od: if not saved then repsets:=[op(repsets), {Rep[i][1]}]: Seqs:=[op(Seqs), [se]]: fi: if nops(Seqs) = 0 then repsets:=[{Rep[i][1]}]: Seqs:=[op(Seqs), [se]]: fi: od: Seqs, repsets: end: #ksets(n,k): returns the set of k-sets of permutations of length n #put into subsets via dihedral action equivalence ksets:=proc(n,k) local P, P1, i, j, Rep: P:={op(permute(n))}: Rep:={}: P1:=choose(P,k): while(P1<>{}) do Rep:=Rep union {khaverimset(P1[1])}: P1:=P1 minus khaverimset(P1[1]): od: Rep: end: #lsets(Li): the set of sets of permutations with one permutation #of length equal to each list entry #e.g. lsets([3,4]) returns all sets of a permutation of length 3 #and a permutation of length 4 lsets:=proc(Li) local Psub, i, P, j, Ptemp, k, Rep: for i from 1 to nops(Li) do Psub[i]:={op(permute(Li[i]))}: od: P:={{}}: Ptemp:={}: for i from 1 to nops(Li) do for j from 1 to nops(P) do for k from 1 to nops(Psub[i]) do Ptemp:=Ptemp union {P[j] union {Psub[i][k]}}: od: od: P:=Ptemp: Ptemp:={}: od: Ptemp:=P: P:={}: for i from 1 to nops(Ptemp) do if nops(Ptemp[i]) = nops(Li) then P:=P union {Ptemp[i]}: fi: od: Rep:={}: Ptemp:=P: while(Ptemp<>{}) do Rep:=Rep union {khaverimset(Ptemp[1])}: Ptemp:=Ptemp minus khaverimset(Ptemp[1]): od: Rep: end: #lsets1(Li): the set of sets of permutations with one permutation #of length equal to each list entry #e.g. lsets([3,4]) returns all sets of a permutation of length 3 #and a permutation of length 4 lsets1:=proc(Li) local Psub, i, P, j, Ptemp, k, Rep: for i from 1 to nops(Li) do Psub[i]:={op(permute(Li[i]))}: od: P:={{}}: Ptemp:={}: for i from 1 to nops(Li) do for j from 1 to nops(P) do for k from 1 to nops(Psub[i]) do Ptemp:=Ptemp union {P[j] union {Psub[i][k]}}: od: od: P:=Ptemp: Ptemp:={}: od: Ptemp:=P: P:={}: for i from 1 to nops(Ptemp) do if nops(Ptemp[i]) = nops(Li) then P:=P union {Ptemp[i]}: fi: od: P: end: #FLsets(Li): given a list of integer permutation lengths, finds all sets of permutations #with one of each length in the list #that have one permutation of the form 1,2,...,j,n,j+1,...,n-1 #and one permutation of the form m-1,...,k+1,m,k,...1 #i.e. these are the sets that FINLABEL can enumerate FLsets:=proc(Li) local nums, p1, p2, i, j, k, numsr, S, l, notdeleted, Others, P, Ptemp, m, n: if (nops(Li)=1) then RETURN({}): fi: P:={}: nums:={op(choose(Li,2))}: numsr:={}: for i from 1 to nops(nums) do numsr:=numsr union {Reverse(nums[i])}: od: nums:=nums union numsr: for i from 1 to nops(nums) do for j from 0 to nums[i][1]-1 do for k from 0 to nums[i][2]-1 do if (j>0) then p1:=[seq(m,m=1..j), nums[i][1], seq(m,m=j+1..nums[i][1]-1)]: else p1:=[nums[i][1], seq(m,m=1..nums[i][1]-1)]: fi: if (k>0) then p2:=[op(Reverse([seq(n,n=k+1..nums[i][2]-1)])), nums[i][2], op(Reverse([seq(n,n=1..k)]))]: else p2:=[op(Reverse([seq(n,n=1..nums[i][2]-1)])), nums[i][2]]: fi: S:=Li: notdeleted:=true: l:=1: while notdeleted do: if S[l]= nums[i][1] then S:=[op(1..l-1, S), op(l+1..nops(S),S)]: notdeleted:=false: else l:=l+1: fi: od: notdeleted:=true: l:=1: while notdeleted do: if S[l]= nums[i][2] then S:=[op(1..l-1, S), op(l+1..nops(S),S)]: notdeleted:=false: else l:=l+1: fi: od: #now S is the set of sizes that we haven't already made a permutation for Others:=lsets1(S): for l from 1 to nops(Others) do P:=P union {{op(Others[l]), p1, p2}}: od: od: od: od: Ptemp:=P: P:={}: for i from 1 to nops(Ptemp) do if nops(Ptemp[i]) = nops(Li) then P:=P union {Ptemp[i]}: fi: od: P: end: #lSymm(n): the set of all symmetry classes of Sn under the dihedral group lSymm:=proc(n) local P, Rep, i, P1: P:={op(permute(n))}: Rep:={}: P1:=P: while (P1<>{}) do Rep:=Rep union {khaverim(P1[1])}: P1:=P1 minus khaverim(P1[1]): od: Rep: end: #################functions modified from WILF package khaverimset:=proc(permset) {permset, opposset(permset),reversset(permset),opposset(reversset(permset)), inversset(permset), opposset(inversset(permset)), reversset(inversset(permset)), opposset(reversset(inversset(permset)))}: end: opposset:=proc(permset) local reps, i: reps:={}: for i from 1 to nops(permset) do reps:=reps union {oppos(permset[i])}: od: reps: end: reversset:=proc(permset) local reps, i: reps:={}: for i from 1 to nops(permset) do reps:=reps union {revers(permset[i])}: od: reps: end: inversset:=proc(permset) local reps, i: reps:={}: for i from 1 to nops(permset) do reps:=reps union {invers(permset[i])}: od: reps: end: #oppos(perm): The opposite of a permutation oppos:=proc(perm) local i: [seq(nops(perm)+1-perm[i],i=1..nops(perm))]: end: #revers(perm): The reverse of a permutation revers:=proc(perm) local i: [seq(perm[nops(perm)-i+1],i=1..nops(perm))]: end: #invers(perm): the inverse of a permutation invers:=proc(perm) local i, a: for i from 1 to nops(perm) do a[perm[i]]:=i: od: [seq(a[i],i=1..nops(perm))]: end: #################functions copied from WILF package #Wilf(n,Patterns): all permutations of length n #that avoid the patterns in the set of patterns #Patterns Wilf:=proc(n,Patterns) local i,mu,gu,pi,j,muamad: option remember: if n=0 then RETURN({[]}): fi: mu:=Wilf(n-1,Patterns): gu:={}: for i from 1 to nops(mu) do pi:=op(i,mu): for j from 1 to n do muamad:=Insert(pi,j): if member(redu([op(2..n,muamad)]),mu) then if good(muamad,Patterns)=1 then gu:=gu union {muamad}: fi: fi: od: od: gu: end: #Insert(pi,i): Given a permutation pi, and an integer #i between 1 and nops(pi)+1, constructs the permutation #of length nops(pi)+1 whose last entry is i, and such that #reduced form of the first nops(pi) letters is pi Insert:=proc(pi,i) local mu,j: mu:=[]: for j from 1 to nops(pi) do if pi[j]n then RETURN(1): fi: gu:=IV(n,k-2): for i from 1 to nops(gu) do vec:=op(i,gu): subperm:=[op(1,pi)]: for j from 1 to k-2 do subperm:=[op(subperm),pi[vec[j]]]: od: subperm:=[op(subperm),pi[n]]: if redu(subperm)=pattern1 then RETURN(0): fi: od: 1: end: #IV(n,k) all increasing vectors of length #k of the form 1<=i_1< ...