print(` Version of April 18, 1997`): print(`This is GJsqfree A Maple package`): print(`that applies the Goulden-Jackson Cluster method,`): print(`as extended and modified by John Noonan and Doron Zeilberger,`): print(`to deal with the enumeration of Square-Free Words.`): lprint(``): print(`Written by John Noonan and Doron Zeilberger.`): lprint(``): print(`It is one of the packages accompanying Noonan and Zeilberger's `): print(`article: "The Goulden-Jackson Cluster Method: Extensions,`): print(`Applications, and Implementations", where the method`): print(`is explained in detail, and then extended and generalized in`): print(`various directions. `): lprint(``): print(`The paper, and the packages, including the present one`): print(`is available from http://www.math.temple.edu/~zeilberg/gj.html`): lprint(``): print(`For general help, and a list of the available functions,`): print(` type "ezra();". For specific help type "ezra(procedure_name)" `): lprint(``): lprint(`Warning: t,s,C,x are global variables, do not use them!`): ezra:=proc() if args=NULL then print(`This is GJsqfree`): print(`A Maple package that applies the Noonan-Zeilberger `): print(`implementation of the Goulden-Jackson Cluster method`): print(` to find series expansions for Square-Free Words`): print(` and pseudo-square-free (i.e. finite-memory)`): print(`For help, and list of procedures type " ezra();" `): lprint(``): print(`Written by John Noonan and Doron Zeilberger`): lprint(``): print(` Contains Procedures `): print(` Series , Zinn `): print(`The main procedure is Series`): print(` For specific help type "ezra(procedure_name)" `): fi: if nops([args])=1 and op(1,[args])=`Zinn` then print(` Zinn's method `): print(`Given an increasing sequence a(n) of positive integers , expressed`): print(`in terms of a list, estimates the theta and mu such that `): print(` a(n) is asympt. to n^(theta)*mu^n. The output is `): print(` theta, mu `): fi: if nops([args])=1 and op(1,[args])=`Series` then print(`Series(MEMO,DIM,NUTERMS): Given the memory, MEMO (a positive `): print(`integer), the number of letters`): print(` DIM, and the number of terms NUTERMS,`): print(`finds the list whose (n+1)^(th) member is the number of words`): print(` of length n, that do not have squares uu, where length(u)<=MEMO`): print(`NUTERMS is the desired number of terms in the list`): fi: if nops([args])=1 and op(1,[args])=`GJ1` then print(`GJ1(DIM,MISTAKES,L) finds the first L terms `): print(`of the sequence: number of words of length 2*DIM, in the alphabet`): print(`\pmDIM, \pm(DIM-1), \pm1 , that avoid`): print(`as factors,`): print(`( i.e. subsequences of consecutive letters) the members of the `): print(`set of lists MISTAKES and its images.`): print(` For example to find the sequence a_n (0<=n<=15)`): print(`where a_n:= wt. numbers of words in {-1,-2,1,2,3} without factors in `): print(` MISTAKES={[1,1],[2,2],[-1,-1],[-2,-2]}. type GJ1(2,{[1,1]},15)`): fi: if nops([args])=1 and op(1,[args])=`Lclust1` then print(`Lclust1(MISTAKES,NUTERMS,DIM): computes the first NUTERMS terms of`): print(`the L-cluster expansion of the g.f. if the set of mistakes is`): print(` MISTAKES where MISTAKES is a set of canonical representatives`): print(`and the actual set of mistakes is the set of all images under`): print(` all signed permutations. For example Lclust1({[1,2]},10,2) `): fi: end: with(combinat): #canon(mila):Given a word in an alphabet of integers, in terms of a list #finds an image under the action of the symmetric group that #is least lexicographically canon:=proc(mila) local i,gu,mu,lu,n: lu:=[1]: mu:=op(1,mila): gu[mu]:=1: n:=2: for i from 2 to nops(mila) do mu:=op(i,mila): if not type(gu[mu],integer) then gu[mu]:=n: n:=n+1: fi: lu:=[op(lu),gu[mu]]: od: lu: end: #khaverim(mila,n):Given a word mila finds the set of all its #images under the action of the group of permutations khaverim:=proc(mila1,n) local i,gu,r,lu,mila,mila2: mila:=canon(mila1): mila2:=[]: for i from 1 to nops(mila) do mila2:=[op(mila2),op(i,mila)]: od: r:=nops(convert(mila2,set)): if nLEN then LEN:=nops(mila): fi: od: for i from 1 to nops(SUFFI) do mila:=op(i,SUFFI): Lt[op(mila)]:=[seq(0,j=1..LEN-nops(mila))]: od: for I1 from 0 to NUTERMS do tot:=0: for i from 1 to nops(SUFFI) do mila:=op(i,SUFFI): x[op(mila)]:=0: od: for i from 1 to nops(MISTAKES) do mila:=op(i,MISTAKES): gu:=0: if nops(mila)=I1 then gu:=-1: fi: for r from 1 to nops(mila)-1 do pref:=canon1([op(1..nops(mila)-r,mila)]): if member(pref,SUFFI) then gu:=gu-op(nops(Lt[op(pref)])-r+1,Lt[op(pref)]): fi: od: for j from 2 to nops(mila) do suffi:=[op(j..nops(mila),mila)]: x[op(suffi)]:=x[op(suffi)]+kapi1[op(mila)] /kapi2[op(suffi)]*gu: od: tot:=tot+kapi1[op(mila)]*gu: od: LIS:=[op(LIS),tot]: for i1 from 1 to nops(SUFFI) do mila:=op(i1,SUFFI): resh:=Lt[op(mila)]: Lt[op(mila)]:=[op(2..nops(resh),resh),x[op(mila)]]: od: od: LIS: end: GJ1:=proc(DIM,MISTAKES,L) local NUMLETTERS,lu,resh,i,gu,t,resh1: NUMLETTERS:=DIM: resh:=Lclust1(MISTAKES,L+2,DIM): lu:=0: for i from 0 to L+1 do lu:=lu+op(i+1,resh)*t^i: od: gu:=1/(1-NUMLETTERS*t-lu): gu:=taylor(gu,t=0,L+1): resh1:=[]: for i from 0 to L do resh1:=[op(resh1),coeff(gu,t,i)]: od: resh1: end: #Series(MEMO,DIM,NUTERMS): Given the memory, MEMO (a positive even #integer), the dimension, DIM, and the number of terms NUTERMS, #finds the list whose (n+1)^(th) member is the number of memory-MEMO #(pseudo-)SAWs in the DIM-dimensional hypercubic lattice . #NUTERMS is the desired number of terms in the list Series:=proc(MEMO,DIM,NUTERMS) local MISTAKES: MISTAKES:=mist(MEMO,DIM) : GJ1(DIM,MISTAKES,NUTERMS): end: kama:=proc(mila,n) local i,r,mila2: mila2:=[]: for i from 1 to nops(mila) do mila2:=[op(mila2),op(i,mila)]: od: r:=nops(convert(mila2,set)): if n