def descendant_subgroups(S, C, R1_c_list, x, R2, N, Y): A_dict = C.A_dict A_dict_inv = C.A_dict_inv if C.is_complete(): # if C is complete then it only needs to test # whether the relators in R2 are satisfied for w, alpha in product(R2, C.omega): if not C.scan_check(alpha, w): return # relators in R2 are satisfied, append the table to list S.append(C) else: # find the first undefined entry in Coset Table for alpha, x in product(range(len(C.table)), C.A): if C.table[alpha][A_dict[x]] is None: # this is "x" in pseudo-code (using "y" makes it clear) undefined_coset, undefined_gen = alpha, x break # for filling up the undefine entry we try all possible values # of beta in Omega or beta = n where beta^(undefined_gen^-1) is undefined reach = C.omega + [C.n] for beta in reach: if beta < N: if beta == C.n or C.table[beta][ A_dict_inv[undefined_gen]] is None: try_descendant(S, C, R1_c_list, R2, N, undefined_coset, \ undefined_gen, beta, Y)
def update(f, sugar, P): """Add f with sugar ``sugar`` to S, update P.""" if not f: return P k = len(S) S.append(f) Sugars.append(sugar) LMf = sdm_LM(f) def removethis(pair): i, j, s, t = pair if LMf[0] != t[0]: return False tik = sdm_monomial_lcm(LMf, sdm_LM(S[i])) tjk = sdm_monomial_lcm(LMf, sdm_LM(S[j])) return tik != t and tjk != t and sdm_monomial_divides(tik, t) and \ sdm_monomial_divides(tjk, t) # apply the chain criterion P = [p for p in P if not removethis(p)] # new-pair set N = [(i, k, Ssugar(i, k), sdm_monomial_lcm(LMf, sdm_LM(S[i]))) for i in range(k) if LMf[0] == sdm_LM(S[i])[0]] # TODO apply the product criterion? N.sort(key=ourkey) remove = set() for i, p in enumerate(N): for j in range(i + 1, len(N)): if sdm_monomial_divides(p[3], N[j][3]): remove.add(j) # TODO mergesort? P.extend(reversed([p for i, p in enumerate(N) if i not in remove])) P.sort(key=ourkey, reverse=True) # NOTE reverse-sort, because we want to pop from the end return P