| 1 | """ |
|---|
| 2 | Base class for groups |
|---|
| 3 | """ |
|---|
| 4 | |
|---|
| 5 | #***************************************************************************** |
|---|
| 6 | # Copyright (C) 2005 William Stein <wstein@gmail.com> |
|---|
| 7 | # |
|---|
| 8 | # Distributed under the terms of the GNU General Public License (GPL) |
|---|
| 9 | # |
|---|
| 10 | # This code is distributed in the hope that it will be useful, |
|---|
| 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 13 | # General Public License for more details. |
|---|
| 14 | # |
|---|
| 15 | # The full text of the GPL is available at: |
|---|
| 16 | # |
|---|
| 17 | # http://www.gnu.org/licenses/ |
|---|
| 18 | #***************************************************************************** |
|---|
| 19 | |
|---|
| 20 | doc=""" |
|---|
| 21 | Base class for all groups |
|---|
| 22 | """ |
|---|
| 23 | |
|---|
| 24 | import random |
|---|
| 25 | |
|---|
| 26 | from sage.rings.infinity import infinity |
|---|
| 27 | import sage.rings.integer_ring |
|---|
| 28 | |
|---|
| 29 | cdef class Group(sage.structure.parent_gens.ParentWithGens): |
|---|
| 30 | """ |
|---|
| 31 | Generic group class |
|---|
| 32 | """ |
|---|
| 33 | def __init__(self): |
|---|
| 34 | sage.structure.parent_gens.ParentWithGens.__init__(self, |
|---|
| 35 | sage.rings.integer_ring.ZZ) |
|---|
| 36 | |
|---|
| 37 | def __call__(self, x): |
|---|
| 38 | """ |
|---|
| 39 | Coerce x into this group. |
|---|
| 40 | """ |
|---|
| 41 | raise NotImplementedError |
|---|
| 42 | |
|---|
| 43 | def __contains__(self, x): |
|---|
| 44 | r""" |
|---|
| 45 | True if coercion of $x$ into self is defined. |
|---|
| 46 | """ |
|---|
| 47 | try: |
|---|
| 48 | self(x) |
|---|
| 49 | except TypeError: |
|---|
| 50 | return False |
|---|
| 51 | return True |
|---|
| 52 | |
|---|
| 53 | def category(self): |
|---|
| 54 | """ |
|---|
| 55 | The category of all groups |
|---|
| 56 | """ |
|---|
| 57 | import sage.categories.all |
|---|
| 58 | return sage.categories.all.Groups() |
|---|
| 59 | |
|---|
| 60 | def is_atomic_repr(self): |
|---|
| 61 | """ |
|---|
| 62 | True if the elements of this group have atomic string |
|---|
| 63 | representations. For example, integers are atomic but |
|---|
| 64 | polynomials are not. |
|---|
| 65 | """ |
|---|
| 66 | return False |
|---|
| 67 | |
|---|
| 68 | def is_abelian(self): |
|---|
| 69 | """ |
|---|
| 70 | Return True if this group is abelian. |
|---|
| 71 | """ |
|---|
| 72 | raise NotImplementedError |
|---|
| 73 | |
|---|
| 74 | def order(self): |
|---|
| 75 | """ |
|---|
| 76 | Returns the number of elements of this group, which is either |
|---|
| 77 | a positive integer or infinity. |
|---|
| 78 | """ |
|---|
| 79 | raise NotImplementedError |
|---|
| 80 | |
|---|
| 81 | def is_finite(self): |
|---|
| 82 | """ |
|---|
| 83 | Returns True if this group is finite. |
|---|
| 84 | """ |
|---|
| 85 | return bool(self.order() != infinity) |
|---|
| 86 | |
|---|
| 87 | def __hash__(self): |
|---|
| 88 | return hash(self.__repr__()) |
|---|
| 89 | |
|---|
| 90 | def random_element(self, bound=None): |
|---|
| 91 | """ |
|---|
| 92 | Return a random element of this group. |
|---|
| 93 | """ |
|---|
| 94 | raise NotImplementedError |
|---|
| 95 | |
|---|
| 96 | def quotient(self, H): |
|---|
| 97 | """ |
|---|
| 98 | Return the quotient of this group by the normal subgroup $H$. |
|---|
| 99 | """ |
|---|
| 100 | raise NotImplementedError |
|---|
| 101 | |
|---|
| 102 | cdef class AbelianGroup(Group): |
|---|
| 103 | """ |
|---|
| 104 | Generic abelian group. |
|---|
| 105 | """ |
|---|
| 106 | def is_abelian(self): |
|---|
| 107 | """ |
|---|
| 108 | Return True. |
|---|
| 109 | """ |
|---|
| 110 | return True |
|---|
| 111 | |
|---|
| 112 | |
|---|
| 113 | cdef class FiniteGroup(Group): |
|---|
| 114 | """ |
|---|
| 115 | Generic finite group. |
|---|
| 116 | """ |
|---|
| 117 | def is_finite(self): |
|---|
| 118 | """ |
|---|
| 119 | Return True. |
|---|
| 120 | """ |
|---|
| 121 | return True |
|---|
| 122 | |
|---|
| 123 | def cayley_graph(self): |
|---|
| 124 | from sage.graphs.graph import DiGraph |
|---|
| 125 | arrows = {} |
|---|
| 126 | for g in self: |
|---|
| 127 | for s in self.gens(): |
|---|
| 128 | gs = g*s |
|---|
| 129 | if not gs == g: |
|---|
| 130 | try: |
|---|
| 131 | _ = arrows[g] |
|---|
| 132 | except KeyError: |
|---|
| 133 | arrows[g] = {} |
|---|
| 134 | |
|---|
| 135 | arrows[g][gs] = s |
|---|
| 136 | |
|---|
| 137 | return DiGraph(arrows) |
|---|
| 138 | |
|---|
| 139 | cdef class AlgebraicGroup(Group): |
|---|
| 140 | """ |
|---|
| 141 | Generic algebraic group. |
|---|
| 142 | """ |
|---|