print(` Version of April 18, 1997.`): print(`This is BLANKS, A Maple package,`): print(`written J. Noonan and D. Zeilberger, zeilberg@math.temple.edu .`): print(`It implements their extension to words with Blanks of`): print(` their previous extension of D. Jackson and`): print(` I. Goulden's Cluster method.`): lprint(``): print(`This package is one of the packages accompanying their paper:`): print(`The Goulden-Jackson method: Extensions, Applications and`): print(`Implementation.`): lprint(` The packages and paper may be obtained from`): print(` http://www.math.temple.edu/~zeilberg/gj.html`): lprint(``): print(`In this extension, one also considers non-consecutive mistakes`): print(`indicated by blanks, B.`): print(`In addition, like in JODO`): print(` one counts words according to their number`): print(`of mistakes, but NOW minimality is not assumed, so both`): print(`DONKEY and DONKEYHOLE can occur, and the weight of ADONKEYHOLES`): print(`is t^2, one because of DONKEY and one because of DONKEYHOLE.`): 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!`): lprint(``): lprint(`Please report bugs to: zeilberg@math.temple.edu`): ezra:=proc() if args=NULL then print(`BLANKS, A Maple package that implements the Noonan-Zeilberger `): print(` extension of the Goulden-Jacskon L-cluster method`): print(` for finding generating functions and series exapansions`): print(`for the number of words avoiding a prescribed, finite, set of`): print(`"mistakes", that may not be minimal, and with blanks.`): print(` Contains Procedures: BLANKS,BLANKSxt, BLANKSst,BLANKSs0,BLANKSseries`): print(` For specific help type "ezra(procedure_name)" `): fi: if nops([args])=1 and op(1,[args])=`BLANKS` then print(`BLANKS(alphabet,B,MISTAKES):Given a set of letters`): print(` alphabet, and a set`): print(`of words labelled MISTAKES (with no restriction of minimality`): print(`and allowing blanks, denoted by B,`): print(`finds the generating function, i.e. weight enumerator, of all`): print(`words in the alphabet according to the weight`): print(`Product x[letter] Product [mistake], where the first product extends`): print(`over all the letters of the word and the second product extends over`): print(`all factors of the word that belongs to MISTAKES`): print(`For example BLANKS({1,2},B,{[1,2,1],[2,1,2],[2,1],[1,2],[1,B,1]})`): print(`after it is`): print(`taylored, should be 1+x[1]+x[2]+x[1]*x[2]*(t[1,2]+t[2,1]) +`): print(`x[1]^3*t[1,B,1]+x[1]^2*x[2]*(t[1,2]*t[2,1]*t[1,2,1]*t[1,B,1]+...1`): fi: if nops([args])=1 and op(1,[args])=`BLANKSseries` then print(`BLANKSseries(alphabet,B,MISTAKES,L):Given an alphabet alphabet,`): print(` and a set`): print(`of words labelled MISTAKES (with no restriction of minimality`): print(`and allowing blanks, denoted by B,`): print(`finds the list, up to L, of a_n:= number of good words`): print(`E.g. BLANKSseries({1,2},B,{[1,2,1],[2,1,2],[2,1],[1,2],[1,B,1]},9).`): fi: if nops([args])=1 and op(1,[args])=`solser` then print(`solser(vars,pols,equs,T,L): Given a system of eqations of the form`): print(`a[i](s)=p[i](s)+ \sum_{j=1}^{n} P[i,j](s) a[j](s), finds the series `): print(`expansion of sum_{i \in T} a[i], where T is a subset of vars.`): print(`The inputs are the list of a[i] , vars, the corresponding`): print(` list pols, of the p[i]'s, the list of expressions`): print(` \sum_{j=1}^{n} P[i,j](s) a[j](s), the above-mentioned `): print(`subset T, and the expansion should be up to the L's term`): fi: if nops([args])=1 and op(1,[args])=`BLANKSxt` then print(`BLANKSxt(alphabet,B,MISTAKES):Given an alphabet alphabet, and a set`): print(`of words labelled MISTAKES (with no restriction of minimality),`): print(`finds the generating function, i.e. weight enumerator, of all`): print(`words in the alphabet according to the weight, weight(word)`): print(`Product x[letter] *t^(#mistakes) where the product extends`): print(`over all the letters and #mistkes is the number of`): print(` factors of the word that belongs to MISTAKES`): print(` BLANKSxt({1,2},B,{[1,2,1],[2,1,2],[2,1],[1,2]}), after it is`): print(`taylored, should be 1+x[1]+x[2]+2*t*x[1]*x[2] +...`): fi: if nops([args])=1 and op(1,[args])=`BLANKSst` then print(`BLANKSst(alphabet,B,MISTAKES):Given an alphabet alphabet, and a set`): print(`of words labelled MISTAKES (with no restriction of minimality),`): print(`finds the generating function, i.e. weight enumerator, of all`): print(`words in the alphabet according to the weight, weight(word)`): print(`Product s^(#letters) *t^(#mistakes) where the product extends`): print(`over all the letters and #mistkes is the number of`): print(` factors of the word that belongs to MISTAKES`): print(`For example BLANKSst({1,2},B,{[1,2,1],[2,1,2],[2,1],[1,2]}), `): print(` after it is taylored, should be 1+2*s+(2+2*t)*s^2 +...`): fi: if nops([args])=1 and op(1,[args])=`BLANKSs0` then print(`BLANKSs0(alphabet,B,MISTAKES):Given an alphabet alphabet, and a set`): print(`of words labelled MISTAKES (with no restriction of minimality),`): print(`finds the generating function, i.e. weight enumerator, of all`): print(`words in the alphabet according to the weight, weight(word)`): print(`Product s^(#letters) *t^(#mistakes) where the product extends`): print(`over all the letters and #mistkes is the number of`): print(` factors of the word that belongs to MISTAKES`): print(`For example BLANKSs0([1,2],B,[[1,2,1],[2,1,2],[2,1],[1,2]]), after it is`): print(`taylored, should be 1+2*s+(2)*s^2 +...`): fi: end: #mekhil(u) checks whether u has components that have = in them mekhil:=proc(u) local i: for i from 1 to nops(u) do if type(op(i,u),`=`) then RETURN(1): fi: od: 0: end: #split1(u): given a generalized word, some of whose components have #the form B=a, where B denotes `blank', outputs the original mistake #with the B's, and the specialized word with the B=a's replaced by a's #for example split1([1,B=2,B,2]) yields [1,B,B,2],[1,2,B,2] split1:=proc(u,B) local i,u1,u2,ot1: u1:=[]: u2:=[]: for i from 1 to nops(u) do ot1:=op(i,u): if type(ot1,`=`) then u1:=[op(u1),B]: u2:=[op(u2),op(2,ot1)]: else u1:=[op(u1),ot1]: u2:=[op(u2),ot1]: fi: od: u1,u2: end: #Given two words, in the alphabet alphabet union {B} #outputs 0 if they are not compatible and it outputs the derived #word with B=letters in the appropiate places compat:=proc(u,v,B) local w,i,otu,otv: if nops(u)<>nops(v) then ERROR(`u and v must be of the same length`): fi: w:=[]: for i from 1 to nops(u) do otu:=op(i,u): otv:=op(i,v): if otv<>otu and otv<>B and otu<>B then RETURN(0): fi: if otv=otu or otv=B then w:=[op(w),otu]: fi: if otu=B and otv<>B then w:=[op(w),B=otv]: fi: od: w: end: #Equik(u,v,i): Given a genuine mistake v, and another mistake under it #such that the 1'st letter of u coincides with the i-th letter of v #finds the term that corresponds to this situation in the Equation #for C[v], and the second component is the new generalized mistake if present Equik:=proc(u,v,i,B,alphabet) local u1,v1,lu: if i<1 or i>nops(v) then ERROR(`1<=i<=nops(v)`): fi: if nops(v)=i then if nops(u)<=nops(v) then RETURN(0,{}): fi: u1:=[op(nops(u)-i+1..nops(u),u)]: if compat(u1,v,B)=0 then RETURN(0,{}): else lu:=[op(1..nops(u)-i,u),op(compat(u1,v,B))]: if mekhil(lu)=0 then RETURN((t[op(v)]-1)*C[op(u)],{}): else RETURN((t[op(v)]-1)*C[op(lu)],{lu}): fi: fi: fi: if nops(u)=i then v1:=[op(1..i,v)]: u1:=[op(nops(u)-i+1..nops(u),u)]: lu:=compat(u1,v1,B): if lu=0 then RETURN(0,{}): else if mekhil(lu)=0 then RETURN((t[op(v)]-1)*weight([op(i+1..nops(v),v)],B,alphabet)*C[op(u)],{}): else RETURN((t[op(v)]-1)*weight([op(i+1..nops(v),v)],B,alphabet)* C[op(1..nops(u)-i,u),op(lu)] ,{[op(1..nops(u)-i,u),op(lu)] }): fi: fi: fi: end: #Equi1k(u,v,i): Given a generalized mistake of the form v=[v1,v2], #and another genuine mistake u under it #such that the last letter of u coincides with the i-th #letter of vt:=[op(v1),op(v2)] #finds the term that corresponds to this situation in the Equation #for C[v], this is the first component. The second component is the #possible new generalized mistake Equi1k:=proc(u,v,i,B,alphabet) local v1,v2,v2ka,v2true,v2spec,vt,u1,lu,V1: v1:=op(1,v): v2:=op(2,v): v2ka:=split1(v2,B): v2true:=v2ka[1]: v2spec:=v2ka[2]: if not type(v1,list) or not type(v2,list) then ERROR(`Something is wrong`): fi: vt:=[op(v1),op(v2spec)]: if i<1 or i>nops(vt) then ERROR(`1<=i<=nops(v1)+nops(v2)`): fi: if nops(vt)=i then if nops(u)<=nops(v2) then RETURN(0,{}): fi: if nops(u)>nops(v2) and nops(u)=i then V1:=[op(1..i,vt)]: u1:=[op(nops(u)-i+1..nops(u),u)]: lu:=compat(u1,V1,B): if lu=0 then RETURN(0,{}): else if mekhil(lu)=0 then RETURN((t[op(v2true)]-1)* weight([op(i+1..nops(vt),vt)],B,alphabet)*C[op(u)],{}): else RETURN((t[op(v2true)]-1)*weight([op(i+1..nops(vt),vt)],B,alphabet)* C[op(1..nops(u)-i,u),op(lu)] ,{[op(1..nops(u)-i,u),op(lu)] }): fi: fi: fi: end: #Equi2k(u,v,i): Given a generalized mistake v, with some #components of the form B=a #and another genuine mistake u under it #such that the last letter of u coincides with the i-th letter of v #finds the term that corresponds to this situation in the Equation #for C[v], this is the first component. The second component is the #possible new generalized mistake Equi2k:=proc(u,v,i,B,alphabet) local v2ka,v2true,v2spec,vt,u1,lu,V1: v2ka:=split1(v,B): v2true:=v2ka[1]: v2spec:=v2ka[2]: if mekhil(v)=0 then ERROR(`Something is wrong`): fi: vt:=v2spec: if i<1 or i>nops(vt) then ERROR(`1<=i<=nops(v)`): fi: if nops(vt)=i then if nops(u)<=nops(v) then RETURN(0,{}): fi: u1:=[op(nops(u)-i+1..nops(u),u)]: if compat(u1,vt,B)=0 then RETURN(0,{}): else lu:=[op(1..nops(u)-i,u),op(compat(u1,vt,B))]: if mekhil(lu)=0 then RETURN((t[op(v2true)]-1)*C[op(u)],{}): else RETURN((t[op(v2true)]-1)*C[op(lu)],{lu}): fi: fi: fi: if nops(u)=i then V1:=[op(1..i,vt)]: u1:=[op(nops(u)-i+1..nops(u),u)]: lu:=compat(u1,V1,B): if lu=0 then RETURN(0,{}): else if mekhil(lu)=0 then RETURN((t[op(v2true)]-1)* weight([op(i+1..nops(vt),vt)],B,alphabet)*C[op(u)],{}): else RETURN((t[op(v2true)]-1)*weight([op(i+1..nops(vt),vt)],B,alphabet)* C[op(1..nops(u)-i,u),op(lu)] ,{[op(1..nops(u)-i,u),op(lu)] }): fi: fi: fi: end: #Equk(v): gives the equation corresponding to the genuine mistake #v being at the top and the list of new generalized mistakes Equk:=proc(v,MISTAKES,B,alphabet) local u,i,j,gu,NEWMIS: NEWMIS:={}: gu:=C[op(v)]-weight(v,B,alphabet)*(t[op(v)]-1): for j from 1 to nops(MISTAKES) do u:=op(j,MISTAKES): for i from 1 to nops(v) do tempka:=Equik(u,v,i,B,alphabet): gu:=gu-tempka[1]: NEWMIS:=NEWMIS union tempka[2]: od: od: gu,NEWMIS: end: #Equ1k(v): gives the equation corresponding to the generalized mistake #v being at the top, and the set of new generalized mistakes produced Equ1k:=proc(v,MISTAKES,B,alphabet) local v1,v2,v2true,v2spec,vt,u,i,j,gu,NEWMIS,tempka,pak: NEWMIS:={}: v1:=op(1,v): v2:=op(2,v): pak:= split1(v2,B): v2true:=pak[1]: v2spec:=pak[2]: vt:=[op(v1),op(v2spec)]: gu:=C[op(v)]-weight(vt,B,alphabet)*(t[op(v2true)]-1): for j from 1 to nops(MISTAKES) do u:=op(j,MISTAKES): for i from 1 to nops(vt) do tempka:=Equi1k(u,v,i,B,alphabet): gu:=gu-tempka[1]: NEWMIS:=NEWMIS union tempka[2]: od: od: gu,NEWMIS: end: Equ2k:=proc(v,MISTAKES,B,alphabet) local v2true,v2spec,pak,u,i,j,gu,NEWMIS,tempka: NEWMIS:={}: pak:=split1(v,B): v2true:=pak[1]: v2spec:=pak[2]: gu:=C[op(v)]-weight(v2spec,B,alphabet)*(t[op(v2true)]-1): for j from 1 to nops(MISTAKES) do u:=op(j,MISTAKES): for i from 1 to nops(v) do tempka:=Equi2k(u,v,i,B,alphabet): gu:=gu-tempka[1]: NEWMIS:=NEWMIS union tempka[2]: od: od: gu,NEWMIS: end: BLANKS:=proc(alphabet,B,MISTAKES1) local gu,i,v,eq,var,GENMIS,MISTAKES,GENMISdone,tempka: MISTAKES:=convert(convert(MISTAKES1,set),list): GENMIS:={}: var:={}: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): var:=var union {C[op(v)]}: od: eq:={}: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): tempka:=Equk(v,MISTAKES,B,alphabet): eq:=eq union {tempka[1]}: GENMIS:=GENMIS union tempka[2]: od: GENMISdone:={}: while nops(GENMIS)-nops(GENMISdone)>0 do v:=op(1,GENMIS minus GENMISdone): GENMISdone:=GENMISdone union {v}: if nops(v)=2 and type(op(1,v),list) then tempka:=Equ1k(v,MISTAKES,B,alphabet): eq:=eq union {tempka[1]}: GENMIS:=GENMIS union tempka[2]: else tempka:=Equ2k(v,MISTAKES,B,alphabet): eq:=eq union {tempka[1]}: GENMIS:=GENMIS union tempka[2]: fi: od: for i from 1 to nops(GENMIS) do v:=op(i,GENMIS): var:=var union {C[op(v)]}: od: var:=solve(eq,var): gu:=1: for i from 1 to nops(alphabet) do gu:=gu-x[op(i,alphabet)]: od: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): gu:=gu-subs(var,C[op(v)]): od: normal(1/gu): end: #weight(u,B,alphabet) gives the weight of a word u weight:=proc(u,B,alphabet) local gu,i,mu: if mekhil(u,B)=1 then ERROR(`In weight, input u is not a proper word`): fi: mu:=0: for i from 1 to nops(alphabet) do mu:=mu+x[op(i,alphabet)]: od: gu:=1: for i from 1 to nops(u) do if op(i,u)<>B then gu:=gu*x[op(i,u)]: else gu:=gu*mu: fi: od: gu: end: khaver:=proc(mila,B,MISTAKES) local gu,i,v: gu:=1: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): if nops(mila)=nops(v) then if compat(mila,v,B)<>0 then gu:=gu*t[op(v)]: fi: fi: od: gu: end: #mishkal finds the weight of a word w according to the set MISTAKES mishkal:=proc(w,B,alphabet,MISTAKES) local gu,i,j,kak: gu:=weight(w,B,alphabet): for i from 1 to nops(w) do for j from i to nops(w) do gu:=gu*khaver([op(i..j,w)],B,MISTAKES): od: od: gu: end: #MILIM(n) finds all the words of length n in the alphabet MILIM:=proc(alphabet,n) local lu,gu,i,j,v: option remember: if n=0 then RETURN({[]}): fi: gu:={}: lu:=MILIM(alphabet,n-1): for i from 1 to nops(lu) do v:=op(i,lu): for j from 1 to nops(alphabet) do gu:=gu union {[op(v),op(j,alphabet)]}: od: od: gu: end: #MISHKAL(alphabet,B,MISTAKES,n) finds the sum of the weights of all words #of length n in the alphabet alphabet according to MISTAKES MISHKAL:=proc(alphabet,B,MISTAKES,n) local i,gu,lu: lu:=MILIM(alphabet,n): gu:=0: for i from 1 to nops(lu) do gu:=gu+mishkal(op(i,lu),B,alphabet,MISTAKES): od: gu: end: #bdok(alphabet,B,MISTAKES,L) checks empirically, up to the Lth term #the validity of BLANKS(alphabet,B,MISTAKES) bdok:=proc(alphabet,B,MISTAKES,L) local i,gu,s,mu: gu:=BLANKS(alphabet,B,MISTAKES): for i from 1 to nops(alphabet) do gu:=subs(x[op(i,alphabet)]=s*x[op(i,alphabet)],gu): od: gu:=taylor(gu,s=0,L+1): mu:=[]: for i from 0 to L do mu:=[op(mu),expand(coeff(gu,s,i)-MISHKAL(alphabet,B,MISTAKES,i))]: od: mu: end: #Equikxt(u,v,i) is like Equik(u,v,i) but the simplified weight in which #all mistakes get the weight t, i.e.: #Equikxt(u,v,i): Given a genuine mistake v, and another mistake under it #such that the 1'st letter of u coincides with the i-th letter of v #finds the term that corresponds to this situation in the Equation #for C[v], and the second component is the new generalized mistake if present Equikxt:=proc(u,v,i,B,alphabet) local u1,v1,lu: if i<1 or i>nops(v) then ERROR(`1<=i<=nops(v)`): fi: if nops(v)=i then if nops(u)<=nops(v) then RETURN(0,{}): fi: u1:=[op(nops(u)-i+1..nops(u),u)]: if compat(u1,v,B)=0 then RETURN(0,{}): else lu:=[op(1..nops(u)-i,u),op(compat(u1,v,B))]: if mekhil(lu)=0 then RETURN((t-1)*C[op(u)],{}): else RETURN((t-1)*C[op(lu)],{lu}): fi: fi: fi: if nops(u)=i then v1:=[op(1..i,v)]: u1:=[op(nops(u)-i+1..nops(u),u)]: lu:=compat(u1,v1,B): if lu=0 then RETURN(0,{}): else if mekhil(lu)=0 then RETURN((t-1)*weight([op(i+1..nops(v),v)],B,alphabet)*C[op(u)],{}): else RETURN((t-1)*weight([op(i+1..nops(v),v)],B,alphabet)* C[op(1..nops(u)-i,u),op(lu)] ,{[op(1..nops(u)-i,u),op(lu)] }): fi: fi: fi: end: #Equi1kxt(u,v,i), like Equi1k(u,v,i) (reviewed below), but the #weight of each mistake is uniform: t # #Equi1k(u,v,i): Given a generalized mistake of the form v=[v1,v2], #and another genuine mistake u under it #such that the last letter of u coincides with the i-th #letter of vt:=[op(v1),op(v2)] #finds the term that corresponds to this situation in the Equation #for C[v], this is the first component. The second component is the #possible new generalized mistake Equi1kxt:=proc(u,v,i,B,alphabet) local v1,v2,v2ka,v2true,v2spec,vt,u1,lu,V1: v1:=op(1,v): v2:=op(2,v): v2ka:=split1(v2,B): v2true:=v2ka[1]: v2spec:=v2ka[2]: if not type(v1,list) or not type(v2,list) then ERROR(`Something is wrong`): fi: vt:=[op(v1),op(v2spec)]: if i<1 or i>nops(vt) then ERROR(`1<=i<=nops(v1)+nops(v2)`): fi: if nops(vt)=i then if nops(u)<=nops(v2) then RETURN(0,{}): fi: if nops(u)>nops(v2) and nops(u)=i then V1:=[op(1..i,vt)]: u1:=[op(nops(u)-i+1..nops(u),u)]: lu:=compat(u1,V1,B): if lu=0 then RETURN(0,{}): else if mekhil(lu)=0 then RETURN((t-1)* weight([op(i+1..nops(vt),vt)],B,alphabet)*C[op(u)],{}): else RETURN((t-1)*weight([op(i+1..nops(vt),vt)],B,alphabet)* C[op(1..nops(u)-i,u),op(lu)] ,{[op(1..nops(u)-i,u),op(lu)] }): fi: fi: fi: end: #Equi2kxt(u,v,i): Like Equi2k(u,v,i) reviewed below, but with #the weight of each mistake equalling t: # #Equi2k(u,v,i): Given a generalized mistake v, with some #components of the form B=a #and another genuine mistake u under it #such that the last letter of u coincides with the i-th letter of v #finds the term that corresponds to this situation in the Equation #for C[v], this is the first component. The second component is the #possible new generalized mistake Equi2kxt:=proc(u,v,i,B,alphabet) local v2ka,v2true,v2spec,vt,u1,lu,V1: v2ka:=split1(v,B): v2true:=v2ka[1]: v2spec:=v2ka[2]: if mekhil(v)=0 then ERROR(`Something is wrong`): fi: vt:=v2spec: if i<1 or i>nops(vt) then ERROR(`1<=i<=nops(v)`): fi: if nops(vt)=i then if nops(u)<=nops(v) then RETURN(0,{}): fi: u1:=[op(nops(u)-i+1..nops(u),u)]: if compat(u1,vt,B)=0 then RETURN(0,{}): else lu:=[op(1..nops(u)-i,u),op(compat(u1,vt,B))]: if mekhil(lu)=0 then RETURN((t-1)*C[op(u)],{}): else RETURN((t-1)*C[op(lu)],{lu}): fi: fi: fi: if nops(u)=i then V1:=[op(1..i,vt)]: u1:=[op(nops(u)-i+1..nops(u),u)]: lu:=compat(u1,V1,B): if lu=0 then RETURN(0,{}): else if mekhil(lu)=0 then RETURN((t-1)* weight([op(i+1..nops(vt),vt)],B,alphabet)*C[op(u)],{}): else RETURN((t-1)*weight([op(i+1..nops(vt),vt)],B,alphabet)* C[op(1..nops(u)-i,u),op(lu)] ,{[op(1..nops(u)-i,u),op(lu)] }): fi: fi: fi: end: #Equkxt(v) like Equk(v) reviewed below, but with uniform weight t #for all mistakes # #Equk(v): gives the equation corresponding to the genuine mistake #v being at the top and the list of new generalized mistakes Equkxt:=proc(v,MISTAKES,B,alphabet) local u,i,j,gu,NEWMIS: NEWMIS:={}: gu:=C[op(v)]-weight(v,B,alphabet)*(t-1): for j from 1 to nops(MISTAKES) do u:=op(j,MISTAKES): for i from 1 to nops(v) do tempka:=Equikxt(u,v,i,B,alphabet): gu:=gu-tempka[1]: NEWMIS:=NEWMIS union tempka[2]: od: od: gu,NEWMIS: end: #Equ1kxt(v): like Equ1k(v) reviewd below, but with uniform weight t #given to all mistakes # #Equ1k(v): gives the equation corresponding to the generalized mistake #v being at the top, and the set of new generalized mistakes produced Equ1kxt:=proc(v,MISTAKES,B,alphabet) local v1,v2,v2true,v2spec,vt,u,i,j,gu,NEWMIS,tempka,pak: NEWMIS:={}: v1:=op(1,v): v2:=op(2,v): pak:= split1(v2,B): v2true:=pak[1]: v2spec:=pak[2]: vt:=[op(v1),op(v2spec)]: gu:=C[op(v)]-weight(vt,B,alphabet)*(t-1): for j from 1 to nops(MISTAKES) do u:=op(j,MISTAKES): for i from 1 to nops(vt) do tempka:=Equi1kxt(u,v,i,B,alphabet): gu:=gu-tempka[1]: NEWMIS:=NEWMIS union tempka[2]: od: od: gu,NEWMIS: end: Equ2kxt:=proc(v,MISTAKES,B,alphabet) local v2true,v2spec,pak,u,i,j,gu,NEWMIS,tempka: NEWMIS:={}: pak:=split1(v,B): v2true:=pak[1]: v2spec:=pak[2]: gu:=C[op(v)]-weight(v2spec,B,alphabet)*(t-1): for j from 1 to nops(MISTAKES) do u:=op(j,MISTAKES): for i from 1 to nops(v) do tempka:=Equi2kxt(u,v,i,B,alphabet): gu:=gu-tempka[1]: NEWMIS:=NEWMIS union tempka[2]: od: od: gu,NEWMIS: end: BLANKSxt:=proc(alphabet,B,MISTAKES1) local gu,i,v,eq,var,GENMIS,MISTAKES,GENMISdone,tempka: MISTAKES:=convert(convert(MISTAKES1,set),list): GENMIS:={}: var:={}: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): var:=var union {C[op(v)]}: od: eq:={}: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): tempka:=Equkxt(v,MISTAKES,B,alphabet): eq:=eq union {tempka[1]}: GENMIS:=GENMIS union tempka[2]: od: GENMISdone:={}: while nops(GENMIS)-nops(GENMISdone)>0 do v:=op(1,GENMIS minus GENMISdone): GENMISdone:=GENMISdone union {v}: if nops(v)=2 and type(op(1,v),list) then tempka:=Equ1kxt(v,MISTAKES,B,alphabet): eq:=eq union {tempka[1]}: GENMIS:=GENMIS union tempka[2]: else tempka:=Equ2kxt(v,MISTAKES,B,alphabet): eq:=eq union {tempka[1]}: GENMIS:=GENMIS union tempka[2]: fi: od: for i from 1 to nops(GENMIS) do v:=op(i,GENMIS): var:=var union {C[op(v)]}: od: var:=solve(eq,var): gu:=1: for i from 1 to nops(alphabet) do gu:=gu-x[op(i,alphabet)]: od: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): gu:=gu-subs(var,C[op(v)]): od: normal(1/gu): end: khaverxt:=proc(mila,B,MISTAKES) local gu,i,v: gu:=1: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): if nops(mila)=nops(v) then if compat(mila,v,B)<>0 then gu:=gu*t: fi: fi: od: gu: end: #mishkal finds the weight of a word w according to the set MISTAKES mishkalxt:=proc(w,B,alphabet,MISTAKES) local gu,i,j,kak: gu:=weight(w,B,alphabet): for i from 1 to nops(w) do for j from i to nops(w) do gu:=gu*khaverxt([op(i..j,w)],B,MISTAKES): od: od: gu: end: #MISHKALxt(alphabet,B,MISTAKES,n) finds the sum of the weights of all words #of length n in the alphabet alphabet according to MISTAKES MISHKALxt:=proc(alphabet,B,MISTAKES,n) local i,gu,lu: lu:=MILIM(alphabet,n): gu:=0: for i from 1 to nops(lu) do gu:=gu+mishkalxt(op(i,lu),B,alphabet,MISTAKES): od: gu: end: #bdokxt(alphabet,B,MISTAKES,L) checks empirically, up to the Lth term #the validity of BLANKSxt(alphabet,B,MISTAKES) bdokxt:=proc(alphabet,B,MISTAKES,L) local i,gu,s,mu: gu:=BLANKSxt(alphabet,B,MISTAKES): for i from 1 to nops(alphabet) do gu:=subs(x[op(i,alphabet)]=s*x[op(i,alphabet)],gu): od: gu:=taylor(gu,s=0,L+1): mu:=[]: for i from 0 to L do mu:=[op(mu),expand(coeff(gu,s,i)-MISHKALxt(alphabet,B,MISTAKES,i))]: od: mu: end: #Equikst(u,v,i) is like Equik(u,v,i) but the simplified weight in which #all mistakes get the weight t, i.e.: #Equikxt(u,v,i): Given a genuine mistake v, and another mistake under it #such that the 1'st letter of u coincides with the i-th letter of v #finds the term that corresponds to this situation in the Equation #for C[v], and the second component is the new generalized mistake if present Equikst:=proc(u,v,i,B,alphabet) local u1,v1,lu: if i<1 or i>nops(v) then ERROR(`1<=i<=nops(v)`): fi: if nops(v)=i then if nops(u)<=nops(v) then RETURN(0,{}): fi: u1:=[op(nops(u)-i+1..nops(u),u)]: if compat(u1,v,B)=0 then RETURN(0,{}): else lu:=[op(1..nops(u)-i,u),op(compat(u1,v,B))]: if mekhil(lu)=0 then RETURN((t-1)*C[op(u)],{}): else RETURN((t-1)*C[op(lu)],{lu}): fi: fi: fi: if nops(u)=i then v1:=[op(1..i,v)]: u1:=[op(nops(u)-i+1..nops(u),u)]: lu:=compat(u1,v1,B): if lu=0 then RETURN(0,{}): else if mekhil(lu)=0 then RETURN((t-1)*weightst([op(i+1..nops(v),v)],B,alphabet)*C[op(u)],{}): else RETURN((t-1)*weightst([op(i+1..nops(v),v)],B,alphabet)* C[op(1..nops(u)-i,u),op(lu)] ,{[op(1..nops(u)-i,u),op(lu)] }): fi: fi: fi: end: #Equi1kst(u,v,i), like Equi1k(u,v,i) (reviewed below), but the #weight of each mistake is uniform: t and every letter gets weight s Equi1kst:=proc(u,v,i,B,alphabet) local v1,v2,v2ka,v2true,v2spec,vt,u1,lu,V1: v1:=op(1,v): v2:=op(2,v): v2ka:=split1(v2,B): v2true:=v2ka[1]: v2spec:=v2ka[2]: if not type(v1,list) or not type(v2,list) then ERROR(`Something is wrong`): fi: vt:=[op(v1),op(v2spec)]: if i<1 or i>nops(vt) then ERROR(`1<=i<=nops(v1)+nops(v2)`): fi: if nops(vt)=i then if nops(u)<=nops(v2) then RETURN(0,{}): fi: if nops(u)>nops(v2) and nops(u)=i then V1:=[op(1..i,vt)]: u1:=[op(nops(u)-i+1..nops(u),u)]: lu:=compat(u1,V1,B): if lu=0 then RETURN(0,{}): else if mekhil(lu)=0 then RETURN((t-1)* weightst([op(i+1..nops(vt),vt)],B,alphabet)*C[op(u)],{}): else RETURN((t-1)*weightst([op(i+1..nops(vt),vt)],B,alphabet)* C[op(1..nops(u)-i,u),op(lu)] ,{[op(1..nops(u)-i,u),op(lu)] }): fi: fi: fi: end: #Equi2kst(u,v,i): Like Equi2k(u,v,i) reviewed below, but with #the weight of each mistake equalling t, and every letter gets weight s # #Equi2k(u,v,i): Given a generalized mistake v, with some #components of the form B=a #and another genuine mistake u under it #such that the last letter of u coincides with the i-th letter of v #finds the term that corresponds to this situation in the Equation #for C[v], this is the first component. The second component is the #possible new generalized mistake Equi2kst:=proc(u,v,i,B,alphabet) local v2ka,v2true,v2spec,vt,u1,lu,V1: v2ka:=split1(v,B): v2true:=v2ka[1]: v2spec:=v2ka[2]: if mekhil(v)=0 then ERROR(`Something is wrong`): fi: vt:=v2spec: if i<1 or i>nops(vt) then ERROR(`1<=i<=nops(v)`): fi: if nops(vt)=i then if nops(u)<=nops(v) then RETURN(0,{}): fi: u1:=[op(nops(u)-i+1..nops(u),u)]: if compat(u1,vt,B)=0 then RETURN(0,{}): else lu:=[op(1..nops(u)-i,u),op(compat(u1,vt,B))]: if mekhil(lu)=0 then RETURN((t-1)*C[op(u)],{}): else RETURN((t-1)*C[op(lu)],{lu}): fi: fi: fi: if nops(u)=i then V1:=[op(1..i,vt)]: u1:=[op(nops(u)-i+1..nops(u),u)]: lu:=compat(u1,V1,B): if lu=0 then RETURN(0,{}): else if mekhil(lu)=0 then RETURN((t-1)* weightst([op(i+1..nops(vt),vt)],B,alphabet)*C[op(u)],{}): else RETURN((t-1)*weightst([op(i+1..nops(vt),vt)],B,alphabet)* C[op(1..nops(u)-i,u),op(lu)] ,{[op(1..nops(u)-i,u),op(lu)] }): fi: fi: fi: end: #Equkst(v) like Equk(v) reviewed below, but with uniform weight t #for all mistakes and all letters get weight s Equkst:=proc(v,MISTAKES,B,alphabet) local u,i,j,gu,NEWMIS: NEWMIS:={}: gu:=C[op(v)]-weightst(v,B,alphabet)*(t-1): for j from 1 to nops(MISTAKES) do u:=op(j,MISTAKES): for i from 1 to nops(v) do tempka:=Equikst(u,v,i,B,alphabet): gu:=gu-tempka[1]: NEWMIS:=NEWMIS union tempka[2]: od: od: gu,NEWMIS: end: #Equkst_series(v) like Equkst(v) reviewed above, but tailored for #BLANKSseries Equkst_series:=proc(v,MISTAKES,B,alphabet) local POL,u,i,j,gu,NEWMIS: NEWMIS:={}: POL:=subs(t=0,weightst(v,B,alphabet))*(-1): gu:=0: for j from 1 to nops(MISTAKES) do u:=op(j,MISTAKES): for i from 1 to nops(v) do tempka:=Equikst(u,v,i,B,alphabet): gu:=gu+subs(t=0,tempka[1]): NEWMIS:=NEWMIS union tempka[2]: od: od: POL,gu,NEWMIS: end: #Equ1kst(v): like Equ1k(v) reviewd below, but with uniform weight t #given to all mistakes and all letters get weight s Equ1kst:=proc(v,MISTAKES,B,alphabet) local v1,v2,v2true,v2spec,vt,u,i,j,gu,NEWMIS,tempka,pak: NEWMIS:={}: v1:=op(1,v): v2:=op(2,v): pak:= split1(v2,B): v2true:=pak[1]: v2spec:=pak[2]: vt:=[op(v1),op(v2spec)]: gu:=C[op(v)]-weightst(vt,B,alphabet)*(t-1): for j from 1 to nops(MISTAKES) do u:=op(j,MISTAKES): for i from 1 to nops(vt) do tempka:=Equi1kst(u,v,i,B,alphabet): gu:=gu-tempka[1]: NEWMIS:=NEWMIS union tempka[2]: od: od: gu,NEWMIS: end: #Equ1kst_series(v): like Equ1kst(v) reviewd above but for the #use of BLANKSseries Equ1kst_series:=proc(v,MISTAKES,B,alphabet) local v1,v2,v2true,v2spec,vt,u,i,j,gu,NEWMIS,tempka,pak,POL: NEWMIS:={}: v1:=op(1,v): v2:=op(2,v): pak:= split1(v2,B): v2true:=pak[1]: v2spec:=pak[2]: vt:=[op(v1),op(v2spec)]: gu:=0: gu:=subs(t=0,weightst(vt,B,alphabet))*(0-1): for j from 1 to nops(MISTAKES) do u:=op(j,MISTAKES): for i from 1 to nops(vt) do tempka:=Equi1kst(u,v,i,B,alphabet): gu:=gu+subs(t=0,tempka[1]): NEWMIS:=NEWMIS union tempka[2]: od: od: POL,gu,NEWMIS: end: Equ2kst:=proc(v,MISTAKES,B,alphabet) local v2true,v2spec,pak,u,i,j,gu,NEWMIS,tempka: NEWMIS:={}: pak:=split1(v,B): v2true:=pak[1]: v2spec:=pak[2]: gu:=C[op(v)]-weightst(v2spec,B,alphabet)*(t-1): for j from 1 to nops(MISTAKES) do u:=op(j,MISTAKES): for i from 1 to nops(v) do tempka:=Equi2kst(u,v,i,B,alphabet): gu:=gu-tempka[1]: NEWMIS:=NEWMIS union tempka[2]: od: od: gu,NEWMIS: end: Equ2kst_series:=proc(v,MISTAKES,B,alphabet) local v2true,v2spec,pak,u,i,j,gu,NEWMIS,tempka,POL: NEWMIS:={}: pak:=split1(v,B): v2true:=pak[1]: v2spec:=pak[2]: POL:=subs(t=0,weightst(v2spec,B,alphabet))*(0-1): gu:=0: for j from 1 to nops(MISTAKES) do u:=op(j,MISTAKES): for i from 1 to nops(v) do tempka:=Equi2kst(u,v,i,B,alphabet): gu:=gu+subs(t=0,tempka[1]): NEWMIS:=NEWMIS union tempka[2]: od: od: POL,gu,NEWMIS: end: BLANKSst:=proc(alphabet,B,MISTAKES1) local gu,i,v,eq,var,GENMIS,MISTAKES,GENMISdone,tempka: MISTAKES:=convert(convert(MISTAKES1,set),list): GENMIS:={}: var:={}: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): var:=var union {C[op(v)]}: od: eq:={}: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): tempka:=Equkst(v,MISTAKES,B,alphabet): eq:=eq union {tempka[1]}: GENMIS:=GENMIS union tempka[2]: od: GENMISdone:={}: while nops(GENMIS)-nops(GENMISdone)>0 do v:=op(1,GENMIS minus GENMISdone): GENMISdone:=GENMISdone union {v}: if nops(v)=2 and type(op(1,v),list) then tempka:=Equ1kst(v,MISTAKES,B,alphabet): eq:=eq union {tempka[1]}: GENMIS:=GENMIS union tempka[2]: else tempka:=Equ2kst(v,MISTAKES,B,alphabet): eq:=eq union {tempka[1]}: GENMIS:=GENMIS union tempka[2]: fi: od: for i from 1 to nops(GENMIS) do v:=op(i,GENMIS): var:=var union {C[op(v)]}: od: var:=solve(eq,var): gu:=1: for i from 1 to nops(alphabet) do gu:=gu-s: od: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): gu:=gu-subs(var,C[op(v)]): od: normal(1/gu): end: khaverst:=proc(mila,B,MISTAKES) local gu,i,v: gu:=1: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): if nops(mila)=nops(v) then if compat(mila,v,B)<>0 then gu:=gu*t: fi: fi: od: gu: end: #mishkal finds the weight of a word w according to the set MISTAKES mishkalst:=proc(w,B,alphabet,MISTAKES) local gu,i,j,kak: #gu:=weightst(w,B,alphabet): gu:=1: for i from 1 to nops(w) do for j from i to nops(w) do gu:=gu*khaverst([op(i..j,w)],B,MISTAKES): od: od: gu: end: #MISHKALst(alphabet,B,MISTAKES,n) finds the sum of the weights of all words #of length n in the alphabet alphabet according to MISTAKES MISHKALst:=proc(alphabet,B,MISTAKES,n) local i,gu,lu: lu:=MILIM(alphabet,n): gu:=0: for i from 1 to nops(lu) do gu:=gu+mishkalst(op(i,lu),B,alphabet,MISTAKES): od: gu: end: #bdokst(alphabet,B,MISTAKES,L) checks empirically, up to the Lth term #the validity of BLANKSst(alphabet,B,MISTAKES) bdokst:=proc(alphabet,B,MISTAKES,L) local i,gu,mu: gu:=BLANKSst(alphabet,B,MISTAKES): gu:=taylor(gu,s=0,L+1): mu:=[]: for i from 0 to L do mu:=[op(mu),expand(coeff(gu,s,i)-MISHKALst(alphabet,B,MISTAKES,i))]: od: mu: end: #weightst(u,B,alphabet) gives the weight of a word u #where every letter gets weight s weightst:=proc(u,B,alphabet) local gu,i,mu: if mekhil(u,B)=1 then ERROR(`In weight, input u is not a proper word`): fi: mu:=0: for i from 1 to nops(alphabet) do mu:=mu+s: od: gu:=1: for i from 1 to nops(u) do if op(i,u)<>B then gu:=gu*s: else gu:=gu*mu: fi: od: gu: end: BLANKSs0:=proc(alphabet,B,MISTAKES1) local gu,i,v,eq,var,GENMIS,MISTAKES,GENMISdone,tempka: MISTAKES:=convert(convert(MISTAKES1,set),list): GENMIS:={}: var:={}: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): var:=var union {C[op(v)]}: od: eq:={}: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): tempka:=Equkst(v,MISTAKES,B,alphabet): eq:=eq union {tempka[1]}: GENMIS:=GENMIS union tempka[2]: od: GENMISdone:={}: while nops(GENMIS)-nops(GENMISdone)>0 do v:=op(1,GENMIS minus GENMISdone): GENMISdone:=GENMISdone union {v}: if nops(v)=2 and type(op(1,v),list) then tempka:=Equ1kst(v,MISTAKES,B,alphabet): eq:=eq union {tempka[1]}: GENMIS:=GENMIS union tempka[2]: else tempka:=Equ2kst(v,MISTAKES,B,alphabet): eq:=eq union {tempka[1]}: GENMIS:=GENMIS union tempka[2]: fi: od: for i from 1 to nops(GENMIS) do v:=op(i,GENMIS): var:=var union {C[op(v)]}: od: eq:=subs(t=0,eq): var:=solve(eq,var): gu:=1: for i from 1 to nops(alphabet) do gu:=gu-s: od: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): gu:=gu-subs(var,C[op(v)]): od: normal(1/gu): end: BLANKSseries:=proc(alphabet,B,MISTAKES1,L) local gu,i,v,eq,var,GENMIS,MISTAKES,GENMISdone,tempka,T,pols: MISTAKES:=convert(convert(MISTAKES1,set),list): GENMIS:={}: var:={}: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): var:=var union {C[op(v)]}: od: T:=var: eq:=[]: var:=[]: pols:=[]: for i from 1 to nops(MISTAKES) do v:=op(i,MISTAKES): tempka:=Equkst_series(v,MISTAKES,B,alphabet): pols:=[op(pols),tempka[1]]: eq:=[op(eq), tempka[2]]: var:=[op(var), C[op(v)]]: GENMIS:=GENMIS union tempka[3]: od: GENMISdone:={}: while nops(GENMIS)-nops(GENMISdone)>0 do v:=op(1,GENMIS minus GENMISdone): GENMISdone:=GENMISdone union {v}: if nops(v)=2 and type(op(1,v),list) then tempka:=Equ1kst_series(v,MISTAKES,B,alphabet): pols:=[op(pols),tempka[1]]: eq:=[op(eq), tempka[2]]: var:=[op(var), C[op(v)]]: GENMIS:=GENMIS union tempka[3]: else tempka:=Equ2kst_series(v,MISTAKES,B,alphabet): ## pols:=[op(pols),tempka[1]]: eq:=[op(eq), tempka[2]]: var:=[op(var), C[op(v)]]: GENMIS:=GENMIS union tempka[3]: fi: od: lu:=solser(var,pols,eq,T,L+2): print(`lu is`,lu): ku:=1-nops(alphabet)*s: for i from 1 to L+2 do ku:=ku-op(i,lu)*s^i: od: ku:=taylor(1/ku,s=0,L+1): lu:=[]: for i from 0 to L do lu:=[op(lu),coeff(ku,s,i)]: od: lu: end: #solser(vars,pols,equs,T,L): Given a system of eqations of the form #a[i](s)=p[i](s)+ \sum_{j=1}^{n} P[i,j](s) a[j](s), finds the series expansion #of sum_{i \in T} a[i], where T is a subset of vars. #The inputs are the list of a[i] , vars, the corresponding list pols, of the #p[i]'s, the list of expressions \sum_{j=1}^{n} P[i,j](s) a[j](s), the #above-mentioned suset T, and the expansion should be up to the L's term solser:=proc(vars,pols,equs,T,L) local Mem,i,aj,maxi,X,VARS,TOSA,r,lu: #Mem is a list of the memories that each a[j] needs Mem:=[]: for j from 1 to nops(vars) do aj:=op(j,vars): maxi:=0: for i from 1 to nops(equs) do if degree(coeff(op(i,equs),aj,1),s)>maxi then maxi:=degree(coeff(op(i,equs),aj,1),s): fi: od: Mem:=[op(Mem),maxi]: od: for i from 1 to nops(vars) do X[i]:=[seq(0,j=1..op(i,Mem))]: od: lu:=[]: for n from 1 to L do for i from 1 to nops(equs) do gu[i]:=coeff(op(i,pols),s,n): for j from 1 to nops(vars) do aj:=op(j,vars): pij:=coeff(op(i,equs),aj,1): for r from 1 to degree(pij,s) do gu[i]:=gu[i]+coeff(pij,s,r)*op(nops(X[j])-r+1,X[j]): od: od: od: lu1:=0: for i from 1 to nops(vars) do if member(op(i,vars),T) then lu1:=lu1+gu[i]: fi: od: lu:=[op(lu),lu1]: for i from 1 to nops(vars) do X[i]:=[op(2..nops(X[i]),X[i]),gu[i]]: od: od: lu: end: