We illustrate modules over subrings are implemented through an example. The following is Example 11.19 from "Groebner bases and Convex Polytopes" by Bernd Sturmfels:

i = 2; gndR = QQ[t_1, t_2, t_3]; A := {t_1*t_2*t_3, t_1^2*t_2, t_1*t_2^2, t_1^2*t_3, t_1*t_3^2, t_2^2*t_3, t_2*t_3^2}; G := matrix {{t_1^4*t_2^4*t_3^4, t_1^8*t_2*t_3^6}} subR = subring sagbi subring A; assert((set first entries gens subR) === (set A)); tsyz := toricSyz(subR, G); assert(tsyz * (transpose G) == 0); ans1 = mingensSubring(subR, tsyz); |

The resulting value of `ans1` and its normal form are:

i13 : ans1 o13 = | t_1^4t_3^5 -t_2^3t_3^3 | | t_1^4t_2t_3^4 -t_2^4t_3^2 | | t_1^5t_3^4 -t_1t_2^3t_3^2 | | t_1^5t_2t_3^3 -t_1t_2^4t_3 | | t_1^6t_3^3 -t_1^2t_2^3t_3 | | t_1^6t_2t_3^2 -t_1^2t_2^4 | | t_1^4t_3^8 -t_2^3t_3^6 | 7 2 o13 : Matrix R <--- R |

i14 : ans1//subR o14 = | p_4^2p_7 -p_3p_5 | | p_4^2p_9 -p_5^2 | | p_4p_7^2 -p_3p_8 | | p_4p_7p_9 -p_5p_8 | | p_7^3 -p_5p_9 | | p_7^2p_9 -p_8^2 | | p_4^4 -p_3^3 | 7 2 o14 : Matrix (QQ[p ..p ]) <--- (QQ[p ..p ]) 0 9 0 9 |

The following code illustrates the function mingensSubring:

mingensSubring = method(TypicalValue => Matrix) mingensSubring(Subring, Matrix) := (subR, M) -> ( (A, B, gVars) := moduleToSubringIdeal(subR, M); final := autoreduce(A, transpose B); final = matrix transpose {sort first entries transpose final}; final = extractEntries(final, gVars); subR#"presentation"#"fullSubstitution"(sub(final,subR#"presentation"#"tensorRing")) ); |

The function mingensSubring works by converting the given matrix (which should be thought of as a module) to an ideal inside of a subring, and then performing autoreduction on the generators of that ideal. It relies on the function moduleToSubringIdeal to construct a suitable subring and provide the generators that define this ideal. Consider the output of the following command:

i5 : debugPrintMap (subR#"presentation"#"fullSubstitution") maps p_0 to t_1 maps p_1 to t_2 maps p_2 to t_3 maps p_3 to t_2*t_3^2 maps p_4 to t_1*t_3^2 maps p_5 to t_2^2*t_3 maps p_6 to t_1*t_2*t_3 maps p_7 to t_1^2*t_3 maps p_8 to t_1*t_2^2 maps p_9 to t_1^2*t_2 |

`p_0`, ..., `p_9` are the variables of what is referred to in the code as the `tensorRing`, which has two types of variables: The variables corresponding to the variables in the ambient ring (`p_0`,...,`p_2` in this example) and the variables corresponding to the generators of the Subring (`p_3`,...,`p_9` in this example).

The function moduleToSubringIdeal converts the toric syzygy module from our example (which is returned by toricSyz in the form of a matrix) to an ideal within a subring. This is identical to the moduleToSubringIdeal call that occurs in the first line of mingensSubring.

i15 : (modRing, idealGens, gVars) = moduleToSubringIdeal(subR, tsyz) o15 = (subring of QQ[p_0..p_11], | -p_0^6p_2^3p_10+p_0^2p_1^3p_2p_11 |, | p_10 p_11 |) | -p_0^6p_1p_2^2p_10+p_0^2p_1^4p_11 | | -p_0^6p_2^3p_10+p_0^2p_1^3p_2p_11 | | -p_0^5p_1p_2^3p_10+p_0p_1^4p_2p_11 | | -p_0^5p_2^4p_10+p_0p_1^3p_2^2p_11 | | -p_0^5p_2^4p_10+p_0p_1^3p_2^2p_11 | | -p_0^4p_1p_2^4p_10+p_1^4p_2^2p_11 | | -p_0^4p_2^5p_10+p_1^3p_2^3p_11 | | p_0^8p_2^4p_10-p_0^4p_1^3p_2^2p_11 | | -p_0^7p_2^5p_10+p_0^3p_1^3p_2^3p_11 | | -p_0^5p_2^7p_10+p_0p_1^3p_2^5p_11 | | -p_0^4p_2^8p_10+p_1^3p_2^6p_11 | | -p_0^6p_2^6p_10+p_0^2p_1^3p_2^4p_11 | |

i16 : debugPrintMap(modRing#"presentation"#"fullSubstition") maps p_0 to p_0 maps p_1 to p_1 maps p_2 to p_2 maps p_3 to p_3 maps p_4 to p_4 maps p_5 to p_5 maps p_6 to p_6 maps p_7 to p_7 maps p_8 to p_8 maps p_9 to p_9 maps p_10 to p_10 maps p_11 to p_11 maps p_12 to p_10 maps p_13 to p_11 maps p_14 to p_1*p_2^2 maps p_15 to p_0*p_2^2 maps p_16 to p_1^2*p_2 maps p_17 to p_0*p_1*p_2 maps p_18 to p_0^2*p_2 maps p_19 to p_0*p_1^2 maps p_20 to p_0^2*p_1 |

The ambient ring of `modRing` is the tensor ring of `subR`, except two new variables `p_10` and `p_11` have been added. The variables `p_10` and `p_11` correspond to the generators of the module. The generators `p_12` and `p_13` also correspond to the generators of the module.

The primary reason why this implementation should be considered experimental is that the monomial order of a module is not fully specified: When a Subring instance is created using the function subring, the monomial order of the ambient variables is the same as the monomial order of their corresponding variables in the ambient ring while the monomial order of the variables corresponding to generators is assigned arbitrarily. The problem with this system is that it is likely to cause bugs in the case where a subring's ambient ring is the tensor ring of another subring.

- moduleToSubringIdeal(Subring,Matrix) -- Convert a module as a matrix to a subring ideal.
- mingensSubring(Subring,Matrix) -- Auto reduces matrix elements
- Subring ^ ZZ -- Construct a product subring.