One Hat Cyber Team
Your IP :
216.73.216.115
Server IP :
194.44.31.54
Server :
Linux zen.imath.kiev.ua 4.18.0-553.77.1.el8_10.x86_64 #1 SMP Fri Oct 3 14:30:23 UTC 2025 x86_64
Server Software :
Apache/2.4.37 (Rocky Linux) OpenSSL/1.1.1k
PHP Version :
5.6.40
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
Macaulay2
/
Core
/
View File Name :
newring.m2
-- Copyright 1996 Michael E. Stillman needs "galois.m2" needs "monoids.m2" needs "quotring.m2" needs "ringmap.m2" needs "rings.m2" needs "matrix2.m2" -- for lift ---------------------------------- -- new polynomial ring or quotient ring from old -- ---------------------------------- -- TODO: rewrite this to be easier to manage with degree group nothing := symbol nothing newRing = method( Options => applyValues(monoidDefaults, x -> nothing), TypicalValue => Ring ) newRing PolynomialRing := opts -> (R) -> ( opts = new MutableHashTable from select(new HashTable from opts, v -> v =!= nothing); nullify := k -> opts#k ??= monoidDefaults#k; if opts.?DegreeRank then nullify \ {Heft, Degrees, DegreeGroup}; if opts.?Degrees then nullify \ {Heft, DegreeRank, DegreeGroup}; if opts.?DegreeGroup then nullify \ {Heft, DegreeRank}; if opts.?Variables then ( if instance(opts.Variables,List) then ( opts.Variables = splice opts.Variables; if # opts.Variables =!= numgens R then nullify Degrees; ) else if instance(opts.Variables,ZZ) then ( if opts.Variables =!= numgens R then nullify Degrees; )); (coefficientRing R)(monoid [merge(options R,new OptionTable from opts,last)])) newRing QuotientRing := opts -> R -> ( p := presentation R; A := ring p; if not instance(A,PolynomialRing) then error "newRing: expected ambient ring of quotient ring to be a polynomial ring"; S := newRing(A, opts); if numgens S != numgens R then error "newRing: cannot change the number of variables"; S / image substitute(p,vars S)) ----------------------------- -- tensor product of rings -- ----------------------------- -- made a method and documented elsewhere. Ring ** Ring := Ring => (R,S) -> tensor(R,S) Ring^** ZZ := Ring => (R, n) -> BinaryPowerMethod(R, n, tensor, R -> coefficientRing R, R -> error "Ring ^** ZZ: expected non-negative integer") tensor(Ring, Ring) := Ring => monoidTensorDefaults >> opts -> (R, S) -> ( if R === (try coefficientRing S) then return S; if S === (try coefficientRing R) then return R; if R === QQ and ZZ === (try coefficientRing S) then ( (A,f) := flattenRing S; T := QQ monoid A; I := ideal A; B := ring I; p := map(T,B); return T/p I); if S === QQ and ZZ === (try coefficientRing R) then return tensor(S,R); error "tensor product not implemented for these rings" ) PolynomialRing ** PolynomialRing := QuotientRing ** PolynomialRing := PolynomialRing ** QuotientRing := QuotientRing ** QuotientRing := (R,S) -> tensor(R,S) tensor(PolynomialRing, PolynomialRing) := tensor(QuotientRing, PolynomialRing) := tensor(PolynomialRing, QuotientRing) := tensor(QuotientRing, QuotientRing) := monoidTensorDefaults >> optns -> (R, S) -> ( k := coefficientRing R; if k =!= coefficientRing S then error "expected rings to have the same coefficient ring"; f := presentation R; A := ring f; M := monoid A; m := numgens M; g := presentation S; B := ring g; N := monoid B; n := numgens N; AB := k tensor(M, N, optns); fg := substitute(f,(vars AB)_{0 .. m-1}) | substitute(g,(vars AB)_{m .. m+n-1}); -- forceGB fg; -- if the monomial order chosen doesn't restrict, then this -- is an error!! MES RS := AB/image fg; setupPromote map(RS,R,(vars AB)_{0 .. m-1}); setupLift map(R,RS,generators A | toList(n:0)); if S =!= R then ( setupPromote map(RS,S,(vars AB)_{m .. m+n-1}); setupLift map(S,RS,toList(m:0) | generators B); ); RS ) ------------------------- -- Graph of a ring map -- ------------------------- graphIdeal = method( Options => apply( {MonomialOrder, MonomialSize, VariableBaseName}, o -> o => monoidDefaults#o )) graphRing = method( Options => options graphIdeal ) graphIdeal RingMap := Ideal => opts -> (cacheValue (symbol graphIdeal => opts)) ((f) -> ( -- return the ideal in the tensor product of the graph of f. -- if f is graded, then set the degrees correctly in the tensor ring. -- return the ideal (y_i - f_i : all i) in this ring. S := source f; R := target f; m := numgens R; n := numgens S; k := coefficientRing R; if not isCommutative S then error "expected source of ring map to be a commutative ring"; if S === k then return ideal map(R^1,R^0,0); if not isAffineRing R then error "expected an affine ring"; if not isAffineRing S then error "expected an affine ring"; if not ( k === coefficientRing S ) then error "expected polynomial rings over the same ring"; gensk := generators(k, CoefficientRing => ZZ); if not all(gensk, x -> promote(x,R) == f promote(x,S)) then error "expected ring map to be identity on coefficient ring"; RS := tensor(R,S, opts, MonomialOrder => Eliminate m, DegreeGroup => degreeGroup R, Degrees => join(degrees R, apply(degrees S, f.cache.DegreeMap)), Heft => heft R); v := vars RS; yv := v_{m .. m+n-1}; xv := v_{0 .. m-1}; h := f.matrix_{0 .. n - 1}; I := ideal(yv - substitute(h, xv)); assert(not isHomogeneous f or isHomogeneous I); I)) graphRing RingMap := QuotientRing => opts -> (f) -> ( I := graphIdeal(f,opts); (ring I)/I ) ----------------------------------------------------------------------------- -- flattenRing ----------------------------------------------------------------------------- -- Copyright 2006 by Daniel R. Grayson coerce = method(Dispatch=>{Thing,Type}) -- this might be generally useful to the user, as the mathematical analogue of new...from... coerce(Thing,Thing) := (x,Y) -> if instance(x,Y) then x else error("no method for coercing result to type ", toString Y) coerce(Ideal,Ring) := quotient @@ first coerce(Thing,Nothing) := (x,Nothing) -> null -- avoid using this one, to save time earlier coerce(Ring,Ideal) := (R,Ideal) -> ideal R -- avoid using this one, to save time earlier preprocessResultTemplate = (narrowers,r) -> ( if instance(r,ZZ) then r = r:null; r = apply(sequence r,x -> if x === null then Thing else x); if #r == 0 then return r; if not all(r, T -> instance(T,Type)) then error "expected Result option to be a type or a sequence of types or nulls"; r = apply(#r, i -> if narrowers#?i and ancestor(r#i,narrowers#i) then narrowers#i else r#i ); toSequence r) coerceResults = (resultTemplate,results) -> ( if #resultTemplate > #results then error( if #results === 1 then ( "only 1 result is available" ) else ( "only ", toString(#results), " results are available" ) ); unsequence apply(take(results,#resultTemplate),resultTemplate,coerce)) flatCoerce = (R,resultTemplate,results) -> ( (X,p,q) := results; -- assert( instance(X,Ideal) or instance(X,Ring)); A := if instance(X,Ideal) then ring X else X; -- assert( instance(p,RingMap) ); -- assert( instance(q,RingMap) ); -- assert( A === target p and A === source q ); -- assert( R === source p and R === target q ); if instance(X,Ideal) and ancestor(Ring,resultTemplate#0) then ( X = quotient X; if X =!= target p then p = map(X,source p,promote(matrix p,X)); if X =!= source q then q = map(target q,X,q); ); if instance(X,Ring) and not ancestor(Ring,resultTemplate#0) then ( X = ideal X; B := ring X; if B =!= target p then p = map(B,source p,lift(matrix p,B)); if B =!= source q then q = map(target q,B,q); ); if instance(X,Ring) then ( p.cache.inverse = q; q.cache.inverse = p; ); coerceResults(resultTemplate,(X,p,q))) -- flattening rings (like (QQ[a,b]/a^3)[x,y]/y^6 --> QQ[a,b,x,y]/(a^3,y^6) flattenRing = method( Options => { Result => (Thing,RingMap), CoefficientRing => null -- the default is to take the latest (declared) field or basic ring in the list of base rings }) unable := () -> error "unable to flatten ring over given coefficient ring" -- in general, fraction fields are not finitely presented over smaller coefficient rings -- maybe we'll do something later when we have localization as something more intrinsic -- flattenRing FractionField := opts -> F -> ... triv := R -> ( idR := map(R,R); idR.cache.inverse = idR; (R,idR,idR)) flattenRing Ring := opts -> R -> ( resultTemplate := preprocessResultTemplate(1:Ring, opts.Result); k := opts.CoefficientRing; if k === R or k === null and (R.?isBasic or isField R) then flatCoerce(R,resultTemplate,triv R) else unable()) flattenRing GaloisField := opts -> (cacheValue (symbol flattenRing => opts)) (F -> ( resultTemplate := preprocessResultTemplate(1:Ring, opts.Result); A := ambient F; (X,p,q) := flattenRing(A, opts, Result => (resultTemplate#0,,)); (p,q) = (map(target p, F, p), map(F, source q, q)); flatCoerce(F,resultTemplate,(X,p,q)))) flatQuotient := method() flatQuotient(Ring,Ideal) := (R,I) -> R/I flatQuotient(QuotientRing,Ideal) := (R,I) -> flatQuotient(ambient R,lift(I,ambient R)) flattenRing Ideal := opts -> (cacheValue (symbol flattenRing => opts)) (J -> ( resultTemplate := preprocessResultTemplate(1:Ideal, opts.Result); R := ring J; (I,p,q) := flattenRing(R,opts,Result => (Ideal,,)); I = if ring I === R then J else I + p J; flatCoerce(ring J, resultTemplate,(I,p,q)))) flattenRing QuotientRing := opts -> (cacheValue (symbol flattenRing => opts)) (R -> ( resultTemplate := preprocessResultTemplate(1:Ring, opts.Result); if instance(ambient R, PolynomialRing) and ( k := coefficientRing R; opts.CoefficientRing === null and (isField k or k.?isBasic) or opts.CoefficientRing === k ) then return flatCoerce(R, resultTemplate,triv R); J := ideal presentation R; A := ring J; (I,p,q) := flattenRing(A,opts,Result => (Ideal,,)); I = I + p J; p = map(target p, R, matrix p); q = map(R, source q, promote(matrix q,R)); r := flatCoerce(R, resultTemplate,(I,p,q)))) flattenRing PolynomialRing := opts -> (cacheValue (symbol flattenRing => opts)) (R -> ( resultTemplate := preprocessResultTemplate(1:Ring, opts.Result); if instance(resultTemplate,VisibleList) then apply(resultTemplate,x -> if x === null then Thing else x); A := coefficientRing R; Q := ultimate(ambient,R); J := lift(ideal map(R^1,R^0,0), Q); M := monoid R; n2 := numgens M; if opts.CoefficientRing === A or opts.CoefficientRing === null and (isField A or A.?isBasic) then return flatCoerce(R, resultTemplate,triv R); (I,p,q) := flattenRing(A, opts, Result => (Ideal,,)); S := ring I; (n1,T) := ( if instance(S,PolynomialRing) then ( numgens monoid S, (coefficientRing S) tensor(M,monoid S) ) else ( 0, S M )); I' := ( (map(T, Q, vars T)) J + (map(T,S,(vars T)_(toList (n2 .. n2 + n1 - 1)))) I ); (p,q) = (map(T,R, vars T), map(R,T, vars R | promote(matrix q,R))); r := flatCoerce(R, resultTemplate,(I',p,q)))) isWellDefined RingMap := f -> ( R := source f; (S,p,q) := flattenRing(R,Result=>3); T := ambient S; I := ideal S; g := f * q * map(S,T); g I == 0) -- Local Variables: -- compile-command: "make -C $M2BUILDDIR/Macaulay2/m2 " -- End: