Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*- Spaces of valuations
This module provides spaces of exponential pseudo-valuations on integral domains. It currently only provides support for such valuations if they are discrete, i.e., their image is a discrete additive subgroup of the rational numbers extended by `\infty`.
AUTHORS:
- Julian Rüth (2016-10-14): initial version
EXAMPLES::
sage: QQ.valuation(2).parent() Discrete pseudo-valuations on Rational Field
.. NOTE::
Note that many tests not only in this module do not create instances of valuations directly since this gives the wrong inheritance structure on the resulting objects::
sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: from sage.rings.valuation.trivial_valuation import TrivialDiscretePseudoValuation sage: H = DiscretePseudoValuationSpace(QQ) sage: v = TrivialDiscretePseudoValuation(H) sage: v._test_category() Traceback (most recent call last): ... AssertionError: False is not true
Instead, the valuations need to be created through the ``__make_element_class__`` of the containing space::
sage: from sage.rings.valuation.trivial_valuation import TrivialDiscretePseudoValuation sage: v = H.__make_element_class__(TrivialDiscretePseudoValuation)(H) sage: v._test_category()
The factories such as ``TrivialPseudoValuation`` provide the right inheritance structure::
sage: v = valuations.TrivialPseudoValuation(QQ) sage: v._test_category()
""" #***************************************************************************** # Copyright (C) 2016-2017 Julian Rüth <julian.rueth@fsfe.org> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # http://www.gnu.org/licenses/ #*****************************************************************************
r""" The space of discrete pseudo-valuations on ``domain``.
EXAMPLES::
sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: H = DiscretePseudoValuationSpace(QQ) sage: QQ.valuation(2) in H True
.. NOTE::
We do not distinguish between the space of discrete valuations and the space of discrete pseudo-valuations. This is entirely for practical reasons: We would like to model the fact that every discrete valuation is also a discrete pseudo-valuation. At first, it seems to be sufficient to make sure that the ``in`` operator works which can essentially be achieved by overriding ``_element_constructor_`` of the space of discrete pseudo-valuations to accept discrete valuations by just returning them. Currently, however, if one does not change the parent of an element in ``_element_constructor_`` to ``self``, then one can not register that conversion as a coercion. Consequently, the operators ``<=`` and ``>=`` can not be made to work between discrete valuations and discrete pseudo-valuations on the same domain (because the implementation only calls ``_richcmp`` if both operands have the same parent.) Of course, we could override ``__ge__`` and ``__le__`` but then we would likely run into other surprises. So in the end, we went for a single homspace for all discrete valuations (pseudo or not) as this makes the implementation much easier.
.. TODO::
The comparison problem might be fixed by :trac:`22029` or similar.
TESTS::
sage: TestSuite(H).run() # long time
""" r""" TESTS::
sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: isinstance(QQ.valuation(2).parent(), DiscretePseudoValuationSpace) True
""" # A valuation is a map from an additive semigroup to an additive semigroup, however, it # does not preserve that structure. It is therefore only a morphism in the category of sets.
raise ValueError("domain must be an integral domain")
def _abstract_element_class(self): r""" Return an abstract base class for all valuations in this space.
This is used to extend every valuation with a number of generic methods that are independent of implementation details.
Usually, extensions of this kind would be done by implementing an appropriate class ``MorphismMethods`` in the category of this homset. However, there is no category whose arrows are the valuations, so we need to move this magic down to the level of the actual homset.
EXAMPLES::
sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: isinstance(QQ.valuation(2), DiscretePseudoValuationSpace.ElementMethods) # indirect doctest True
"""
r""" Return the ``op`` action of ``S`` on elements in this space.
EXAMPLES::
sage: v = QQ.valuation(2) sage: from operator import mul sage: v.parent().get_action(ZZ, mul) # indirect doctest Right action by Integer Ring on Discrete pseudo-valuations on Rational Field
"""
r""" Return a trivial valuation in this space.
EXAMPLES::
sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: DiscretePseudoValuationSpace(QQ).an_element() # indirect doctest Trivial pseudo-valuation on Rational Field
"""
r""" Return a printable representation of this space.
EXAMPLES::
sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: DiscretePseudoValuationSpace(QQ) # indirect doctest Discrete pseudo-valuations on Rational Field
"""
r""" Return whether ``x`` is a valuation in this space.
EXAMPLES::
sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: H = DiscretePseudoValuationSpace(QQ) sage: H.an_element() in H True sage: QQ.valuation(2) in H True
""" # override the logic from Homset with the original implementation for Parent # which entirely relies on a proper implementation of # _element_constructor_ and coercion maps
r""" Create an element in this space from ``x``.
EXAMPLES::
sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: H = DiscretePseudoValuationSpace(QQ) sage: H(QQ.valuation(2)) 2-adic valuation
""" # override the logic from Homset with the original implementation for Parent # which entirely relies on a proper implementation of # _element_constructor_ and coercion maps
r""" Create an element in this space from ``x``,
EXAMPLES:
We try to convert valuations defined on different domains by changing their base ring::
sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: Z = DiscretePseudoValuationSpace(ZZ) sage: Q = DiscretePseudoValuationSpace(QQ) sage: v = ZZ.valuation(2) sage: v in Q False sage: Q(v) in Q True sage: Q(v) in Z False sage: Z(Q(v)) in Z True
""" except NotImplementedError: pass else: return x raise ValueError("element can not be converted into the space of %r"%(self,))
r""" Provides methods for discrete pseudo-valuations that are added automatically to valuations in this space.
EXAMPLES:
Here is an example of a method that is automagically added to a discrete valuation::
sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: H = DiscretePseudoValuationSpace(QQ) sage: QQ.valuation(2).is_discrete_pseudo_valuation() # indirect doctest True
The methods will be provided even if the concrete type is not created with ``__make_element_class__``::
sage: from sage.rings.valuation.valuation import DiscretePseudoValuation sage: m = DiscretePseudoValuation(H) sage: m.parent() is H True sage: m.is_discrete_pseudo_valuation() True
However, the category framework advises you to use inheritance::
sage: m._test_category() Traceback (most recent call last): ... AssertionError: False is not true
Using ``__make_element_class__``, makes your concrete valuation inherit from this class::
sage: m = H.__make_element_class__(DiscretePseudoValuation)(H) sage: m._test_category()
""" r""" Return whether this valuation is a discrete pseudo-valuation.
EXAMPLES::
sage: QQ.valuation(2).is_discrete_pseudo_valuation() True
"""
def is_discrete_valuation(self): r""" Return whether this valuation is a discrete valuation, i.e., whether it is a :meth:`discrete pseudo valuation <is_discrete_pseudo_valuation>` that only sends zero to `\infty`.
EXAMPLES::
sage: QQ.valuation(2).is_discrete_valuation() True
"""
r""" Return whether this valuation is a discrete pseudo-valuation that does attain `-\infty`, i.e., it is non-trivial and its domain contains an element with valuation `\infty` that has an inverse.
EXAMPLES::
sage: QQ.valuation(2).is_negative_pseudo_valuation() False
""" elif self.domain() in Fields(): return True raise NotImplementedError
def is_trivial(self): r""" Return whether this valuation is trivial, i.e., whether it is constant `\infty` or constant zero for everything but the zero element.
Subclasses need to override this method if they do not implement :meth:`uniformizer`.
EXAMPLES::
sage: QQ.valuation(7).is_trivial() False
""" # the constant infinity return True # not constant on the non-zero elements return True
def uniformizer(self): r""" Return an element in the domain which has positive valuation and generates the value group of this valuation.
EXAMPLES::
sage: QQ.valuation(11).uniformizer() 11
Trivial valuations have no uniformizer::
sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: v = DiscretePseudoValuationSpace(QQ).an_element() sage: v.is_trivial() True sage: v.uniformizer() Traceback (most recent call last): ... ValueError: Trivial valuations do not define a uniformizing element
"""
def value_group(self): r""" Return the value group of this discrete pseudo-valuation, the discrete additive subgroup of the rational numbers which is generated by the valuation of the :meth:`uniformizer`.
EXAMPLES::
sage: QQ.valuation(2).value_group() Additive Abelian Group generated by 1
A pseudo-valuation that is `\infty` everywhere, does not have a value group::
sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: v = DiscretePseudoValuationSpace(QQ).an_element() sage: v.value_group() Traceback (most recent call last): ... ValueError: The trivial pseudo-valuation that is infinity everywhere does not have a value group.
"""
r""" Return the value semigroup of this discrete pseudo-valuation, the additive subsemigroup of the rational numbers which is generated by the valuations of the elements in the domain.
EXAMPLES:
Most commonly, in particular over fields, the semigroup is the group generated by the valuation of the uniformizer::
sage: G = QQ.valuation(2).value_semigroup(); G Additive Abelian Semigroup generated by -1, 1 sage: G in AdditiveMagmas().AdditiveAssociative().AdditiveUnital().AdditiveInverse() True
If the domain is a discrete valuation ring, then the semigroup consists of the positive elements of the :meth:`value_group`::
sage: Zp(2).valuation().value_semigroup() Additive Abelian Semigroup generated by 1
The semigroup can have a more complicated structure when the uniformizer is not in the domain::
sage: v = ZZ.valuation(2) sage: R.<x> = ZZ[] sage: w = GaussValuation(R, v) sage: u = w.augmentation(x, 5/3) sage: u.value_semigroup() Additive Abelian Semigroup generated by 1, 5/3
""" # return the semigroup generated by the elements of the group raise NotImplementedError("can not determine value semigroup of %r"%(self,))
r""" Return an element in the domain of this valuation with valuation ``s``.
EXAMPLES::
sage: v = ZZ.valuation(2) sage: v.element_with_valuation(10) 1024
""" raise NotImplementedError("s must be a multiple of %r but %r is not"%(self.value_group().gen(), s))
def residue_ring(self): r""" Return the residue ring of this valuation, i.e., the elements of non-negative valuation modulo the elements of positive valuation. EXAMPLES::
sage: QQ.valuation(2).residue_ring() Finite Field of size 2 sage: valuations.TrivialValuation(QQ).residue_ring() Rational Field
Note that a residue ring always exists, even when a residue field may not::
sage: valuations.TrivialPseudoValuation(QQ).residue_ring() Quotient of Rational Field by the ideal (1) sage: valuations.TrivialValuation(ZZ).residue_ring() Integer Ring sage: GaussValuation(ZZ['x'], ZZ.valuation(2)).residue_ring() Univariate Polynomial Ring in x over Finite Field of size 2 (using ...)
"""
r""" Return the residue field of this valuation, i.e., the field of fractions of the :meth:`residue_ring`, the elements of non-negative valuation modulo the elements of positive valuation.
EXAMPLES::
sage: QQ.valuation(2).residue_field() Finite Field of size 2 sage: valuations.TrivialValuation(QQ).residue_field() Rational Field
sage: valuations.TrivialValuation(ZZ).residue_field() Rational Field sage: GaussValuation(ZZ['x'], ZZ.valuation(2)).residue_field() Rational function field in x over Finite Field of size 2
"""
def reduce(self, x): r""" Return the image of ``x`` in the :meth:`residue_ring` of this valuation.
EXAMPLES::
sage: v = QQ.valuation(2) sage: v.reduce(2) 0 sage: v.reduce(1) 1 sage: v.reduce(1/3) 1 sage: v.reduce(1/2) Traceback (most recent call last): ... ValueError: reduction is only defined for elements of non-negative valuation
"""
def lift(self, X): r""" Return a lift of ``X`` in the domain which reduces down to ``X`` again via :meth:`reduce`.
EXAMPLES::
sage: v = QQ.valuation(2) sage: v.lift(v.residue_ring().one()) 1
"""
r""" Return the unique extension of this valuation to ``ring``.
EXAMPLES::
sage: v = ZZ.valuation(2) sage: w = v.extension(QQ) sage: w.domain() Rational Field
""" raise ValueError("there is no unique extension of %r from %r to %r"%(self, self.domain(), ring))
r""" Return the extensions of this valuation to ``ring``.
EXAMPLES::
sage: v = ZZ.valuation(2) sage: v.extensions(QQ) [2-adic valuation]
""" if ring is self.domain(): return [self] raise NotImplementedError("extending %r from %r to %r not implemented"%(self, self.domain(), ring))
r""" Return the restriction of this valuation to ``ring``.
EXAMPLES::
sage: v = QQ.valuation(2) sage: w = v.restriction(ZZ) sage: w.domain() Integer Ring
""" raise NotImplementedError("restricting %r from %r to %r not implemented"%(self, self.domain(), ring))
r""" Return this valuation over ``ring``.
Unlike :meth:`extension` or :meth:`restriction`, this might not be completely sane mathematically. It is essentially a conversion of this valuation into another space of valuations.
EXAMPLES::
sage: v = QQ.valuation(3) sage: v.change_domain(ZZ) 3-adic valuation
""" if self.domain().is_subring(ring): return self.extension(ring) if ring.is_subring(self.domain()): return self.restriction(ring) raise NotImplementedError("changing %r from %r to %r not implemented"%(self, self.domain(), ring))
r""" Return this valuation scaled by ``scalar``.
INPUT:
- ``scalar`` -- a non-negative rational number or infinity
EXAMPLES::
sage: v = ZZ.valuation(3) sage: w = v.scale(3) sage: w(3) 3
Scaling can also be done through multiplication with a scalar::
sage: w/3 == v True
Multiplication by zero produces the trivial discrete valuation::
sage: w = 0*v sage: w(3) 0 sage: w(0) +Infinity
Multiplication by infinity produces the trivial discrete pseudo-valuation::
sage: w = infinity*v sage: w(3) +Infinity sage: w(0) +Infinity
""" return self
r""" Return an element in the domain of this valuation which has positive valuation with respect to this valuation but negative valuation with respect to the valuations in ``others``.
EXAMPLES::
sage: v2 = QQ.valuation(2) sage: v3 = QQ.valuation(3) sage: v5 = QQ.valuation(5) sage: v2.separating_element([v3,v5]) 4/15
""" except TypeError: raise ValueError("others must be a list of valuations")
raise ValueError("all valuations must be valuations on %r but %r is a valuation on %r"%(self.domain(), other, other.domain())) raise ValueError("all valuationss must be discrete valuations but %r is not"%(other,)) raise ValueError("all valuations must be non-trivial but %r is not"%(other,))
return self.uniformizer()
# see the proof of Lemma 6.9 in http://www1.spms.ntu.edu.sg/~frederique/antchap6.pdf # ret is an element which separates self and others[:i] # it also separates self and others[i] continue
# combining powers of ret and delta, we produce a # separating element for self and others[:i+1] else: # others[i](ret) > 0 # construct an element which approximates a unit with respect to others[i] # and has negative valuation with respect to others[:i] # When we enter this loop we are essentially out of # luck. The size of the coefficients is likely going # through the roof here and this is not going to # terminate in reasonable time.
r""" Return an element in the domain of this valuation which has positive valuation with respect to this valuation but negative valuation with respect to ``other``.
.. NOTE::
Overriding this method tends to be a nuisance as you need to handle all possible types (as in Python type) of valuations. This is essentially the same problem that you have when implementing operators such as ``+`` or ``>=``. A sufficiently fancy multimethod implementation could solve that here but there is currently nothing like that in Sage/Python.
EXAMPLES::
sage: v2 = QQ.valuation(2) sage: v3 = QQ.valuation(3) sage: v2._strictly_separating_element(v3) 2/3
"""
return numerator
# The following may fail if denominator is not inverible in the domain, # but we don't have a better option this generically. return self.domain()(~denominator)
# We need non-negative integers a and b such that # a*n - b*d > 0 and a*nn - b*dd < 0 # the above becomes b != 0 and a/b > d/n else: # Since n,nn,d,dd are all non-negative this is essentially equivalent to # a/b > d/n and b/a > nn/dd # which is # dd/nn > a/b > d/n assert(dd/nn > d/n) from sage.rings.continued_fraction import continued_fraction ab_cf = [] dn_cf = continued_fraction(d/n) ddnn_cf = continued_fraction(dd/nn) for i, (x,y) in enumerate(zip(dn_cf, ddnn_cf)): if x == y: ab_cf.append(x) elif x < y: if y > x+1 or len(ddnn_cf) > i+1: ab_cf.append(x+1) else: # the expansion of dd/nn is ending, so we can't append x+1 ab_cf.extend([x,1,1]) elif y < x: if x > y+1 or len(dn_cf) > i+1: ab_cf.append(y+1) else: ab_cf.extend([y,1,1]) ab = continued_fraction(ab_cf).value() a,b = ab.numerator(), ab.denominator()
r""" Return an element in the domain of this valuation which has positive valuation with respect to this valuation and higher valuation with respect to this valuation than with respect to ``other``.
.. NOTE::
Overriding this method tends to be a nuisance as you need to handle all possible types (as in Python type) of valuations. This is essentially the same problem that you have when implementing operators such as ``+`` or ``>=``. A sufficiently fancy multimethod implementation could solve that here but there is currently nothing like that in Sage/Python.
EXAMPLES::
sage: v2 = QQ.valuation(2) sage: v3 = QQ.valuation(3) sage: v2._weakly_separating_element(v3) 2
""" raise NotImplementedError("weakly separating element for %r and %r"%(self, other))
r""" Shift ``x`` in its expansion with respect to :meth:`uniformizer` by ``s`` "digits".
For non-negative ``s``, this just returns ``x`` multiplied by a power of the uniformizer `\pi`.
For negative ``s``, it does the same but when not over a field, it drops coefficients in the `\pi`-adic expension which have negative valuation.
EXAMPLES::
sage: v = ZZ.valuation(2) sage: v.shift(1, 10) 1024 sage: v.shift(11, -1) 5
For some rings, there is no clear `\pi`-adic expansion. In this case, this method performs negative shifts by iterated division by the uniformizer and substraction of a lift of the reduction::
sage: R.<x> = ZZ[] sage: v = ZZ.valuation(2) sage: w = GaussValuation(R, v) sage: w.shift(x, 1) 2*x sage: w.shift(2*x, -1) x sage: w.shift(x + 2*x^2, -1) x^2
"""
else: # s < 0 return self.domain()(x / self.uniformizer()**(-s)) else: raise NotImplementedError("can not compute general shifts over non-fields which contain elements of negative valuation")
r""" Return a simplified version of ``x``.
Produce an element which differs from ``x`` by an element of valuation strictly greater than the valuation of ``x`` (or strictly greater than ``error`` if set.)
If ``force`` is not set, then expensive simplifications may be avoided.
EXAMPLES::
sage: v = ZZ.valuation(2) sage: v.simplify(6, force=True) 2 sage: v.simplify(6, error=0, force=True) 0
"""
return self.domain().zero()
r""" Return a lower bound of this valuation at ``x``.
Use this method to get an approximation of the valuation of ``x`` when speed is more important than accuracy.
EXAMPLES::
sage: v = ZZ.valuation(2) sage: v.lower_bound(2^10) 10
"""
r""" Return an upper bound of this valuation at ``x``.
Use this method to get an approximation of the valuation of ``x`` when speed is more important than accuracy.
EXAMPLES::
sage: v = ZZ.valuation(2) sage: v.upper_bound(2^10) 10
"""
r""" Return an approximate inverse of ``x``.
The element returned is such that the product differs from 1 by an element of valuation at least ``precision``.
INPUT:
- ``x`` -- an element in the domain of this valuation
- ``precision`` -- a rational or infinity
EXAMPLES::
sage: v = ZZ.valuation(2) sage: x = 3 sage: y = v.inverse(3, 2); y 3 sage: x*y - 1 8
This might not be possible for elements of positive valuation::
sage: v.inverse(2, 2) Traceback (most recent call last): ... ValueError: element has no approximate inverse in this ring
Of course this always works over fields::
sage: v = QQ.valuation(2) sage: v.inverse(2, 2) 1/2
""" try: return x.inverse_of_unit() except: raise NotImplementedError("can not compute approximate inverse with respect to this valuation")
r""" Return an estimate on the coefficient size of ``x``.
The number returned is an estimate on the factor between the number of Bits used by ``x`` and the minimal number of bits used by an element congruent to ``x``.
This is used by :meth:`simplify` to decide whether simplification of coefficients is going to lead to a significant shrinking of the coefficients of ``x``.
EXAMPLES::
sage: v = Qp(2).valuation() sage: v._relative_size(2) 1
Some valuations do not overwrite this method because simplification does not increase the speed of valuations, e.g., some `p`-adic valuations::
sage: v._relative_size(2**20) 1
"""
r""" Check that :meth:`is_negative_pseudo_valuation` works correctly.
TESTS::
sage: v = ZZ.valuation(3) sage: v._test_is_negative_pseudo_valuation()
"""
if not self.is_negative_pseudo_valuation(): X = self.domain().some_elements() for x in tester.some_elements(X): from sage.rings.all import infinity tester.assertNotEqual(self(x), -infinity)
r""" Check that :meth:`lower_bound` and :meth:`upper_bound` work correctly.
TESTS::
sage: v = ZZ.valuation(3) sage: v._test_bounds()
"""
r""" Check that :meth:`simplify` works correctly.
TESTS::
sage: v = ZZ.valuation(3) sage: v._test_simplify()
"""
except NotImplementedError: # over non-fields (and especially polynomial rings over # non-fields) computation of the residue ring is often # difficult and not very interesting from sage.categories.fields import Fields if self.domain() not in Fields(): return raise
return
y = self.simplify(x, error=s) if self.domain().is_exact(): tester.assertGreaterEqual(self(x-y), s) elif hasattr(y, 'precision_absolute'): tester.assertGreaterEqual(self(x-y), min(s, y.precision_absolute()))
r""" Check that :meth:`shift` works correctly.
TESTS::
sage: v = ZZ.valuation(3) sage: v._test_shift()
""" return
except Exception: # it is not clear what a shift should be in this case return
# it is not clear what a shift should be in this case continue # the shift here sometimes fails if elements implement # __floordiv__ incorrectly, see #23971 tester.assertEqual(x, self.shift(y, -s))
r""" Check that :meth:`scale` works correctly.
TESTS::
sage: v = ZZ.valuation(3) sage: v._test_scale()
"""
r""" Check that the (strict) triangle equality is satisfied for the valuation of this ring.
TESTS::
sage: v = ZZ.valuation(3) sage: v._test_add()
""" tester.assertGreaterEqual(self(x+y),min(self(x),self(y))) if self(x) != self(y): tester.assertEqual(self(x+y),min(self(x),self(y)))
r""" Check that zero is sent to infinity.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_infinite_zero()
"""
r""" Check that multiplication translates to addition of valuations.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_mul()
""" from sage.rings.all import infinity if set([self(x), self(y)]) == set([infinity, -infinity]): continue tester.assertEqual(self(x*y),self(x)+self(y))
r""" Checks that no units are sent to infinity.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_no_infinite_units()
As multiplication translates to addition, pseudo-valuations which send a unit to infinity are necessarily trivial::
sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: v = DiscretePseudoValuationSpace(QQ).an_element() sage: v(1) +Infinity sage: v.is_trivial() True
""" return return
r""" Check correctness of the value group.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_value_group()
""" # check consistency of trivial valuations first if self(self.domain().one()) is infinity: # a trivial pseudo-valuation that sends everything to infinity with tester.assertRaises(ValueError): self.value_group() return
# check that all valuations are in the value group
# check that the uniformizer generates the value group
r""" Check correctness of the value semigroup.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_value_semigroup()
"""
# the trivial pseudo-valuation does not have a value semigroup return
r""" Check correctness of :meth:`element_with_valuation`.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_element_with_valuation()
"""
# the trivial pseudo-valuation does not have a value semigroup return
r""" Check the correctness of residue rings.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_residue_ring()
"""
except NotImplementedError: # over non-fields (and especially polynomial rings over # non-fields) computation of the residue ring is often # difficult and not very interesting from sage.categories.fields import Fields if self.domain() not in Fields(): return raise
# residue ring is the zero rng tester.assertGreater(self(1), 0) return
r""" Check the correctness of reductions.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_reduce()
"""
except NotImplementedError: # over non-fields (and especially polynomial rings over # non-fields) computation of the residue ring is often # difficult and not very interesting from sage.categories.fields import Fields if self.domain() not in Fields(): return raise
r""" Check the correctness of lifts.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_lift()
"""
except NotImplementedError: # over non-fields (and especially polynomial rings over # non-fields) computation of the residue ring is often # difficult and not very interesting from sage.categories.fields import Fields if self.domain() not in Fields(): return raise
r""" Check the correctness of reductions.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_restriction()
"""
r""" Check the correctness of extensions.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_extension()
"""
r""" Check the correctness of :meth:`change_domain`.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_change_domain()
"""
r""" Check that only zero is sent to infinity.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_no_infinite_nonzero()
""" return
r""" Check the correctness of residue fields.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_residue_field()
""" return
except ValueError: from sage.categories.fields import Fields # a discrete valuation on a field has a residue field tester.assertFalse(self.domain() in Fields()) return except NotImplementedError: # over non-fields (and especially polynomial rings over # non-fields) computation of the residue ring is often # difficult and not very interesting from sage.categories.fields import Fields if self.domain() not in Fields(): return raise
r""" Check the correctness of the ``>=`` operator.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_ge()
"""
return
r""" Check the correctness of the ``<=`` operator.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_le()
"""
return
r""" Check the correctness of :meth:`inverse`.
TESTS::
sage: v = QQ.valuation(5) sage: v._test_inverse()
"""
continue
r""" Action of integers, rationals and the infinity ring on valuations by scaling it.
EXAMPLES::
sage: v = QQ.valuation(5) sage: from operator import mul sage: v.parent().get_action(ZZ, mul, self_on_left=False) Left action by Integer Ring on Discrete pseudo-valuations on Rational Field
""" r""" Let ``s`` act on ``v``.
EXAMPLES::
sage: v = QQ.valuation(5) sage: 3*v # indirect doctest 3 * 5-adic valuation
""" # for a right action, the parameters are swapped |