diff --git a/M2/Macaulay2/m2/matrix1.m2 b/M2/Macaulay2/m2/matrix1.m2 index b6e5022983a..c5c6770078c 100644 --- a/M2/Macaulay2/m2/matrix1.m2 +++ b/M2/Macaulay2/m2/matrix1.m2 @@ -13,7 +13,7 @@ notsamering := (X,Y) -> ( nottosamering := (X,Y) -> ( if X === Y then error("expected ",pluralsynonym X, " for compatible rings") else error("expected ",X.synonym," and ",Y.synonym," for compatible rings")) -samering := (M,N) -> if ring M === ring N then (M,N) else notsamering(class M,class N) +samering = (M,N) -> if ring M === ring N then (M,N) else notsamering(class M,class N) tosamering := (M,N) -> if ring M === ring N then (M,N) else ( z := try 0_(ring M) + 0_(ring N) else nottosamering(class M,class N); (promote(M,ring z),promote(N,ring z))) @@ -555,11 +555,9 @@ ideal Matrix := Ideal => (f) -> ( ); new Ideal from { symbol generators => f, symbol ring => R, symbol cache => new CacheTable } ) -ideal Module := Ideal => (M) -> ( - F := ambient M; - if isSubmodule M and rank F === 1 then ideal generators M - else error "expected a submodule of a free module of rank 1" - ) +ideal Module := Ideal => M -> if isIdeal M then ideal generators M else ( + error "expected a submodule of a free module of rank 1") + idealPrepare = method() idealPrepare RingElement := idealPrepare Number := identity diff --git a/M2/Macaulay2/m2/matrix2.m2 b/M2/Macaulay2/m2/matrix2.m2 index 07005cdb446..0373b48b1f3 100644 --- a/M2/Macaulay2/m2/matrix2.m2 +++ b/M2/Macaulay2/m2/matrix2.m2 @@ -135,14 +135,16 @@ complement Matrix := Matrix => (f) -> ( else if instance(R,QuotientRing) then map(target f,,R ** complement lift(f,ambient R)) else error "complement: expected matrix over affine ring or finitely generated ZZ-algebra") +----------------------------------------------------------------------------- +-- mingens and trim +----------------------------------------------------------------------------- + -- the method is declared in gb.m2 +-- TODO: the strategies should be separated mingens Ideal := Matrix => opts -> I -> mingens(module I, opts) -mingens Module := Matrix => opts -> (cacheValue symbol mingens) ((M) -> ( - c := runHooks((mingens, Module), (opts, M)); - if c =!= null then c else error "mingens: no method implemented for this type of module")) - --- FIXME: This is kind of a hack. The strategies should be separated in mingensHelper -mingensHelper = ((opts, M) -> ( +mingens Module := Matrix => opts -> M -> if isFreeModule M then generators M else cacheHooks( + symbol mingens, M, (mingens, Module), (opts, M), (opts, M) -> ( + if opts.Strategy === null then opts = opts ++ { Strategy => Complement }; mingb := m -> gb (m, StopWithMinimalGenerators=>true, Syzygies=>false, ChangeMatrix=>false); zr := f -> if f === null or f == 0 then null else f; F := ambient M; @@ -164,25 +166,15 @@ mingensHelper = ((opts, M) -> ( else mingens mingb (id_F % mingb(M.relations))) else id_F))) -addHook((mingens, Module), Strategy => Inhomogeneous, (opts, M) -> mingensHelper(opts ++ {Strategy => Inhomogeneous}, M)) -addHook((mingens, Module), Strategy => Complement, (opts, M) -> mingensHelper(opts ++ {Strategy => Complement}, M)) - trim = method (Options => { Strategy => null -* TODO: add DegreeLimit => {} *-}) -trim Ring := Ring => opts -> (R) -> R -trim QuotientRing := opts -> (R) -> ( - f := presentation R; - A := ring f; - A/(trim(ideal f,opts))) - --- TODO: why is the caching key an Option? -trim Ideal := Ideal => opts -> (cacheValue (symbol trim => opts)) ((I) -> ideal trim(module I, opts)) -trim Module := Module => opts -> (cacheValue symbol trim) (M -> ( - if isFreeModule M then return M; - c := runHooks((trim, Module), (opts, M)); - if c =!= null then c else error "trim: no method implemented for this type of module")) - --- FIXME: This is kind of a hack. The strategies should be separated in trimHelper -trimHelper = ((opts, M) -> ( +trim Ring := Ring => o -> identity +trim QuotientRing := Ring => o -> R -> quotient trim(ideal presentation R, o) + +-- TODO: the strategies should be separated +trim Ideal := Ideal => opts -> I -> ideal trim(module I, opts) +trim Module := Module => opts -> M -> if isFreeModule M then M else cacheHooks( + (symbol trim, opts), M, (trim, Module), (opts, M), (opts, M) -> ( + if opts.Strategy === null then opts = opts ++ { Strategy => Complement }; -- we preserve the ambient free module of which M is subquotient and try to minimize the generators and relations -- without computing an entire gb -- does using "complement" as in "mingens Module" above offer a benefit? @@ -244,9 +236,6 @@ trimHelper = ((opts, M) -> ( N.cache.trim = N; N)) -addHook((trim, Module), Strategy => Inhomogeneous, (opts, M) -> trimHelper(opts ++ {Strategy => Inhomogeneous}, M)) -addHook((trim, Module), Strategy => Complement, (opts, M) -> trimHelper(opts ++ {Strategy => Complement}, M)) - trimPID := M -> if M.?relations then (if M.?generators then trimPID image generators M else ambient M) / trimPID image relations M else if not M.?generators then M else ( f := presentation M; (g,ch) := smithNormalForm(f, ChangeMatrix => {true, false}); @@ -266,6 +255,7 @@ addHook((trim, Module), Strategy => "PID", ) ) +----------------------------------------------------------------------------- syz Matrix := Matrix => opts -> (f) -> ( c := runHooks((syz, Matrix), (opts, f)); diff --git a/M2/Macaulay2/m2/monideal.m2 b/M2/Macaulay2/m2/monideal.m2 index a78db62d76e..59b55295833 100644 --- a/M2/Macaulay2/m2/monideal.m2 +++ b/M2/Macaulay2/m2/monideal.m2 @@ -1,203 +1,158 @@ -- Copyright 1995-2002 by Michael Stillman -needs "basis.m2" -needs "integers.m2" -- for lcm -needs "matrix1.m2" -needs "quotring.m2" -needs "betti.m2" -needs "res.m2" +needs "hilbert.m2" -- for poincare +needs "matrix2.m2" + +----------------------------------------------------------------------------- +-- MonomialIdeal type declaration and basic constructors +----------------------------------------------------------------------------- MonomialIdeal = new Type of Ideal MonomialIdeal.synonym = "monomial ideal" -monomialIdeal = method(TypicalValue => MonomialIdeal,Dispatch => Thing) -numgens MonomialIdeal := I -> I.numgens -raw MonomialIdeal := I -> I.RawMonomialIdeal -generators MonomialIdeal := opts -> (cacheValue symbol generators) ( (I) -> map(ring I, rawMonomialIdealToMatrix raw I) ) -toExternalString MonomialIdeal := (I) -> "monomialIdeal " | toExternalString generators I -ideal MonomialIdeal := (I) -> ideal generators I -isIdeal MonomialIdeal := I -> true +newMonomialIdeal = (R, rawI) -> new MonomialIdeal from { + symbol ring => R, + symbol numgens => rawNumgens rawI, + symbol RawMonomialIdeal => rawI, + symbol cache => new CacheTable, + } -newMonomialIdeal = (R,rawI) -> new MonomialIdeal from { - symbol numgens => rawNumgens rawI, - symbol RawMonomialIdeal => rawI, - symbol cache => new CacheTable, - symbol ring => R - } +monomialIdealOfRow := (i, m) -> newMonomialIdeal(ring m, rawMonomialIdeal(raw m, i)) -monomialIdealOfRow := (i,m) -> newMonomialIdeal(ring m,rawMonomialIdeal(raw m, i)) +monomialIdeal = method(TypicalValue => MonomialIdeal, Dispatch => Thing) +monomialIdeal Matrix := f -> ( + if not isCommutative ring f then error "expected a commutative ring"; + if not isPolynomialRing ring f then error "expected a polynomial ring without quotient elements"; + monomialIdealOfRow(0, flatten f)) -codimopts := { Generic => false } -codim MonomialIdeal := codimopts >> opts -> m -> rawCodimension raw m -codim Module := codimopts >> opts -> (cacheValue (symbol codim => opts)) (M -> runHooks((codim, Module), (opts, M))) -codim Ideal := codimopts >> opts -> I -> codim( cokernel generators I, opts) -codim PolynomialRing := codimopts >> opts -> R -> 0 -codim QuotientRing := codimopts >> opts -> (R) -> codim( cokernel presentation R, opts) +monomialIdeal Ideal := I -> monomialIdeal generators gb I +monomialIdeal Module := M -> monomialIdeal ideal M +monomialIdeal MonomialIdeal := identity -addHook((codim, Module), Strategy => Default, (opts, M) -> ( - R := ring M; - if M == 0 then infinity - else if isField R then 0 - else if R === ZZ then if M ** QQ == 0 then 1 else 0 - else ( - if not opts.Generic and not isAffineRing ring M - then error "codim: expected an affine ring (consider Generic=>true to work over QQ)"; - p := leadTerm gb presentation M; - n := rank target p; - c := infinity; - for i from 0 to n-1 when c > 0 do c = min(c,codim(monomialIdealOfRow(i,p))); - c - codim monomialIdealOfRow(0,matrix{{0_R}}) -- same as c - codim R, except works for iterated rings - ))) +monomialIdeal List := v -> monomialIdeal matrix {splice v} +monomialIdeal Sequence := v -> monomialIdeal toList v +monomialIdeal RingElement := v -> monomialIdeal {v} MonomialIdeal#1 = I -> monomialIdeal 1_(ring I) MonomialIdeal ^ ZZ := MonomialIdeal => (I, n) -> monomialIdeal (ideal I)^n MonomialIdeal ^ Array := MonomialIdeal => (I, e) -> monomialIdeal (ideal I)^e -Ring / MonomialIdeal := (R,I) -> R / ideal I - -monomialIdeal MonomialIdeal := identity - -monomialIdeal Matrix := MonomialIdeal => f -> ( - if numgens target f =!= 1 then error "expected a matrix with 1 row"; - if not isCommutative ring f - then error "expected a commutative ring"; - if not isPolynomialRing ring f - then error "expected a polynomial ring without quotient elements"; - monomialIdealOfRow(0,f)) - -monomialIdeal List := MonomialIdeal => v -> monomialIdeal matrix {splice v} -monomialIdeal Sequence := v -> monomialIdeal toList v +MonomialIdeal + MonomialIdeal := MonomialIdeal => ((I, J) -> newMonomialIdeal(ring I, raw I + raw J)) @@ samering +MonomialIdeal * MonomialIdeal := MonomialIdeal => ((I, J) -> newMonomialIdeal(ring I, raw I * raw J)) @@ samering +MonomialIdeal - MonomialIdeal := MonomialIdeal => ((I, J) -> newMonomialIdeal(ring I, raw I - raw J)) @@ samering -MonomialIdeal == MonomialIdeal := (I,J) -> I === J +MonomialIdeal * Ring := MonomialIdeal => (I, S) -> if ring I === S then I else monomialIdeal(generators I ** S) +Ring * MonomialIdeal := MonomialIdeal => (S, I) -> I ** S -MonomialIdeal == ZZ := (I,i) -> ( - if i === 0 then numgens I == 0 - else if i === 1 then 1 % I == 0 - else error "asked to compare monomial ideal to nonzero integer") -ZZ == MonomialIdeal := (i,I) -> I == i - -MonomialIdeal + MonomialIdeal := MonomialIdeal => (I,J) -> ( - if ring I =!= ring J then error "expected monomial ideals in the same ring"; - newMonomialIdeal(ring I, raw I + raw J)) -MonomialIdeal * MonomialIdeal := MonomialIdeal => (I,J) -> ( - if ring I =!= ring J then error "expected monomial ideals in the same ring"; - newMonomialIdeal(ring I, raw I * raw J)) -MonomialIdeal - MonomialIdeal := MonomialIdeal => (I,J) -> ( - if ring I =!= ring J then error "expected monomial ideals in the same ring"; - newMonomialIdeal(ring I, raw I - raw J)) - -borel MonomialIdeal := MonomialIdeal => (I) -> newMonomialIdeal(ring I, rawStronglyStableClosure raw I) -isBorel MonomialIdeal := Boolean => m -> rawIsStronglyStable raw m - -poincare MonomialIdeal := (cacheValue symbol poincare) (M -> new degreesRing ring M from rawHilbert rawMonomialIdealToMatrix M.RawMonomialIdeal) - -independentSets = method(Options => { Limit => infinity }) -independentSets MonomialIdeal := o -> (M) -> ( - result := newMonomialIdeal(ring M, - rawMaximalIndependentSets(M.RawMonomialIdeal, - if o.Limit === infinity then -1 else o.Limit)); - flatten entries generators result) -independentSets Ideal := o -> (M) -> independentSets(monomialIdeal M,o) +RingElement * MonomialIdeal := ZZ * MonomialIdeal := MonomialIdeal => (r, I) -> monomialIdeal(r * generators I) ----------------------------------------------------------------------------- --- this code below here is by Greg Smith (and partially Mike Stillman) +-- Basic methods (specifically those which are distinct from Ideal) ----------------------------------------------------------------------------- +-- TODO: is degree(MonomialIdeal) faster with 'poincare' or with degree(Ideal)? -expression MonomialIdeal := (I) -> (expression monomialIdeal) unsequence apply(toSequence first entries generators I, expression) - -MonomialIdeal#AfterPrint = MonomialIdeal#AfterNoPrint = (I) -> (MonomialIdeal," of ",ring I) - -monomialIdeal Ideal := MonomialIdeal => (I) -> monomialIdeal generators gb I - -monomialIdeal Module := MonomialIdeal => (M) -> ( - if isSubmodule M and rank ambient M === 1 - then monomialIdeal generators gb M - else error "expected a submodule of a free module of rank 1" - ) +raw MonomialIdeal := I -> I.RawMonomialIdeal +ideal MonomialIdeal := I -> ideal generators I -monomialIdeal RingElement := MonomialIdeal => v -> monomialIdeal {v} -ring MonomialIdeal := I -> I.ring numgens MonomialIdeal := I -> I.numgens -MonomialIdeal _ ZZ := (I,n) -> (generators I)_(0,n) -isMonomialIdeal = method(TypicalValue => Boolean) -isMonomialIdeal Thing := x -> false -isMonomialIdeal MonomialIdeal := (I) -> true -isMonomialIdeal Ideal := (I) -> isPolynomialRing ring I and all(first entries generators I, r -> size r === 1 and leadCoefficient r == 1) +-- monomial ideals are trimmed by construction (c.f the == method below) +trim MonomialIdeal := MonomialIdeal => o -> identity +mingens MonomialIdeal := MonomialIdeal => o -> I -> sort generators I +-- FIXME: for Ideal, this is cached in I.generators +generators MonomialIdeal := o -> I -> I.cache.generators ??= map(ring I, rawMonomialIdealToMatrix raw I) -MonomialIdeal == Ideal := (I,J) -> ideal I == J -Ideal == MonomialIdeal := (I,J) -> I == ideal J +-- arithmetic operations +Matrix % MonomialIdeal := Matrix => (f, I) -> f % forceGB generators I +Matrix // MonomialIdeal := Matrix => (f, I) -> f // forceGB generators I -MonomialIdeal == Ring := (I,R) -> ( - if ring I =!= R then error "expected ideals in the same ring"; - 1_R % I == 0) -Ring == MonomialIdeal := (R,I) -> I == R +RingElement % MonomialIdeal := ZZ % MonomialIdeal := RingElement => (r, I) -> r_(ring I) % forceGB generators I +RingElement // MonomialIdeal := ZZ // MonomialIdeal := RingElement => (r, I) -> r_(ring I) // forceGB generators I -MonomialIdeal + Ideal := Ideal => (I,J) -> ideal I + J -Ideal + MonomialIdeal := Ideal => (I,J) -> I + ideal J +MonomialIdeal == MonomialIdeal := (I, J) -> I === J +MonomialIdeal == ZZ := (I, i) -> ( + if i === 0 then numgens I == 0 else + if i === 1 then 1 % I == 0 else + error "attempted to compare monomial ideal to nonzero integer") +ZZ == MonomialIdeal := (i, I) -> I == i -RingElement * MonomialIdeal := MonomialIdeal => (r,I) -> monomialIdeal (r * generators I) -ZZ * MonomialIdeal := MonomialIdeal => (r,I) -> monomialIdeal (r * generators I) +isMonomialIdeal = method(TypicalValue => Boolean) +isMonomialIdeal Thing := x -> false +isMonomialIdeal Ideal := I -> isPolynomialRing ring I and all(I_*, r -> size r === 1 and leadCoefficient r == 1) +isMonomialIdeal Module := M -> isIdeal M and isMonomialIdeal ideal M +isMonomialIdeal MonomialIdeal := I -> true -MonomialIdeal * Ideal := Ideal => (I,J) -> ideal I * J -Ideal * MonomialIdeal := Ideal => (I,J) -> I * ideal J +-- We use E. Miller's definition for non-square free monomial ideals. +isSquareFree = method(TypicalValue => Boolean) -- could be isRadical? +isSquareFree Module := +isSquareFree Ideal := I -> isMonomialIdeal I and isSquareFree monomialIdeal I +isSquareFree MonomialIdeal := I -> all(I_*, m -> all(first exponents m, i -> i < 2)) -MonomialIdeal * Module := Module => (I,M) -> ideal I * M +-- printing methods +toExternalString MonomialIdeal := I -> "monomialIdeal " | toExternalString generators I +expression MonomialIdeal := I -> (expression monomialIdeal) unsequence apply(toSequence first entries generators I, expression) -MonomialIdeal * Ring := Ideal => (I,S) -> if ring I === S then I else monomialIdeal(I.generators ** S) -Ring * MonomialIdeal := Ideal => (S,I) -> if ring I === S then I else monomialIdeal(I.generators ** S) +MonomialIdeal#AfterPrint = MonomialIdeal#AfterNoPrint = I -> (MonomialIdeal, " of ", ring I) -Matrix % MonomialIdeal := Matrix => (f,I) -> f % forceGB generators I -RingElement % MonomialIdeal := (r,I) -> r % forceGB generators I -ZZ % MonomialIdeal := (r,I) -> r_(ring I) % forceGB generators I +----------------------------------------------------------------------------- +-- codim +----------------------------------------------------------------------------- -Matrix // MonomialIdeal := Matrix => (f,I) -> f // forceGB generators I -RingElement // MonomialIdeal := (r,I) -> r // forceGB generators I -ZZ // MonomialIdeal := (r,I) -> r_(ring I) // forceGB generators I +codimopts := { Generic => false } +codim PolynomialRing := codimopts >> opts -> R -> 0 +codim QuotientRing := codimopts >> opts -> R -> codim(cokernel presentation R, opts) +codim Ideal := codimopts >> opts -> I -> codim(cokernel generators I, opts) +codim MonomialIdeal := codimopts >> opts -> I -> I.cache#(symbol codim => opts) ??= rawCodimension raw I +codim Module := codimopts >> opts -> M -> M.cache#(symbol codim => opts) ??= tryHooks((codim, Module), (opts, M), + (opts, M) -> ( + R := ring M; + if M == 0 then infinity + else if isField R then 0 + else if R === ZZ then if M ** QQ == 0 then 1 else 0 + else ( + if not opts.Generic and not isAffineRing ring M + then error "codim: expected an affine ring (consider Generic=>true to work over QQ)"; + p := leadTerm gb presentation M; + n := rank target p; + c := infinity; + for i from 0 to n-1 when c > 0 do c = min(c,codim(monomialIdealOfRow(i,p))); + c - codim monomialIdealOfRow(0,matrix{{0_R}}) -- same as c - codim R, except works for iterated rings + ))) dim MonomialIdeal := I -> dim ring I - codim I -degree MonomialIdeal := I -> degree cokernel generators I -- maybe it's faster with 'poincare' - -jacobian MonomialIdeal := Matrix => (I) -> jacobian generators I +----------------------------------------------------------------------------- +-- Specialized algorithms for monomial ideals +----------------------------------------------------------------------------- --- TODO: move to res.m2, or add as a strategy -resolution MonomialIdeal := ChainComplex => opts -> I -> resolution ideal I -betti MonomialIdeal := opts -> I -> betti(ideal I,opts) -minimalBetti MonomialIdeal := opts -> I -> minimalBetti(ideal I,opts) +borel MonomialIdeal := MonomialIdeal => (I) -> newMonomialIdeal(ring I, rawStronglyStableClosure raw I) +isBorel MonomialIdeal := Boolean => m -> rawIsStronglyStable raw m -lcm MonomialIdeal := (I) -> (if I.cache.?lcm - then I.cache.lcm - else I.cache.lcm = (ring I) _ (rawMonomialIdealLCM raw I)) +poincare MonomialIdeal := I -> I.cache.poincare ??= new degreesRing ring I from rawHilbert rawMonomialIdealToMatrix raw I - -- We use E. Miller's definition for nonsquare - -- free monomial -- ideals. +independentSets = method(Options => { Limit => infinity }) +independentSets Ideal := List => opts -> I -> independentSets(monomialIdeal I, opts) +independentSets MonomialIdeal := List => opts -> I -> first entries generators newMonomialIdeal( + ring I, rawMaximalIndependentSets(raw I, if opts.Limit === infinity then -1 else opts.Limit)) -protect alexanderDual -alexopts = {Strategy=>0} +lcm MonomialIdeal := I -> I.cache.lcm ??= (ring I) _ (rawMonomialIdealLCM raw I) -dual(MonomialIdeal, List) := alexopts >> o -> (I,a) -> ( - aI := first exponents lcm I; - if aI =!= a then ( - if #aI =!= #a then error ( "expected list of length ", toString (#aI)); - scan(a, aI, (b,c) -> if b> o -> (I,r) -> dual(I,first exponents r,o) +protect AlexanderDual +alexopts = { Strategy => 0 } -dual MonomialIdeal := alexopts >> o -> (I) -> ( - if I.cache#?alexanderDual - then I.cache#alexanderDual - else I.cache#alexanderDual = ( - dual(I, first exponents lcm I, o) - )) +dual MonomialIdeal := alexopts >> o -> I -> dual(I, first exponents lcm I, o) +dual(MonomialIdeal, List) := alexopts >> o -> (I, a) -> I.cache#(AlexanderDual, a) ??= ( + aI := first exponents lcm I; + if aI =!= a then ( + if #aI =!= #a then error("expected list of length ", #aI); + if any(a-aI, i -> i < 0) then error "exponent vector not large enough"); + newMonomialIdeal(ring I, rawAlexanderDual(raw I, a, o.Strategy)) -- 0 is the default algorithm + ) +dual(MonomialIdeal, RingElement) := alexopts >> o -> (I, r) -> dual(I, first exponents r, o) --- TESTING IF A THING IS A SQUARE FREE MONOMIAL IDEAL ---- -isSquareFree = method(TypicalValue => Boolean) -- could be isRadical? --- isSquareFree Thing := x -> false -isSquareFree MonomialIdeal := (I) -> all(first entries generators I, m -> all(first exponents m, i -> i<2)) +----------------------------------------------------------------------------- -- STANDARD PAIR DECOMPOSITION --------------------------- -- algorithm 3.2.5 in Saito-Sturmfels-Takayama @@ -209,13 +164,13 @@ standardPairs(MonomialIdeal, List) := (I,D) -> ( X := generators R; S := {}; k := coefficientRing R; - scan(D, L -> ( + scan(D, L -> ( Y := X; m := vars R; Lset := set L; Y = select(Y, r -> not Lset#?r); m = substitute(m, apply(L, r -> r => 1)); - -- using monoid to create ring to avoid + -- using monoid to create ring to avoid -- changing global ring. A := k (monoid [Y]); phi := map(A, R, substitute(m, A)); diff --git a/M2/Macaulay2/m2/quotring.m2 b/M2/Macaulay2/m2/quotring.m2 index 0a6c22914ff..7619f1b2d31 100644 --- a/M2/Macaulay2/m2/quotring.m2 +++ b/M2/Macaulay2/m2/quotring.m2 @@ -1,6 +1,7 @@ -- Copyright 1996-2006 by Daniel R. Grayson and Michael E. Stillman needs "enginering.m2" +needs "polyrings.m2" needs "matrix1.m2" ----------------------------------------------------------------------------- diff --git a/M2/Macaulay2/m2/set.m2 b/M2/Macaulay2/m2/set.m2 index 883ed7b2801..90085064184 100644 --- a/M2/Macaulay2/m2/set.m2 +++ b/M2/Macaulay2/m2/set.m2 @@ -1,6 +1,7 @@ -- Copyright 1994 by Daniel R. Grayson needs "methods.m2" +needs "shared.m2" -- for union ----------------------------------------------------------------------------- -- Tally and VirtualTally type declarations and basic constructors diff --git a/M2/Macaulay2/packages/BettiCharacters.m2 b/M2/Macaulay2/packages/BettiCharacters.m2 index 693e7529f3a..dd73ca98574 100644 --- a/M2/Macaulay2/packages/BettiCharacters.m2 +++ b/M2/Macaulay2/packages/BettiCharacters.m2 @@ -203,12 +203,8 @@ Character Array := Character => (C,A) -> ( } ) --- character dual --- borrowing default options from alexander dual method -alexopts = {Strategy=>0}; - -- character of dual/contragredient representation with conjugation -dual(Character,RingMap) := Character => alexopts >> o -> (c,phi) -> ( +dual(Character,RingMap) := Character => {} >> o -> (c,phi) -> ( -- check characteristic R := c.ring; if char(R) != 0 then ( @@ -236,7 +232,7 @@ dual(Character,RingMap) := Character => alexopts >> o -> (c,phi) -> ( ) -- character of dual/contragredient representation without conjugation -dual(Character,List) := Character => alexopts >> o -> (c,perm) -> ( +dual(Character,List) := Character => {} >> o -> (c,perm) -> ( n := c.numActors; if #perm != n then ( error "dual: expected permutation size to match character length"; diff --git a/M2/Macaulay2/packages/Macaulay2Doc/doc.m2 b/M2/Macaulay2/packages/Macaulay2Doc/doc.m2 index 104b9584cee..e279f547638 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/doc.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/doc.m2 @@ -89,7 +89,6 @@ document { (symbol*, RingMap, RingMap), (symbol*, RingElement, MutableMatrix), (symbol*, Ring, MonomialIdeal), - (symbol*, MonomialIdeal, Module), (symbol*, MonomialIdeal, MonomialIdeal), (symbol*, RingElement, Ideal), (symbol*, Matrix, Vector), @@ -817,7 +816,6 @@ document { (symbol==, RingElement, Number), (symbol==, Number, RingElement), (symbol==, RingElement, Matrix), - (symbol==, Ideal, MonomialIdeal), (symbol==, GradedModuleMap, ZZ), (symbol==, InfiniteNumber, InfiniteNumber), (symbol==, ZZ, Ring), @@ -825,8 +823,6 @@ document { (symbol==, Matrix, ZZ), (symbol==, ZZ, ChainComplex), (symbol==, ChainComplex, ZZ), - (symbol==, MonomialIdeal, Ring), - (symbol==, Ring, MonomialIdeal), (symbol==, MonomialIdeal, ZZ), (symbol==, Equation, Holder), (symbol==, Holder, Equation), @@ -842,7 +838,6 @@ document { (symbol==, ZZ, Ideal), (symbol==, Ideal, ZZ), (symbol==, Matrix, RingElement), - (symbol==, MonomialIdeal, Ideal), (symbol==, ZZ, GradedModuleMap), (symbol==, GradedModule, GradedModule), (symbol==, Module, ZZ), diff --git a/M2/Macaulay2/packages/Macaulay2Doc/doc10.m2 b/M2/Macaulay2/packages/Macaulay2Doc/doc10.m2 index 30f586bd73e..b2595bcb5a6 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/doc10.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/doc10.m2 @@ -235,7 +235,7 @@ document { } document { -- This node is used as an example in the documentation nodes: Inputs, Outputs - Key => {(resolution, Ideal),(resolution, MonomialIdeal)}, + Key => (resolution, Ideal), Headline => "compute a projective resolution of (the quotient ring corresponding to) an ideal", Usage => "resolution I", Inputs => { diff --git a/M2/Macaulay2/packages/Macaulay2Doc/doc7.m2 b/M2/Macaulay2/packages/Macaulay2Doc/doc7.m2 index d90fa6dc815..29f112be3dd 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/doc7.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/doc7.m2 @@ -346,7 +346,6 @@ document { Key => {(symbol /, Ring, Ideal), (symbol /, Ring, Module), (symbol /, Ring, RingElement), - (symbol /, Ring, MonomialIdeal), (symbol /, Ring, List), (symbol /, Ring, Sequence), (symbol /, Ring, ZZ) diff --git a/M2/Macaulay2/packages/Macaulay2Doc/doc_ideals.m2 b/M2/Macaulay2/packages/Macaulay2Doc/doc_ideals.m2 index 1ecc4fc1658..3b4d0bd79fb 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/doc_ideals.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/doc_ideals.m2 @@ -93,10 +93,7 @@ document { cache information about it, put it in the hash table ", TT "I.cache", "." } document { - Key => {(symbol *,Ideal,Ideal), - (symbol *,Ideal,MonomialIdeal), - (symbol *,MonomialIdeal,Ideal) - }, + Key => (symbol *,Ideal,Ideal), Headline => "product of ideals", Usage => "I * J", Inputs => { "I", "J" => {"in the same ring as ", TT "I"}, @@ -114,10 +111,7 @@ document { SeeAlso => {"ideals"} } document { - Key => {(symbol +,Ideal,Ideal), - (symbol +,Ideal,MonomialIdeal), - (symbol +,MonomialIdeal,Ideal) - }, + Key => (symbol +,Ideal,Ideal), Headline => "sum of ideals", Usage => "I + J", Inputs => { "I", "J" => {"in the same ring as ", TT "I"}, }, diff --git a/M2/Macaulay2/packages/Macaulay2Doc/functions/betti-doc.m2 b/M2/Macaulay2/packages/Macaulay2Doc/functions/betti-doc.m2 index 328259ebe98..9fa3d4bd5c5 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/functions/betti-doc.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/functions/betti-doc.m2 @@ -98,7 +98,6 @@ Node (betti, GradedModule) (betti, ChainComplex) (betti, GroebnerBasis) - (betti, MonomialIdeal) Headline display or modify a Betti diagram Usage @@ -206,7 +205,7 @@ Node Usage betti I Inputs - I:{Ideal,MonomialIdeal} + I:Ideal Weights=>List Outputs :BettiTally diff --git a/M2/Macaulay2/packages/Macaulay2Doc/functions/degree-doc.m2 b/M2/Macaulay2/packages/Macaulay2Doc/functions/degree-doc.m2 index 980d59b8a2a..77a72995b4e 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/functions/degree-doc.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/functions/degree-doc.m2 @@ -15,7 +15,6 @@ document { } undocumented { - (degree, MonomialIdeal), (degree, Number) } diff --git a/M2/Macaulay2/packages/Macaulay2Doc/functions/isIdeal-doc.m2 b/M2/Macaulay2/packages/Macaulay2Doc/functions/isIdeal-doc.m2 index d6fb954b80e..46e568dbcde 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/functions/isIdeal-doc.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/functions/isIdeal-doc.m2 @@ -3,7 +3,7 @@ --- notes: document { - Key => {isIdeal, (isIdeal,Thing), (isIdeal,Module),(isIdeal, Ideal),(isIdeal, MonomialIdeal)}, + Key => {isIdeal, (isIdeal,Thing), (isIdeal,Module),(isIdeal, Ideal)}, Headline => "whether something is an ideal", Usage => "isIdeal I", Inputs => { diff --git a/M2/Macaulay2/packages/Macaulay2Doc/functions/isMonomialIdeal-doc.m2 b/M2/Macaulay2/packages/Macaulay2Doc/functions/isMonomialIdeal-doc.m2 index 13cdcbf5277..49f18ae1880 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/functions/isMonomialIdeal-doc.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/functions/isMonomialIdeal-doc.m2 @@ -3,7 +3,7 @@ --- notes: document { - Key => {isMonomialIdeal, (isMonomialIdeal,Ideal), (isMonomialIdeal,Thing), (isMonomialIdeal,MonomialIdeal)}, + Key => {isMonomialIdeal, (isMonomialIdeal,Ideal), (isMonomialIdeal,Thing), (isMonomialIdeal, Module), (isMonomialIdeal,MonomialIdeal)}, Headline => "whether something is a monomial ideal", Usage => "isMonomialIdeal I", Inputs => { diff --git a/M2/Macaulay2/packages/Macaulay2Doc/functions/isSquareFree-doc.m2 b/M2/Macaulay2/packages/Macaulay2Doc/functions/isSquareFree-doc.m2 index 963b8a1e0d3..8b3b9ae743c 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/functions/isSquareFree-doc.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/functions/isSquareFree-doc.m2 @@ -3,7 +3,10 @@ --- notes: document { - Key => {isSquareFree, (isSquareFree,MonomialIdeal)}, + Key => {isSquareFree, + (isSquareFree, MonomialIdeal), + (isSquareFree, Ideal), + (isSquareFree, Module)}, Headline => "whether something is square free monomial ideal", Usage => "isSquareFree I", Inputs => { diff --git a/M2/Macaulay2/packages/Macaulay2Doc/functions/jacobian-doc.m2 b/M2/Macaulay2/packages/Macaulay2Doc/functions/jacobian-doc.m2 index 0c3a0f9dac5..0a42b69e2a3 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/functions/jacobian-doc.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/functions/jacobian-doc.m2 @@ -39,7 +39,7 @@ document { } } document { - Key => {(jacobian,Ideal),(jacobian, MonomialIdeal)}, + Key => (jacobian, Ideal), Headline => "the Jacobian matrix of the generators of an ideal", Usage => "jacobian I", Inputs => {"I" => " in a polynomial ring"}, diff --git a/M2/Macaulay2/packages/Macaulay2Doc/functions/mingens-doc.m2 b/M2/Macaulay2/packages/Macaulay2Doc/functions/mingens-doc.m2 index 3d66c92cf52..4ae673dea76 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/functions/mingens-doc.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/functions/mingens-doc.m2 @@ -63,7 +63,7 @@ document { } document { - Key => {(mingens,Module),(mingens,Ideal)}, + Key => {(mingens,Module),(mingens,Ideal),(mingens,MonomialIdeal)}, Usage => "mingens I", Inputs => { "I" => "or an ideal" diff --git a/M2/Macaulay2/packages/Macaulay2Doc/functions/minimalBetti-doc.m2 b/M2/Macaulay2/packages/Macaulay2Doc/functions/minimalBetti-doc.m2 index d4b37c16115..97020c1469e 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/functions/minimalBetti-doc.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/functions/minimalBetti-doc.m2 @@ -3,7 +3,6 @@ doc /// minimalBetti (minimalBetti,Ideal) (minimalBetti,Module) - (minimalBetti,MonomialIdeal) [minimalBetti,DegreeLimit] [minimalBetti,LengthLimit] [minimalBetti,Weights] @@ -14,7 +13,7 @@ doc /// B = minimalBetti I B = minimalBetti(I, DegreeLimit=>d, LengthLimit=>len, Weights=>h) Inputs - I:{Ideal,Module,MonomialIdeal} + I:{Ideal,Module} a homogeneous ideal or module in a singly graded polynomial ring or skew commuting polynomial ring over a finite prime field DegreeLimit=>ZZ if given, only compute enough to determine the Betti diagram up to and including the row labelled {\tt d} diff --git a/M2/Macaulay2/packages/Macaulay2Doc/functions/ring-doc.m2 b/M2/Macaulay2/packages/Macaulay2Doc/functions/ring-doc.m2 index 660f463c89e..eb5a2b3e802 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/functions/ring-doc.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/functions/ring-doc.m2 @@ -7,7 +7,7 @@ document { (ring,ChainComplexMap),(ring, GradedModuleMap),(ring, GroebnerBasis),(ring, Number), (ring,Module),(ring,ChainComplex),(ring,Matrix), (ring,MutableMatrix),(ring,Ideal), (ring,CC),(ring,RR),(ring,RRi),(ring,Resolution), - (ring,MonomialIdeal)}, + }, Headline => "get the associated ring of an object", Usage => "ring M", Inputs => {"M" => "an object with a ring associated to it"}, diff --git a/M2/Macaulay2/packages/Macaulay2Doc/functions/symbol-underscore-doc.m2 b/M2/Macaulay2/packages/Macaulay2Doc/functions/symbol-underscore-doc.m2 index 92888e5dd20..87cb0bf8704 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/functions/symbol-underscore-doc.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/functions/symbol-underscore-doc.m2 @@ -317,7 +317,6 @@ document { document { Key => {"generators of ideals and modules", (symbol _, Ideal, ZZ), - (symbol _, MonomialIdeal, ZZ), (symbol _, Module, ZZ), (symbol _, Matrix, ZZ)}, Headline => "", @@ -325,7 +324,7 @@ document { Heading => "Synopsis", Usage => "L_i", Inputs => { - "L" => ofClass{Ideal,MonomialIdeal,Module,Matrix}, + "L" => ofClass{Ideal,Module,Matrix}, "i" => ZZ }, Outputs => { diff --git a/M2/Macaulay2/packages/Saturation.m2 b/M2/Macaulay2/packages/Saturation.m2 index 1e2504ff073..172647405a1 100644 --- a/M2/Macaulay2/packages/Saturation.m2 +++ b/M2/Macaulay2/packages/Saturation.m2 @@ -36,7 +36,6 @@ importFrom_Core { "nonnull", "raw", "rawColon", "rawSaturate", "newMonomialIdeal importFrom_Core { "isComputationDone", "cacheComputation", "fetchComputation", "updateComputation", "cacheHit", "Context", "Computation" } -- TODO: where should these be placed? -trim MonomialIdeal := MonomialIdeal => opts -> (cacheValue (symbol trim => opts)) ((I) -> monomialIdeal trim(module I, opts)) -- TODO: pick a better name and move to interpreter for speed? -- this is similar to override, except: diff --git a/M2/Macaulay2/packages/SimplicialComplexes/Code.m2 b/M2/Macaulay2/packages/SimplicialComplexes/Code.m2 index ed27c856859..1e8d4d3e364 100644 --- a/M2/Macaulay2/packages/SimplicialComplexes/Code.m2 +++ b/M2/Macaulay2/packages/SimplicialComplexes/Code.m2 @@ -525,10 +525,7 @@ isProper SimplicialComplex := Boolean => D -> ( ------------------------------------------------------------------------------ -- Associated chain complexes ------------------------------------------------------------------------------ ---- kludge to access parts of the 'Core' -raw = value Core#"private dictionary"#"raw"; -rawIndices = value Core#"private dictionary"#"rawIndices"; -rawKoszulMonomials = value Core#"private dictionary"#"rawKoszulMonomials"; +importFrom_Core { "raw", "rawIndices", "rawKoszulMonomials" } -- local function lcmM = L -> ( diff --git a/M2/Macaulay2/tests/ComputationsBook/monomialIdeals/test.out.expected b/M2/Macaulay2/tests/ComputationsBook/monomialIdeals/test.out.expected index 94b09e0a262..ff130ba7667 100644 --- a/M2/Macaulay2/tests/ComputationsBook/monomialIdeals/test.out.expected +++ b/M2/Macaulay2/tests/ComputationsBook/monomialIdeals/test.out.expected @@ -172,12 +172,11 @@ o27 = -- code for method: dual(MonomialIdeal,List) | f : FunctionClosure -- {*Function[/Users/dan/src/M2/Macaulay2/m2/monideal.m2:. /Users/dan/src/M2/Macaulay2/m2/option.m2:6:9-6:9 | -- function f: | /Users/dan/src/M2/Macaulay2/m2/monideal.m2:243:44-250:60: --source code: - | dual(MonomialIdeal, List) := alexopts >> o -> (I,a) -> ( + | dual(MonomialIdeal, List) := alexopts >> o -> (I, a) -> I.cache#(AlexanderDual, a) ??= ( | aI := first exponents lcm I; | if aI =!= a then ( - | if #aI =!= #a then error ( "expected list of length ", toString (#aI)); - | scan(a, aI, (b,c) -> if b i < 0) then error "exponent vector not large enough"); | newMonomialIdeal(ring I, rawAlexanderDual(raw I, a, o.Strategy)) -- 0 is the default algorithm | ) | -- option table opts: diff --git a/M2/Macaulay2/tests/normal/000-core.m2 b/M2/Macaulay2/tests/normal/000-core.m2 index a579799e51b..c294984236b 100644 --- a/M2/Macaulay2/tests/normal/000-core.m2 +++ b/M2/Macaulay2/tests/normal/000-core.m2 @@ -812,12 +812,6 @@ assert( degree U3 == 0 ) assert( degree U4 == 0 ) --- -R=ZZ/101[x] -assert(monomialIdeal vars R != 0) -assert(monomialIdeal map(R^1,R^1,0) == 0) - - -- R = ZZ/101[a .. d,Degrees=>{1,2,3,5}] f = vars R @@ -1185,22 +1179,6 @@ F 3 -- assert( 3 === position({a,b,c,d,e,f},i->i===d ) ) - - --- - R = QQ[x,y,z]; - I = monomialIdeal(x^2,y^3,x*y^2*z,y*z^4); - J = polarize(I); - assert(betti res I==betti res J) - - --- - R = QQ[x,y,z]; - I = monomialIdeal(x^2*y^2,y^2*z^2,x*y*z^4); - J = polarize(I, VariableBaseName => "whyNotAWord"); - assert(betti res I==betti res J) - - -- clearAll numgens ZZ diff --git a/M2/Macaulay2/tests/normal/monideal1.m2 b/M2/Macaulay2/tests/normal/monideal1.m2 new file mode 100644 index 00000000000..28c963709a8 --- /dev/null +++ b/M2/Macaulay2/tests/normal/monideal1.m2 @@ -0,0 +1,14 @@ +-- +R=ZZ/101[x] +assert(monomialIdeal vars R != 0) +assert(monomialIdeal map(R^1,R^1,0) == 0) + +-- +R = QQ[x,y,z]; +I = monomialIdeal(x^2,y^3,x*y^2*z,y*z^4); +J = polarize I; +assert(betti res I == betti res J) + +I = monomialIdeal(x^2*y^2,y^2*z^2,x*y*z^4); +J = polarize(I, VariableBaseName => "whyNotAWord"); +assert(betti res I == betti res J)