Пример #1
0
    def generate(self, elems):
        """
        Returns the subgroup of self generated by GroupElems elems

        If any of the items aren't already GroupElems, we will try to convert
        them to GroupElems before continuing.

        elems must be iterable
        """

        elems = Set(g if isinstance(g, GroupElem) else GroupElem(g, self) \
                    for g in elems)

        if not elems <= self.group_elems:
            raise ValueError("elems must be a subset of self.group_elems")
        if len(elems) == 0:
            raise ValueError("elems must have at least one element")

        oldG = elems
        while True:
            newG = oldG | Set(a * b for a in oldG for b in oldG)
            if oldG == newG: break
            else: oldG = newG
        oldG = Set(g.elem for g in oldG)

        return Group(oldG, self.bin_op.new_domains(oldG * oldG, oldG))
Пример #2
0
    def __div__(self, other):
        """ Returns the quotient group self / other """
        if not other.is_normal_subgroup(self):
            raise ValueError("other must be a normal subgroup of self")
        G = Set(Set(self.bin_op((g, h)) for h in other.Set) for g in self.Set)

        def multiply_cosets(x):
            h = x[0].pick()
            return Set(self.bin_op((h, g)) for g in x[1])

        return Group(G, Function(G * G, G, multiply_cosets))
Пример #3
0
    def subgroups(self):
        """Returns the Set of self's subgroups"""

        old_sgs = Set([self.generate([self.e])])
        while True:
            new_sgs = old_sgs | Set(self.generate(list(sg.group_elems) + [g]) \
                                     for sg in old_sgs for g in self \
                                     if g not in sg.group_elems)
            if new_sgs == old_sgs: break
            else: old_sgs = new_sgs

        return old_sgs
Пример #4
0
    def test_basics(self):
        s = Set([0, 1, 2, 3])
        t = Set([1, 2, 3, 4])
        f = Function(s, t, lambda x: x + 1)
        str(f)
        for x in range(4):
            self.assertEquals(f(x), x + 1)
        self.assertEquals(f, f)

        with self.assertRaises(TypeError):
            Function([0, 1, 2, 3], t, lambda x: x + 1)
        with self.assertRaises(TypeError):
            Function(s, [1, 2, 3, 4], lambda x: x + 1)
        with self.assertRaises(TypeError):
            Function(s, t, lambda x: x + 2)
Пример #5
0
def Dn(n):
    """Returns the dihedral group of order 2n """
    G = Set("%s%d" % (l, x) for l in "RS" for x in range(n))

    def multiply_symmetries(x):
        l1, l2 = x[0][0], x[1][0]
        x1, x2 = int(x[0][1:]), int(x[1][1:])
        if l1 == "R":
            if l2 == "R":
                return "R%d" % ((x1 + x2) % n)
            else:
                return "S%d" % ((x1 + x2) % n)
        else:
            if l2 == "R":
                return "S%d" % ((x1 - x2) % n)
            else:
                return "R%d" % ((x1 - x2) % n)

    return Group(G, Function(G * G, G, multiply_symmetries))
Пример #6
0
    def __init__(self, G, bin_op):
        """Create a group, checking group axioms"""

        # Test types
        if not isinstance(G, Set): raise TypeError("G must be a set")
        if not isinstance(bin_op, Function):
            raise TypeError("bin_op must be a function")
        if bin_op.codomain != G:
            raise TypeError("binary operation must have codomain equal to G")
        if bin_op.domain != G * G:
            raise TypeError("binary operation must have domain equal to G * G")

        # Test associativity
        if not all(bin_op((a, bin_op((b, c)))) == \
                   bin_op((bin_op((a, b)), c)) \
                   for a in G for b in G for c in G):
            raise ValueError("binary operation is not associative")

        # Find the identity
        found_id = False
        e = None
        for a in G:
            if all(bin_op((a, b)) == b for b in G):
                e = a
                found_id = True
                break
        if not found_id:
            raise ValueError("G doesn't have an identity")

        # Test for inverses
        for a in G:
            if not any(bin_op((a, b)) == e for b in G):
                raise ValueError("G doesn't have inverses")

        # At this point, we've verified that we have a Group.
        # Now determine if the Group is abelian:
        self.abelian = all(bin_op((a, b)) == bin_op((b, a)) \
                           for a in G for b in G)

        self.Set = G
        self.group_elems = Set(GroupElem(g, self) for g in G)
        self.e = GroupElem(e, self)
        self.bin_op = bin_op
Пример #7
0
    def test_simple(self):
        s = Set([0, 1, 2, 3])
        t = Set([1, 2, 3, 4])
        u = Set([0, 1, 2, 3, 4, 5])
        f = Function(s, t, lambda x: x + 1)
        g = Function(t, u, lambda x: x + 1)
        h = g.compose(f)
        i = Function(Set([-1, 0, 1]), Set([0, 1]), lambda x: abs(x))

        self.assertEquals(f.is_surjective(), True)
        self.assertEquals(f.is_injective(), True)
        self.assertEquals(f.is_bijective(), True)
        self.assertEquals(f.image(), t)
        str(f)

        self.assertEquals(g.is_surjective(), False)
        self.assertEquals(g.is_injective(), True)
        self.assertEquals(g.is_bijective(), False)
        self.assertEquals(g.image(), Set([2, 3, 4, 5]))
        str(g)

        self.assertEquals(h.is_surjective(), False)
        self.assertEquals(h.is_injective(), True)
        self.assertEquals(h.is_bijective(), False)
        self.assertEquals(h.image(), Set([2, 3, 4, 5]))
        str(h)

        self.assertEquals(i.is_surjective(), True)
        self.assertEquals(i.is_injective(), False)
        self.assertEquals(i.is_bijective(), False)
        self.assertEquals(i.image(), Set([0, 1]))
        str(i)

        with self.assertRaises(ValueError):
            i.compose(f)
        with self.assertRaises(ValueError):
            f.compose(i)
Пример #8
0
 def is_surjective(self):
     # Need to make self.domain into a Set, since it might not be in
     # subclasses of Function
     return self._image() == Set(self.codomain)
Пример #9
0
 def _image(self):
     """The literal image of the function"""
     return Set(self(elem) for elem in self.domain)
Пример #10
0
def Sn(n):
    """Returns the symmetric group of order n! """
    G = Set(g for g in itertools.permutations(range(n)))
    bin_op = Function(G * G, G, lambda x: tuple(x[0][j] for j in x[1]))
    return Group(G, bin_op)
Пример #11
0
def Zn(n):
    """Returns the cylic group of order n"""
    G = Set(range(n))
    bin_op = Function(G * G, G, lambda x: (x[0] + x[1]) % n)
    return Group(G, bin_op)
Пример #12
0
 def image(self):
     """Returns the image of the homomorphism as a Group object"""
     G = Set(g.elem for g in self._image())
     return Group(G, self.codomain.bin_op.new_domains(G * G, G))
Пример #13
0
 def kernel(self):
     """Returns the kernel of the homomorphism as a Group object"""
     G = Set(g.elem for g in self.domain if self(g) == self.codomain.e)
     return Group(G, self.domain.bin_op.new_domains(G * G, G))
Пример #14
0
 def multiply_cosets(x):
     h = x[0].pick()
     return Set(self.bin_op((h, g)) for g in x[1])
Пример #15
0
 def is_normal_subgroup(self, other):
     """Checks if self is a normal subgroup of other"""
     return self <= other and \
            all(Set(g * h for h in self) == Set(h * g for h in self) \
                for g in other)
Пример #16
0
 def test_identity(self):
     s = Set(["las", 3, "ksjfdlka"])
     ID = identity(s)
     str(ID)
     for item in s:
         self.assertEquals(ID(item), item)