# Declaring variable to be in a particular field/ring/group

Is it possible to have Sage symbolically simplify expressions involving variables subject to the assumption that the variables take values in a defined domain (field/ring/group/etc)?

The closest I've gotten is to declare a dummy polynomial ring over my domain of interest so that its variable has some notion of the domain, e.g.:

Z3=Integers(3)
Dummy.<x> = PolynomialRing(Z3)
3*x

evaluates to "0" as I'd expect, but sage fails to simplify "x^3" to "x", which ISTM should be doable if it really understood that x is a variable in Z/3Z.

Related things I've found in my searches that haven't panned out:
1. var('x', domain=foo) -- apparently foo can only be one of real/complex/positive (where I'd like to be able to say 'Z3' in the example above)
2. assume('x is Z3') - doesn't seem to have any effect.

edit retag close merge delete

Sort by » oldest newest most voted

I think I found a workaround: make x not be the variable of the polynomial ring but rather that of the quotient of that ring by the ideal generated by z^2-z. In other words:

var('X'); x=PolynomialRing(Integers(3), 'X').quotient([X^2-1], 'x').gens()
print x^3==x and x^2==1 and 3*x==0


evals to True

more

What you are telling Sage with the code snippet is a polynomial whose coefficients are in Z/3Z, but you want a symbolic expression where the variable x is integer and whose values are in Z/3Z, or in other words, modulo 3.

sage: assume(x, "integer")
sage: (x^3).mod(3)
x^3


That would be the most natural way to express it but, as you see, the result is wrong. The Pari-style alternative Mod function only accepts numeric input.

Note that with noninteger x the result wold not be x but -3*floor(x^3/3)+x^3.

EDIT: There is an old ticket at trac #9935 that is a prerequisite for such simplifications.

more

Thanks for your answer. I guess there are two issues here: 1) the feature request you point out as #9935 to make mod work with symbolic expressions; and 2) that sage should know that PolynomialRing(Integers(3)) doesn't need to track powers higher than 2 (and generally that PR(I(p)) doesn't need to track powers higher than p-1). Is that natural fallout from #9935 or do you think that deserves its own feature request?

At any rate, it seems the short answer to my original question is "it's not possible (yet)". Unless you can think of a workaround?

I think it would be natural to add this logic to #9935, just like special functions get immediately expanded for specific values, depending on said assumptions here.

1

Some more head-smacking revealed I can take a quotient to get what I wanted; see my self-answer above. Thanks again for your feedback!