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 -*- Value groups of discrete valuations
This file defines additive sub(semi-)groups of `\QQ` and related structures.
AUTHORS:
- Julian Rüth (2013-09-06): initial version
EXAMPLES::
sage: v = ZZ.valuation(2) sage: v.value_group() Additive Abelian Group generated by 1 sage: v.value_semigroup() Additive Abelian Semigroup generated by 1
""" #***************************************************************************** # Copyright (C) 2013-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 codomain of discrete valuations, the rational numbers extended by `\pm\infty`.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValuationCodomain sage: C = DiscreteValuationCodomain(); C Codomain of Discrete Valuations
TESTS::
sage: TestSuite(C).run() # long time
""" r""" TESTS::
sage: from sage.rings.valuation.value_group import DiscreteValuationCodomain sage: isinstance(QQ.valuation(2).codomain(), DiscreteValuationCodomain) True
"""
r""" Create an element from ``x``.
INPUT:
- ``x`` -- a rational number or `\infty`
TESTS::
sage: from sage.rings.valuation.value_group import DiscreteValuationCodomain sage: DiscreteValuationCodomain()(0) 0 sage: DiscreteValuationCodomain()(infinity) +Infinity sage: DiscreteValuationCodomain()(-infinity) -Infinity
""" raise ValueError("must be a rational number or infinity")
r""" Return a printable representation.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValuationCodomain sage: DiscreteValuationCodomain() # indirect doctest Codomain of Discrete Valuations
"""
r""" The value group of a discrete valuation, an additive subgroup of `\QQ` generated by ``generator``.
INPUT:
- ``generator`` -- a rational number
.. NOTE::
We do not rely on the functionality provided by additive abelian groups in Sage since these require the underlying set to be the integers. Therefore, we roll our own \Z-module here. We could have used :class:`AdditiveAbelianGroupWrapper` here, but it seems to be somewhat outdated. In particular, generic group functionality should now come from the category and not from the super-class. A facade of \Q appeared to be the better approach.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: D1 = DiscreteValueGroup(0); D1 Trivial Additive Abelian Group sage: D2 = DiscreteValueGroup(4/3); D2 Additive Abelian Group generated by 4/3 sage: D3 = DiscreteValueGroup(-1/3); D3 Additive Abelian Group generated by 1/3
TESTS::
sage: TestSuite(D1).run() # long time sage: TestSuite(D2).run() # long time sage: TestSuite(D3).run() # long time
""" def __classcall__(cls, generator): r""" Normalizes ``generator`` to a positive rational so that this is a unique parent.
TESTS::
sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(1) is DiscreteValueGroup(-1) True
"""
r""" TESTS::
sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: isinstance(DiscreteValueGroup(0), DiscreteValueGroup) True
"""
# We can not set the facade to DiscreteValuationCodomain since there # are some issues with iterated facades currently
r""" Create an element in this group from ``x``.
INPUT:
- ``x`` -- a rational number
TESTS::
sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(0)(0) 0 sage: DiscreteValueGroup(0)(1) Traceback (most recent call last): ... ValueError: `1` is not in Trivial Additive Abelian Group. sage: DiscreteValueGroup(1)(1) 1 sage: DiscreteValueGroup(1)(1/2) Traceback (most recent call last): ... ValueError: `1/2` is not in Additive Abelian Group generated by 1.
"""
r""" Return a printable representation for this group.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(0) # indirect doctest Trivial Additive Abelian Group
"""
r""" Return the subgroup of `\QQ` generated by this group and ``other``.
INPUT:
- ``other`` -- a discrete value group or a rational number
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: D = DiscreteValueGroup(1/2) sage: D + 1/3 Additive Abelian Group generated by 1/6 sage: D + D Additive Abelian Group generated by 1/2 sage: D + 1 Additive Abelian Group generated by 1/2 sage: DiscreteValueGroup(2/7) + DiscreteValueGroup(4/9) Additive Abelian Group generated by 2/63
""" raise ValueError("`other` must be a DiscreteValueGroup or a rational number")
r""" Return the group generated by ``other`` times the generator of this group.
INPUT:
- ``other`` -- a rational number
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: D = DiscreteValueGroup(1/2) sage: 1/2 * D Additive Abelian Group generated by 1/4 sage: D * (1/2) Additive Abelian Group generated by 1/4 sage: D * 0 Trivial Additive Abelian Group
"""
r""" Return the index of ``other`` in this group.
INPUT:
- ``other`` -- a subgroup of this group
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(3/8).index(DiscreteValueGroup(3)) 8 sage: DiscreteValueGroup(3).index(DiscreteValueGroup(3/8)) Traceback (most recent call last): ... ValueError: other must be a subgroup of this group sage: DiscreteValueGroup(3).index(DiscreteValueGroup(0)) Traceback (most recent call last): ... ValueError: other must have finite index in this group sage: DiscreteValueGroup(0).index(DiscreteValueGroup(0)) 1 sage: DiscreteValueGroup(0).index(DiscreteValueGroup(3)) Traceback (most recent call last): ... ValueError: other must be a subgroup of this group
""" raise ValueError("other must be a DiscreteValueGroup") else:
r""" Return the numerator of a generator of this group.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(3/8).numerator() 3
"""
r""" Return the denominator of a generator of this group.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(3/8).denominator() 8
"""
r""" Return a generator of this group.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(-3/8).gen() 3/8
"""
r""" Return some typical elements in this group.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(-3/8).some_elements() [3/8, -3/8, 0, 42, 3/2, -3/2, 9/8, -9/8]
"""
r""" Return whether this is the trivial additive abelian group.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueGroup sage: DiscreteValueGroup(-3/8).is_trivial() False sage: DiscreteValueGroup(0).is_trivial() True
"""
r""" The value semigroup of a discrete valuation, an additive subsemigroup of `\QQ` generated by ``generators``.
INPUT:
- ``generators`` -- rational numbers
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup sage: D1 = DiscreteValueSemigroup(0); D1 Trivial Additive Abelian Semigroup sage: D2 = DiscreteValueSemigroup(4/3); D2 Additive Abelian Semigroup generated by 4/3 sage: D3 = DiscreteValueSemigroup([-1/3, 1/2]); D3 Additive Abelian Semigroup generated by -1/3, 1/2
TESTS::
sage: TestSuite(D1).run() # long time sage: TestSuite(D2).run() # long time sage: TestSuite(D3).run() # long time
""" def __classcall__(cls, generators): r""" Normalize ``generators``.
TESTS:
We do not find minimal generators or something like that but just sort the generators and drop generators that are trivially contained in the semigroup generated by the remaining generators::
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup sage: DiscreteValueSemigroup([1,2]) is DiscreteValueSemigroup([1]) True
In this case, the normalization is not sufficient to determine that these are the same semigroup::
sage: DiscreteValueSemigroup([1,-1,1/3]) is DiscreteValueSemigroup([1/3,-1/3]) False
"""
# this is not very efficient but there should never be more than a # couple of generators
r""" TESTS::
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup sage: isinstance(DiscreteValueSemigroup([0]), DiscreteValueSemigroup) True
"""
# check whether this is trivially a group # is_group() performs a complete check that is very costly and # refines the category
# We can not set the facade to DiscreteValuationCodomain since there # are some issues with iterated facades currently
r""" Return the coefficients of a linear combination to write ``target`` in terms of the generators of this semigroup.
Return ``None`` if no such combination exists.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup sage: D = DiscreteValueSemigroup([2,3,5]) sage: D._solve_linear_program(12) {0: 1, 1: 0, 2: 2} sage: 1*2 + 0*3 + 2*5 12
""" else:
except MIPSolverException: return None
r""" Create an element in this group from ``x``.
INPUT:
- ``x`` -- a rational number
TESTS::
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup sage: DiscreteValueSemigroup([])(0) 0 sage: DiscreteValueSemigroup([])(1) Traceback (most recent call last): ... ValueError: `1` is not in Trivial Additive Abelian Semigroup. sage: DiscreteValueSemigroup([1])(1) 1 sage: DiscreteValueSemigroup([1])(-1) Traceback (most recent call last): ... ValueError: `-1` is not in Additive Abelian Semigroup generated by 1.
"""
r""" Return a printable representation for this semigroup.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup sage: DiscreteValueSemigroup(0) # indirect doctest Trivial Additive Abelian Semigroup
"""
r""" Return the subsemigroup of `\QQ` generated by this semigroup and ``other``.
INPUT:
- ``other`` -- a discrete value (semi-)group or a rational number
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup, DiscreteValueGroup sage: D = DiscreteValueSemigroup(1/2) sage: D + 1/3 Additive Abelian Semigroup generated by 1/3, 1/2 sage: D + D Additive Abelian Semigroup generated by 1/2 sage: D + 1 Additive Abelian Semigroup generated by 1/2 sage: DiscreteValueGroup(2/7) + DiscreteValueSemigroup(4/9) Additive Abelian Semigroup generated by -2/7, 2/7, 4/9
""" raise ValueError("`other` must be a DiscreteValueGroup, a DiscreteValueSemigroup or a rational number")
r""" Return the semigroup generated by ``other`` times the generators of this semigroup.
INPUT:
- ``other`` -- a rational number
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup sage: D = DiscreteValueSemigroup(1/2) sage: 1/2 * D Additive Abelian Semigroup generated by 1/4 sage: D * (1/2) Additive Abelian Semigroup generated by 1/4 sage: D * 0 Trivial Additive Abelian Semigroup
"""
r""" Return the generators of this semigroup.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup sage: DiscreteValueSemigroup(-3/8).gens() (-3/8,)
"""
r""" Return some typical elements in this semigroup.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup sage: list(DiscreteValueSemigroup([-3/8,1/2]).some_elements()) [0, -3/8, 1/2, ...]
""" return
r""" Return whether this is the trivial additive abelian semigroup.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup sage: DiscreteValueSemigroup(-3/8).is_trivial() False sage: DiscreteValueSemigroup([]).is_trivial() True
"""
def is_group(self): r""" Return whether this semigroup is a group.
EXAMPLES::
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup sage: DiscreteValueSemigroup(1).is_group() False sage: D = DiscreteValueSemigroup([-1, 1]) sage: D.is_group() True
Invoking this method also changes the category of this semigroup if it is a group::
sage: D in AdditiveMagmas().AdditiveAssociative().AdditiveUnital().AdditiveInverse() True
""" else: |