/* $OpenXM: OpenXM/src/k097/lib/minimal/minimal.k,v 1.36 2007/07/03 22:28:11 takayama Exp $ */ #define DEBUG 1 Sordinary = false; /* If you run this program on openxm version 1.1.2 (FreeBSD), make a symbolic link by the command ln -s /usr/bin/cpp /lib/cpp */ #define OFFSET 0 /* #define OFFSET 20*/ Sverbose = false; /* Be extreamly verbose */ Sverbose2 = true; /* Don't be quiet and show minimal information */ def Sprintln(s) { if (Sverbose) Println(s); } def Sprint(s) { if (Sverbose) Print(s); } def Sprintln2(s) { if (Sverbose2) Println(s); } def Sprint2(s) { if (Sverbose2) Print(s); sm1(" [(flush)] extension "); } /* Test sequences. Use load["minimal.k"];; a=Sminimal(v); b=a[0]; b[1]*b[0]: b[2]*b[1]: a = test0(); b = a[0]; b[1]*b[0]: b[2]*b[1]: a = Sminimal(b[0]); a = test1(); b=a[0]; b[1]*b[0]: b[2]*b[1]: */ /* We cannot use load command in the if statement. */ load("lib/minimal/cohom.k"); Load_sm1(["k0-tower.sm1","lib/minimal/k0-tower.sm1"],"k0-tower.sm1.loaded"); Load_sm1(["new.sm1","lib/minimal/new.sm1"],"new.sm1.loaded"); sm1(" oxNoX "); SonAutoReduce = true; def Factor(f) { sm1(f, " fctr /FunctionValue set"); } def Reverse(f) { sm1(f," reverse /FunctionValue set"); } def Sgroebner(f) { sm1(" [f] groebner /FunctionValue set"); } def Sinvolutive(f,w) { local g,m; if (IsArray(f[0])) { m = NewArray(Length(f[0])); }else{ m = [0]; } g = Sgroebner(f); /* This is a temporary code. */ sm1(" g 0 get { w m init_w} map /FunctionValue set "); } def Error(s) { sm1(" s error "); } def IsNull(s) { if (Stag(s) == 0) return(true); else return(false); } def MonomialPart(f) { sm1(" [(lmonom) f] gbext /FunctionValue set "); } def Warning(s) { Print("Warning: "); Println(s); } def RingOf(f) { local r; if (IsPolynomial(f)) { if (f != Poly("0")) { sm1(f," (ring) dc /r set "); }else{ sm1(" [(CurrentRingp)] system_variable /r set "); } }else{ Warning("RingOf(f): the argument f must be a polynomial. Return the current ring."); sm1(" [(CurrentRingp)] system_variable /r set "); } return(r); } def Ord_w_m(f,w,m) { sm1(" f w m ord_w { (universalNumber) dc } map /FunctionValue set "); } HelpAdd(["Ord_w_m", ["Ord_w_m(f,w,m) returns the order of f with respect to w with the shift m.", "Note that the order of the ring and the weight w must be the same.", "When f is zero, it returns -intInfinity = -999999999.", "Example: Sweyl(\"x,y\",[[\"x\",-1,\"Dx\",1]]); ", " Ord_w_m([x*Dx+1,Dx^2+x^5],[\"x\",-1,\"Dx\",1],[2,0]):"]]); def Init_w_m(f,w,m) { sm1(" f w m init_w /FunctionValue set "); } HelpAdd(["Init_w_m", ["Init_w_m(f,w,m) returns the initial of f with respect to w with the shift m.", "Note that the order of the ring and the weight w must be the same.", "Example: Sweyl(\"x,y\",[[\"x\",-1,\"Dx\",1]]); ", " Init_w_m([x*Dx+1,Dx^2+x^5],[\"x\",-1,\"Dx\",1],[2,0]):"]]); def Max(v) { local i,t,n; n = Length(v); if (n == 0) return(null); t = v[0]; for (i=0; i t) { t = v[i];} } return(t); } HelpAdd(["Max", ["Max(v) returns the maximal element in v."]]); def Kernel(f,v) { local ans; /* v : string or ring */ if (Length(Arglist) < 2) { sm1(" [f] syz /ans set "); }else{ sm1(" [f v] syz /ans set "); } return(ans); } def Syz(f) { sm1(" [f] syz /FunctionValue set "); } HelpAdd(["Kernel", ["Kernel(f) returns the syzygy of f.", "Return value [b, c]: b is a set of generators of the syzygies of f", " : c=[gb, backward transformation, syzygy without", " dehomogenization", "Example: Weyl(\"x,y\",[[\"x\",-1,\"Dx\",1]]); ", " s=Kernel([x*Dx+1,Dx^2+x^5]); s[0]:"]]); /* cf. sm1_syz in cohom.k */ def Gb(f) { sm1(" [f] gb /FunctionValue set "); } HelpAdd(["Gb", ["Gb(f) returns the Groebner basis of f.", "cf. Kernel, Weyl."]]); /* End of standard functions that should be moved to standard libraries. */ def test0() { local f; Sweyl("x,y,z"); f = [x^2+y^2+z^2, x*y+x*z+y*z, x*z^2+y*z^2, y^3-x^2*z - x*y*z+y*z^2, -y^2*z^2 + x*z^3 + y*z^3, -z^4]; frame=SresolutionFrame(f); Println(frame); /* return(frame); */ return(SlaScala(f)); } def test1() { local f; Sweyl("x,y,z"); f = [x^2+y^2+z^2, x*y+x*z+y*z, x*z^2+y*z^2, y^3-x^2*z - x*y*z+y*z^2, -y^2*z^2 + x*z^3 + y*z^3, -z^4]; return(Sminimal(f)); } def Sweyl(v,w) { /* extern WeightOfSweyl ; */ local ww,i,n; if(Length(Arglist) == 1) { sm1(" [v s_ring_of_differential_operators 0 [(schreyer) 1]] define_ring "); sm1(" define_ring_variables "); sm1(" [ v to_records pop ] /ww set "); n = Length(ww); WeightOfSweyl = NewArray(n*4); for (i=0; i< n; i++) { WeightOfSweyl[2*i] = ww[i]; WeightOfSweyl[2*i+1] = 1; } for (i=0; i< n; i++) { WeightOfSweyl[2*n+2*i] = AddString(["D",ww[i]]); WeightOfSweyl[2*n+2*i+1] = 1; } }else{ sm1(" [v s_ring_of_differential_operators w s_weight_vector 0 [(schreyer) 1]] define_ring "); sm1(" define_ring_variables "); WeightOfSweyl = w[0]; } } def Spoly(f) { sm1(f, " toString tparse /FunctionValue set "); } def SreplaceZeroByZeroPoly(f) { if (IsArray(f)) { return(Map(f,"SreplaceZeroByZeroPoly")); }else{ if (IsInteger(f)) { return(Poly(ToString(f))); }else{ return(f); } } } def Shomogenize(f) { f = SreplaceZeroByZeroPoly(f); if (IsArray(f)) { sm1(f," sHomogenize2 /FunctionValue set "); /* sm1(f," {sHomogenize2} map /FunctionValue set "); */ /* Is it correct? Double check.*/ }else{ sm1(f, " sHomogenize /FunctionValue set "); } } def StoTower() { sm1(" [(AvoidTheSameRing)] pushEnv [ [(AvoidTheSameRing) 0] system_variable (mmLarger) (tower) switch_function ] pop popEnv "); } def SsetTower(tower) { sm1(" [(AvoidTheSameRing)] pushEnv \ [ [(AvoidTheSameRing) 0] system_variable \ [(gbListTower) tower (list) dc] system_variable \ ] pop popEnv "); /* sm1("(hoge) message show_ring "); */ } def SresolutionFrameWithTower(g,opt) { local gbTower, ans, ff, count, startingGB, opts, skelton,withSkel, autof, gbasis, nohomog,i,n; /* extern Sordinary */ nohomog = false; count = -1; Sordinary = false; /* default value for options. */ if (Length(Arglist) >= 2) { if (IsArray(opt)) { n = Length(opt); for (i=0; i ans) ans = tt; }else{ if (a[i] > ans) ans = a[i]; } } }else{ if (a > ans) ans = a; } return(ans); } def SlaScala(g,opt) { local rf, tower, reductionTable, skel, redundantTable, bases, strategy, maxOfStrategy, height, level, n, i, freeRes,place, f, reducer,pos, redundant_seq,bettiTable,freeResV,ww, redundantTable_ordinary, redundant_seq_ordinary, reductionTable_tmp; /* extern WeightOfSweyl; */ ww = WeightOfSweyl; Sprint("WeightOfSweyl="); Sprintln(WeightOfSweyl); rf = SresolutionFrameWithTower(g,opt); Sprint("rf="); if (Sverbose) {sm1_pmat(rf);} redundant_seq = 1; redundant_seq_ordinary = 1; tower = rf[1]; Sprintln("Generating reduction table which gives an order of reduction."); Sprint("WeghtOfSweyl="); Sprintln(WeightOfSweyl); Sprint2("tower="); Sprintln2(tower); reductionTable = SgenerateTable(tower); Sprint2("reductionTable="); if (Sverbose || Sverbose2) {sm1_pmat(reductionTable);} skel = rf[2]; redundantTable = SnewArrayOfFormat(rf[1]); redundantTable_ordinary = SnewArrayOfFormat(rf[1]); reducer = SnewArrayOfFormat(rf[1]); freeRes = SnewArrayOfFormat(rf[1]); bettiTable = SsetBettiTable(rf[1],g); strategy = SminOfStrategy( reductionTable ); maxOfStrategy = SmaxOfStrategy( reductionTable ); height = Length(reductionTable); while (strategy <= maxOfStrategy) { for (level = 0; level < height; level++) { n = Length(reductionTable[level]); reductionTable_tmp = ScopyArray(reductionTable[level]); while (SthereIs(reductionTable_tmp,strategy)) { i = SnextI(reductionTable_tmp,strategy,redundantTable, skel,level,freeRes); Sprintln([level,i]); reductionTable_tmp[i] = -200000; if (reductionTable[level,i] == strategy) { Sprint("Processing [level,i]= "); Sprint([level,i]); Sprint(" Strategy = "); Sprintln(strategy); Sprint2(strategy); if (level == 0) { if (IsNull(redundantTable[level,i])) { bases = freeRes[level]; /* Println(["At floor : GB=",i,bases,tower[0,i]]); */ pos = SwhereInGB(tower[0,i],rf[3,0]); bases[i] = rf[3,0,pos]; redundantTable[level,i] = 0; redundantTable_ordinary[level,i] = 0; freeRes[level] = bases; /* Println(["GB=",i,bases,tower[0,i]]); */ } }else{ /* level >= 1 */ if (IsNull(redundantTable[level,i])) { bases = freeRes[level]; f = SpairAndReduction(skel,level,i,freeRes,tower,ww); if (f[0] != Poly("0")) { place = f[3]; /* (level-1, place) is the place for f[0], which is a newly obtained GB. */ if (Sordinary) { redundantTable[level-1,place] = redundant_seq; redundant_seq++; }else{ if (f[4] > f[5]) { /* Zero in the gr-module */ Sprint("v-degree of [org,remainder] = "); Sprintln([f[4],f[5]]); Sprint("[level,i] = "); Sprintln([level,i]); redundantTable[level-1,place] = 0; }else{ redundantTable[level-1,place] = redundant_seq; redundant_seq++; } } redundantTable_ordinary[level-1,place] =redundant_seq_ordinary; redundant_seq_ordinary++; bases[i] = SunitOfFormat(place,f[1])-f[1]; /* syzygy */ redundantTable[level,i] = 0; redundantTable_ordinary[level,i] = 0; /* i must be equal to f[2], I think. Double check. */ freeRes[level] = bases; bases = freeRes[level-1]; bases[place] = f[0]; freeRes[level-1] = bases; reducer[level-1,place] = f[1]; }else{ redundantTable[level,i] = 0; bases = freeRes[level]; bases[i] = f[1]; /* Put the syzygy. */ freeRes[level] = bases; } } } /* end of level >= 1 */ } } } strategy++; } Sprintln2(" "); n = Length(freeRes); freeResV = SnewArrayOfFormat(freeRes); for (i=0; i= 1 in SpairAndReduction."); p = skel[level,ii]; myindex = p[0]; i = myindex[0]; j = myindex[1]; bases = freeRes[level-1]; Sprintln(["p and bases ",p,bases]); if (IsNull(bases[i]) || IsNull(bases[j])) { Sprintln([level,i,j,bases[i],bases[j]]); Error("level, i, j : bases[i], bases[j] must not be NULL."); } tower2 = StowerOf(tower,level-1); SsetTower(tower2); Sprintln(["level=",level]); Sprintln(["tower2=",tower2]); /** sm1(" show_ring "); */ gi = Stoes_vec(bases[i]); gj = Stoes_vec(bases[j]); ssp = Sspolynomial(gi,gj); si = ssp[0,0]; sj = ssp[0,1]; syzHead = si*es^i; /* This will be the head term, I think. But, double check. */ Sprintln([si*es^i,sj*es^j]); Sprint("[gi, gj] = "); Sprintln([gi,gj]); sm1(" [(Homogenize)] system_variable "); Sprint("Reduce the element "); Sprintln(si*gi+sj*gj); Sprint("by "); Sprintln(bases); tmp = Sreduction(si*gi+sj*gj, bases); Sprint("result is "); Sprintln(tmp); /* This is essential part for V-minimal resolution. */ /* vdeg = SvDegree(si*gi+sj*gj,tower,level-1,ww); */ vdeg = SvDegree(si*gi,tower,level-1,ww); vdeg_reduced = SvDegree(tmp[0],tower,level-1,ww); Sprint("vdegree of the original = "); Sprintln(vdeg); Sprint("vdegree of the remainder = "); Sprintln(vdeg_reduced); t_syz = tmp[2]; si = si*tmp[1]+t_syz[i]; sj = sj*tmp[1]+t_syz[j]; t_syz[i] = si; t_syz[j] = sj; SsetTower(StowerOf(tower,level)); pos = SwhereInTower(syzHead,tower[level]); SsetTower(StowerOf(tower,level-1)); pos2 = SwhereInTower(tmp[0],tower[level-1]); ans = [tmp[0],t_syz,pos,pos2,vdeg,vdeg_reduced]; /* pos is the place to put syzygy at level. */ /* pos2 is the place to put a new GB at level-1. */ Sprintln(ans); return(ans); } def Sreduction(f,myset) { local n, indexTable, set2, i, j, tmp, t_syz; n = Length(myset); indexTable = NewArray(n); set2 = [ ]; j = 0; for (i=0; i 0 && size == -1) { if (size == -1) { sm1(f," (array) dc /ans set"); return(ans); } } /* Coefficients(x^2-1,x): [ [ 2 , 0 ] , [ 1 , -1 ] ] */ if (Degree(f,myee) > 0) { c = Coefficients(f,myee); }else{ c = Coefficients(f,myes); } if (size < 0) { size = c[0,0]+1; } ans = NewArray(size); for (i=0; i 1) { giveSize = true; }else{ giveSize = false; } n = Length(bases); newbases = NewArray(n); for (i=0; i D^{m_3} --b[2]--> D^{m_2} --b[1]--> D^{m_1} --b[0]--> D^{m_0} ", " Here D^{m_i} are the set of row vectors. " ]]); def Sminimal(g,opt) { local r, freeRes, redundantTable, reducer, maxLevel, minRes, seq, maxSeq, level, betti, q, bases, dr, betti_levelplus, newbases, i, j,qq, tminRes,bettiTable, ansSminimal; if (Length(Arglist) < 2) { opt = null; } /* Sordinary is set in SlaScala(g,opt) --> SresolutionFrameWithTower */ ScheckIfSchreyer("Sminimal:0"); r = SlaScala(g,opt); /* Should I turn off the tower?? */ ScheckIfSchreyer("Sminimal:1"); freeRes = r[0]; redundantTable = r[1]; reducer = r[2]; bettiTable = SbettiTable(redundantTable); Sprintln2("BettiTable ------"); if (Sverbose || Sverbose2) {sm1_pmat(bettiTable);} minRes = SnewArrayOfFormat(freeRes); seq = 0; maxSeq = SgetMaxSeq(redundantTable); maxLevel = Length(freeRes); for (level = 0; level < maxLevel; level++) { minRes[level] = freeRes[level]; } seq=maxSeq+1; while (seq > 1) { seq--; Sprint2(seq); for (level = 0; level < maxLevel; level++) { betti = Length(freeRes[level]); for (q = 0; q ans) { ans = bases[i]; } } } } return(ans); } def Stetris(freeRes,redundantTable) { local level, i, j, resLength, minRes, bases, newbases, newbases2; minRes = SnewArrayOfFormat(freeRes); resLength = Length( freeRes ); for (level=0; level 0) { /* Delete columns */ newbases = Transpose(bases); betti = Length(newbases); j = 0; newbases2 = SnewArrayOfFormat(newbases); for (i=0; i The betti numbers are 3, 2. a=Sannfs2("x^3-y^2-x"); a=Sannfs2("x*y*(x-y)"); */ def Sannfs3(f) { local p,pp; p = Sannfs(f,"x,y,z"); sm1(" p 0 get { [(x) (y) (z) (Dx) (Dy) (Dz)] laplace0 } map /p set "); Sweyl("x,y,z",[["x",-1,"y",-1,"z",-1,"Dx",1,"Dy",1,"Dz",1]]); pp = Map(p,"Spoly"); return(Sminimal(pp)); } HelpAdd(["Sannfs3", ["Sannfs3(f) constructs the V-minimal free resolution for the weight (-1,1)", "of the Laplace transform of the annihilating ideal of the polynomial f in x,y,z.", "See also Sminimal, Sannfs2.", "Example: a=Sannfs3(\"x^3-y^2*z^2\");", " b=a[0]; sm1_pmat(b);", " b[1]*b[0]: b[2]*b[1]:"]]); /* Sannfs2("x*y*(x-y)*(x+y)"); is a test problem */ /* x y (x+y-1)(x-2), x^3-y^2, x^3 - y^2 z^2, x y z (x+y+z-1) seems to be interesting, because the first syzygy contains 1. */ def CopyArray(m) { local ans,i,n; if (IsArray(m)) { n = Length(m); ans = NewArray(n); for (i=0; i (homogenized Weyl algebra)", "cf. ReParse" ]]); def IsSameIdeal_h(ii,jj,v) { local a; v = ToString_array(v); a = [ii,jj,v]; sm1(a," isSameIdeal_h /FunctionValue set "); } HelpAdd(["IsSameIdeal_h", ["IsSameIdeal_h(ii,jj,var): bool", "It checks the given ideals are the same or not in D (homogenized Weyl algebra)", "cf. ReParse" ]]); /* Output of S* functions may cause a trouble because it uses Schreyer orders. In this case, use ReParse(). */ def ScheckIfSchreyer(s) { local ss; sm1(" (report) (grade) switch_function /ss set "); if (ss != "module1v") { Print("ScheckIfSchreyer: from "); Println(s); Error("grade is not module1v"); } /* sm1(" (report) (mmLarger) switch_function /ss set "); if (ss != "tower") { Print("ScheckIfSchreyer: from "); Println(s); Error("mmLarger is not tower"); } */ sm1(" [(Schreyer)] system_variable (universalNumber) dc /ss set "); if (ss != 1) { Print("ScheckIfSchreyer: from "); Printl(s); Error("Schreyer order is not set."); } /* More check will be necessary. */ return(true); } def SgetShift(mat,w,m) { local omat; sm1(" mat { w m ord_w {(universalNumber) dc}map } map /omat set"); return(Map(omat,"Max")); } HelpAdd(["SgetShift", ["SgetShift(mat,w,m) returns the shift vector of mat with respect to w with the shift m.", "Note that the order of the ring and the weight w must be the same.", "Example: Sweyl(\"x,y\",[[\"x\",-1,\"Dx\",1]]); ", " SgetShift([[x*Dx+1,Dx^2+x^5],[Poly(\"0\"),x],[x,x]],[\"x\",-1,\"Dx\",1],[2,0]):"]]); def SgetShifts(resmat,w) { local i,n,ans,m0; n = Length(resmat); ans = NewArray(n+1); m0 = NewArray(Length(resmat[0,0])); ans[0] = m0; for (i=0; i