def setUp(self): self.max_length = 2 self.x = GroupTerm([Literal('x')]) self.y = GroupTerm([Literal('y')]) self.generators = {Literal('x'), Literal('y')} self.truncated_group = TruncatedFreeGroup(self.max_length, self.generators)
def extends_to_total_order(self): if GroupTerm([]) in self.positives: return False assert GroupTerm([]) not in self.complement if all([t in self.positives or t.inv() in self.positives for t in self.complement]): return True # now there exists t in ambient_set such that neither # t nor t^{-1} are in positives. assert self.complement != set() candidates = [t for t in self.complement if t not in self.positives and t.inv() not in self.positives] assert candidates != [] t = candidates[0] # t is now a candidate to extend with. assert t not in self.positives and t.inv() not in self.positives for s in [t, t.inv()]: new_set = MultiplicativelyClosedSet(self.positives.copy(), self.max_length, True) new_set.add(s) new_complement = self.complement.copy() new_complement.remove(s) child = PartialOrder(new_set, self.truncated_group, new_complement) if child.extends_to_total_order(): return True return False
def extends_to_total_order(self): if GroupTerm([]) in self.positives: return False assert GroupTerm([]) not in self.complement if not self.complement: return True # now there exists t in ambient_set such that neither # t nor t^{-1} are in positives. assert self.complement != set() t = min(self.complement, key=len) # t is now a candidate to extend with. assert t not in self.positives and t.inv() not in self.positives for s in [t, t.inv()]: new_set = MultiplicativelyClosedSet(self.positives.copy(), self.max_length, True) new_set.add(s) new_complement = self.complement.copy() new_complement -= new_set.elements | { x.inv() for x in new_set.elements } child = PartialOrder(new_set, self.truncated_group, new_complement) if child.extends_to_total_order(): return True return False
def setUp(self) -> None: self.parser = Parser("(x)") self.x = Atom(GroupTerm([Literal('x')])) self.y = Atom(GroupTerm([Literal('y')])) self.z = Atom(GroupTerm([Literal('z')])) self.xyz = self.x.prod(self.y).prod(self.z) self.e = Atom(GroupTerm([]))
def test_replace(self): x = Literal('x') y = Literal('y') z = Literal('z') term = GroupTerm([x, y.inv(), z]).replace_under_bijection([x, y, z], [z, x, y]) string = str(term) self.assertEqual(GroupTerm([z, x.inv(), y]), term, "expected zXy but got " + str(term))
def reduce(self): new_factors = [] # strip identities for factor in self.factors: if not factor.is_identity(): new_factors.append(factor) self.factors = new_factors # absorb products i = 0 while i < len(self.factors): if self.factors[i].is_prod(): self.factors = self.factors[:i] + self.factors[ i].factors + self.factors[i + 1:] else: i += 1 # multiply together consecutive factors that are atoms i = 0 while i < len(self.factors) - 1: if self.factors[i].is_atom() and self.factors[i + 1].is_atom(): self.factors[i] = Atom(self.factors[i].atom.times( self.factors[i + 1].atom)) del self.factors[i + 1] else: i += 1 if len(self.factors) == 1: for t in self.factors: self.cast_to(t) self.reduce() if len(self.factors) == 0: self.cast_to(Atom(GroupTerm([])))
def _split_atom(atom, counter) -> Join: if len(atom) <= 3: return atom first_literals = atom.atom.literals[:2] + [Literal('x0', False)] last_literals = [Literal('x' + str(len(atom) - 4), True)] + atom.atom.literals[-2:] first_meetand = Atom(GroupTerm(first_literals)) last_meetand = Atom(GroupTerm(last_literals)) joinands = {first_meetand, last_meetand} for mid in atom.atom.literals[2:-2]: pre = Literal('x' + str(counter.current), True) post = Literal('x' + str(counter.step()), False) joinands.add(Atom(GroupTerm([pre, mid, post]))) return Join(joinands)
def __init__(self, positives: MultiplicativelyClosedSet, truncated_group: TruncatedFreeGroup, complement=None): assert positives.max_length == truncated_group.max_length self.max_length = positives.max_length self.positives = positives.elements self.truncated_group = truncated_group if complement is None: self.complement = truncated_group.elements.copy() self.complement -= self.positives if GroupTerm([]) in self.complement: self.complement.remove(GroupTerm([])) else: self.complement = complement assert GroupTerm([]) not in self.complement
def add(self, element: GroupTerm): assert self.unchecked_pairs == [] assert element.__len__() <= self.max_length self.unchecked_pairs = [(element, t) for t in self.elements] \ + [(t, element) for t in self.elements] \ + [(element, element)] self.unchecked_pairs.append((element, element)) self.elements.add(element) self.close()
class TestPartialOrder(TestCase): def setUp(self): self.max_length = 2 self.x = GroupTerm([Literal('x')]) self.y = GroupTerm([Literal('y')]) self.generators = {Literal('x'), Literal('y')} self.truncated_group = TruncatedFreeGroup(self.max_length, self.generators) def test_extends(self): positives = MultiplicativelyClosedSet({self.x, self.y.inv()}, self.max_length) order = PartialOrder(positives, self.truncated_group) self.assertTrue(order.extends_to_total_order()) def test_extends2(self): positives = MultiplicativelyClosedSet({self.x, self.x.inv()}, self.max_length) order = PartialOrder(positives, self.truncated_group) self.assertFalse(order.extends_to_total_order())
def parse_atom(self) -> Atom: assert self.meet_delimiter not in self.string assert self.join_delimiter not in self.string assert self.inv_character not in self.string literals = [] for char in self.string: if char.lower() == 'e': pass elif char.isupper(): literals.append(Literal(char.lower(), True)) else: literals.append(Literal(char)) return Atom(GroupTerm(literals))
def construct(self): if self.max_length >= 0: self.elements.add(GroupTerm([])) if self.max_length >= 1: self.elements |= {GroupTerm([x]) for x in self.generators} \ | {GroupTerm([x.inv()]) for x in self.generators} if self.max_length >= 2: shorter_elements = TruncatedFreeGroup(self.max_length - 1, self.generators).elements # seems to break down when shorter_elements has more than 100 000 elements. self.elements = shorter_elements \ | {GroupTerm([x]).times(t) for x in self.generators for t in shorter_elements} \ | {t.times(GroupTerm([x])) for x in self.generators for t in shorter_elements} \ | {t.times(GroupTerm([x.inv()])) for x in self.generators for t in shorter_elements} \ | {GroupTerm([x.inv()]).times(t) for x in self.generators for t in shorter_elements}
def __init__(self, max_length: int, generators: Set[Literal]): self.max_length = max_length self.generators = generators self.elements = set() if max_length >= 0: self.elements.add(GroupTerm([])) if max_length >= 1: self.elements |= {GroupTerm([x]) for x in generators} \ | {GroupTerm([x.inv()]) for x in generators} if max_length >= 2: shorter_elements = TruncatedFreeGroup(max_length - 1, generators).elements self.elements = shorter_elements \ | {GroupTerm([x]).times(t) for x in generators for t in shorter_elements} \ | {t.times(GroupTerm([x])) for x in generators for t in shorter_elements} \ | {t.times(GroupTerm([x.inv()])) for x in generators for t in shorter_elements} \ | {GroupTerm([x.inv()]).times(t) for x in generators for t in shorter_elements}
def __init__(self, max_length: int, generators: Set[Literal]): self.max_length = max_length self.generators = generators self.elements = set() if max_length >= 0: self.elements.add(GroupTerm([])) if max_length >= 1: self.elements |= {GroupTerm([x]) for x in generators} \ | {GroupTerm([x.inv()]) for x in generators} if max_length >= 2: shorter_elements = TruncatedFreeGroup(max_length - 1, generators).elements # seems to break down when shorter_elements has more than 100 000 elements. VERY SLOW!!!!!!!! self.elements = shorter_elements \ | {GroupTerm([x]).times(t) for x in generators for t in shorter_elements} \ | {t.times(GroupTerm([x])) for x in generators for t in shorter_elements} \ | {t.times(GroupTerm([x.inv()])) for x in generators for t in shorter_elements} \ | {GroupTerm([x.inv()]).times(t) for x in generators for t in shorter_elements}
def setUp(self): self.x = Atom(GroupTerm([Literal('x')])) self.y = Atom(GroupTerm([Literal('y')]))
def setUp(self): self.x = Atom(GroupTerm([Literal('x', False)])) self.y = Atom(GroupTerm([Literal('y', False)])) self.z = Atom(GroupTerm([Literal('z', False)])) self.meet = Meet({self.x, self.y, self.z})
def is_identity(self): return self.atom == GroupTerm([])
def test_times(self): self.assertEqual( GroupTerm([]), GroupTerm([self.lit]).times(GroupTerm([self.lit]).inv()))
def test_is_reduced(self): term = GroupTerm([self.lit]) self.assertTrue(term.is_reduced()) term = GroupTerm([self.lit.inv()]) self.assertTrue(term.is_reduced()) term = GroupTerm([]) self.assertTrue(term.is_reduced()) term = GroupTerm([self.lit, self.lit]) self.assertTrue(term.is_reduced())
def test_reduce(self): term = GroupTerm([self.lit, self.lit.inv()]) self.assertEqual(GroupTerm([]), term)
def test_str(self): term = GroupTerm([self.lit, self.lit]) self.assertEqual("aa", term.__str__())
def test_str_identity(self): self.assertEqual('e', GroupTerm([]).__str__())
def setUp(self): self.identity = Atom(GroupTerm([]))
def setUp(self): self.terms = {GroupTerm([Literal('x')]), GroupTerm([Literal('y')])}
def test_validity(self): inequation = LGroupInequation(Atom(GroupTerm([])), self.x.join(self.x.inv())) self.assertTrue(inequation.is_valid()) inequation = LGroupInequation(Atom(GroupTerm([])), self.x) self.assertFalse(inequation.is_valid())