Skip to content
This repository has been archived by the owner on Aug 18, 2021. It is now read-only.

Commit

Permalink
Todd-Coxeter + examples
Browse files Browse the repository at this point in the history
  • Loading branch information
hivert committed Jan 17, 2020
1 parent a20d381 commit ab0039a
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 0 deletions.
48 changes: 48 additions & 0 deletions examples/newpres.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import libsemigroups_cppyy

from libsemigroups_cppyy.todd_coxeter import *

def symgroup(n):
s = ["s%i"%i for i in range(n)]
res = []
for i in range(1,n):
res.append([[s[i],s[i]], [1]])
for i in range(1, n-1):
res.append([[s[i],s[i+1],s[i]], [s[i+1],s[i],s[i+1]]])
for i in range(1, n-2):
for j in range(i+2, n):
res.append([[s[i],s[j]], [s[j],s[i]]])
return s[1:], res
def Hecke0(n):
p = ["pi%i"%i for i in range(n)]
res = []
for i in range(1,n):
res.append([[p[i],p[i]], [1]])
for i in range(1, n-1):
res.append([[p[i],p[i+1],p[i]], [p[i+1],p[i],p[i+1]]])
for i in range(1, n-2):
for j in range(i+2, n):
res.append([[p[i],p[j]], [p[j],p[i]]])
return p[1:], res


N = 5

gs, rs = symgroup(N)
SG = make_cong([1]+gs, rs, identity=1)
SG.run()
SG.standardize(ToddCoxeter.order.shortlex)
clSG = classes_reduced_word_cong(SG)

gs, rs = Hecke0(N)
H0 = make_cong([1]+gs, rs, identity=1)
H0.run()
H0.standardize(ToddCoxeter.order.shortlex)
clH0 = classes_reduced_word_cong(H0)

print (clSG == clH0)





75 changes: 75 additions & 0 deletions libsemigroups_cppyy/todd_coxeter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""
This file contains the interface to the implementation of the
Todd-Coxeter algorithm for finitely presented semigroups in libsemigroups; see
https://libsemigroups.readthedocs.io/en/latest/_generated/libsemigroups__congruence__toddcoxeter.html
for further details.
"""
import cppyy
cppyy.include("cong.hpp")
cppyy.include("cong-intf.hpp")

lsg = cppyy.gbl.libsemigroups
congruence_type = lsg.congruence_type
ToddCoxeter = lsg.congruence.ToddCoxeter

def make_cong(lgen, rels, identity=None):
"""
Build a congruence
each generator must be hashable.
- `lgen` : the list of generators (must be unique)
- `rels` : a list of pairs of tuple
- `identity` : the identity if known
if `rels` contains a generator which is not in `lgen`, it will be appended.
"""
if len(set(lgen)) != len(lgen):
raise ValueError("duplicate generator")
if identity is not None and identity not in lgen:
lgen.append(identity)
for rel in rels:
for w in rel:
for g in w:
if g not in lgen:
lgen.append(g)
res = ToddCoxeter(lsg.congruence_type.twosided)
res.set_nr_generators(len(lgen))
def add_pair(a,b) :
# print("Adding : (%s, %s)"%(a,b))
res.add_pair(a,b)
if identity is not None:
idd = lgen.index(identity)
for ig in range(len(lgen)):
add_pair([ig, idd], [ig])
if idd != ig:
add_pair([idd, ig], [ig])
def iword(w):
return [lgen.index(l) for l in w]
for rel in rels:
trg = iword(rel[0])
for src in rel[1:]:
add_pair(trg, iword(src))
return res


def classes_reduced_word_cong(C):
r"""
returns the list of the classes all the reduced words.
Each classes is stored as a frozenset. in the same order as the
index of `C`.
"""
res = []
for nc in range(C.nr_classes()):
w = C.class_index_to_word(nc)
Cl = []
for wrd in lsg.shortlex_words(C.nr_generators(), w.size(), w.size()):
if (C.word_to_class_index(wrd) == nc):
Cl.append(tuple(wrd))
res.append(frozenset(Cl))
return res

0 comments on commit ab0039a

Please sign in to comment.