def test_FreeGroup__init__(): x, y, z = map(Symbol, "xyz") assert len(FreeGroup("x, y, z").generators) == 3 assert len(FreeGroup(x).generators) == 1 assert len(FreeGroup(("x", "y", "z"))) == 3 assert len(FreeGroup((x, y, z)).generators) == 3
def simplify_presentation(*args, **kwargs): ''' For an instance of `FpGroup`, return a simplified isomorphic copy of the group (e.g. remove redundant generators or relators). Alternatively, a list of generators and relators can be passed in which case the simplified lists will be returned. By default, the generators of the group are unchanged. If you would like to remove redundant generators, set the keyword argument `change_gens = True`. ''' change_gens = kwargs.get("change_gens", False) if len(args) == 1: if not isinstance(args[0], FpGroup): raise TypeError("The argument must be an instance of FpGroup") G = args[0] gens, rels = simplify_presentation(G.generators, G.relators, change_gens=change_gens) if gens: return FpGroup(gens[0].group, rels) return FpGroup(FreeGroup([]), []) elif len(args) == 2: gens, rels = args[0][:], args[1][:] if not gens: return gens, rels identity = gens[0].group.identity else: if len(args) == 0: m = "Not enough arguments" else: m = "Too many arguments" raise RuntimeError(m) prev_gens = [] prev_rels = [] while not set(prev_rels) == set(rels): prev_rels = rels while change_gens and not set(prev_gens) == set(gens): prev_gens = gens gens, rels = elimination_technique_1(gens, rels, identity) rels = _simplify_relators(rels, identity) if change_gens: syms = [g.array_form[0][0] for g in gens] F = free_group(syms)[0] identity = F.identity gens = F.generators subs = dict(zip(syms, gens)) for j, r in enumerate(rels): a = r.array_form rel = identity for sym, p in a: rel = rel * subs[sym]**p rels[j] = rel return gens, rels
def test_FreeGroup__getitem__(): assert F[0:] == FreeGroup("x, y, z") assert F[1:] == FreeGroup("y, z") assert F[2:] == FreeGroup("z")
def test_simplify_presentation(): # ref #16083 G = simplify_presentation(FpGroup(FreeGroup([]), [])) assert not G.generators assert not G.relators
import networkx as nx from graphs.oriented_labelled_graph_with_basepoint import OrientedLabelledGraphWithBasePoint from graphs.graph_from_free_group_factory import GraphFromFreeGroupFactory, CoreGraph from sympy.combinatorics.free_groups import FreeGroup, FreeGroupElement from itertools import product, combinations from typing import Iterable from utilities.general_utilities import memorize n = 3 generators_string = ",".join(["a%d" % d for d in range(1, n+1)]) F = FreeGroup(generators_string) a1, a2, a3 = F.generators free_group_graph = GraphFromFreeGroupFactory.get_subgroup_core(F.generators) def get_edge_crosses(graph, element): path = graph.get_membership_path(element) edge_crosses = {} for x in path: u, v, n, s = x if s.ext_rep[1] < 0: u2 = u u = v v = u2 generator = s if s.ext_rep[1] > 0 else s.inverse() edge_id = (u, v, n, generator) if edge_id not in edge_crosses: edge_crosses[edge_id] = 0