This is the code that searchs for a friend.
# Imports
import snappy
import regina
import csv
import sys
from IPython.display import display, clear_output #used as in-calculation feedback
# for timing
import time
# for exponential function
import math
# for random choices
import random
#### Snappy extensions #####
def all_positive(manifold):
'''
Checks if the solution type of a triangulation is positive.
'''
return manifold.solution_type() == 'all tetrahedra positively oriented'
def find_positive_triangulations(manifold,number=1,tries=100):
'''
Searches for one triangulation with a positive solution type.
(Or if number is set to a different value also for different such triangulations.)
'''
M = manifold.copy()
pos_triangulations=[]
for i in range(tries):
if all_positive(M):
pos_triangulations.append(M)
if len(pos_triangulations)==number:
return pos_triangulations
break
M.randomize()
for d in M.dual_curves(max_segments=500):
try:
X = M.drill(d)
X = X.filled_triangulation()
X.dehn_fill((1,0),-1)
for i in range(tries):
if all_positive(X):
pos_triangulations.append(X)
if len(pos_triangulations)==number:
return pos_triangulations
break
X.randomize()
except (snappy.SnapPeaFatalError,RuntimeError):
pass
# In the closed case, here is another trick.
if all(not c for c in M.cusp_info('is_complete')):
for i in range(tries):
# Drills out a random edge
X = M.__class__(M.filled_triangulation())
if all_positive(X):
pos_triangulations.append(X)
if len(pos_triangulations)==number:
return pos_triangulations
break
M.randomize()
return pos_triangulations
def better_is_isometric_to(X,Y,index=50,try_hard=False):
"""
Returns True if X and Y are isometric.
Returns False if X and Y appear to be different.
"""
for i in (0,index):
w=False
try:
w=X.is_isometric_to(Y)
if w==True:
return w
except (RuntimeError,snappy.SnapPeaFatalError):
pass
X.randomize()
Y.randomize()
if try_hard:
pos_triang_X=find_positive_triangulations(X,number=1,tries=index)
pos_triang_Y=find_positive_triangulations(Y,number=1,tries=index)
for X in pos_triang_X:
for Y in pos_triang_Y:
w=better_is_isometric_to(X,Y,index=100,try_hard=False)
if w==True:
return w
return w
# Checking for knot complements
def is_homology_solid_torus(manifold):
'''
Checks if the input manifold has homology Z.
'''
M=snappy.Manifold(manifold)
if M.homology().coefficients!=[0]:
return False
return True
def is_knot_complement(manifold,index=2):
'''
Checks the short fillings to be S3.
'''
assert manifold.num_cusps() == 1
if manifold.homology().elementary_divisors() != [0]:
return False
try:
slopes = manifold.short_slopes(3.5)[0]
except RuntimeError:
slopes = []
(a, b) = manifold.homological_longitude()
slopes = [s for s in slopes if abs(a*s[1] - b*s[0]) == 1]
for s in slopes:
M = snappy.Triangulation(manifold)
M.dehn_fill(s)
if is_three_sphere(M,tries=index):
return True
return False
def is_three_sphere(manifold,tries=2):
"""
True means the manifold is definitely S^3.
False means it is *likely* not S^3.
"""
T = manifold
order = T.homology().order()
if order == 'infinite' or order > 1:
return False
G = snappy.Manifold(T)
if G.solution_type(enum=True) == 1:
return False
for i in range(tries):
if T.fundamental_group().num_generators() == 0:
return True
F = T.filled_triangulation()
if F.fundamental_group().num_generators() == 0:
return True
T.randomize()
return False
def better_length_spectrum(manifold,max_length=5.0,index=10,high_precision=False):
'''Computes the length spectrum of the input manifold up to the given max_length.
Index gives the number of tries and high_precision increases the precision.'''
M=snappy.Manifold(manifold)
if high_precision:
M=M.high_precision()
for i in range(index):
try:
return M.length_spectrum(cutoff=max_length,include_words=True)
except RuntimeError:
M.randomize()
return False
#regina functions
def to_regina(data):
'''
This function was written by Dunfield.
It sends a SnapPy triangulation to regina.
'''
if hasattr(data, '_to_string'):
data = data._to_string()
if isinstance(data, str):
if data.find('(') > -1:
data = closed_isosigs(data)[0]
return regina.Triangulation3(data)
assert isinstance(data, regina.Triangulation3)
return data
def display_check(sig, tri):
iso_signatures.append(sig)
if len(iso_signatures)>maximum:
return True
#It stops if we have too many signatures
return False
def drill_edges(T,index=0,verbose=False,cores=1,max_submanifolds=100,max_triangulations=10,randomized=False):
'''
Takes as input a regina triangulation and drills out edges and returns a list of its signatures.
'''
global iso_signatures
iso_signatures=[]
global maximum
maximum=max_triangulations
if index < 0:
ctr=0
while len(iso_signatures) < (-1)*index and ctr < 1000:
ctr+=1
T = randomise(T, 100, 2/T.size())
if not T.isoSig() in iso_signatures:
iso_signatures.append(T.isoSig())
else:
T.retriangulate(index,cores,display_check)
if verbose:
print('Found',len(iso_signatures),'triangulations')
drilled=[]
if randomized==False:
for sig in iso_signatures:
Y=regina.Triangulation3(sig)
for e in range(Y.edges().size()):
X=regina.Triangulation3(sig)
X.pinchEdge(X.edge(e))
if X.homology().isZ():
X.intelligentSimplify()
drilled.append(X.isoSig())
if len(drilled)>max_submanifolds:
if verbose:
print('Number of submanifolds found:',len(drilled))
return drilled
if randomized==True:
l=len(iso_signatures)
for i in range(max_submanifolds):
sig=iso_signatures[random.randint(0,l-1)]
Y=regina.Triangulation3(sig)
for e in range(Y.edges().size()):
X=regina.Triangulation3(sig)
X.pinchEdge(X.edge(e))
if X.homology().isZ():
X.intelligentSimplify()
drilled.append(X.isoSig())
if len(drilled)>max_submanifolds:
if verbose:
print('Number of submanifolds found:',len(drilled))
return drilled
if verbose:
print('Number of submanifolds found:',len(drilled))
return drilled
#####################################################################
#####################################################################
# functions for random walk
#####################################################################
#####################################################################
def choosemove(T, beta):
x = random.random()
if x < math.exp((-1)*beta*T.size()):
a = 1
else:
a = 2
# setup done
# go up (2-3)
# most triangles correspond to a valid move, no need to classify
if a == 1:
tri = random.choice(range(T.countTriangles()))
if T.pachner(T.triangle(tri),True,False):
S = regina.Triangulation3(T)
S.pachner(S.triangle(tri),False,True)
return S
# go down
elif a == 2:
# get all possible 3-2 moves
valid = []
for e in range(T.countEdges()):
if T.pachner(T.edge(e),True,False):
valid.append(e)
if valid != []:
S = regina.Triangulation3(T)
S.pachner(S.edge(random.choice(valid)),False,True)
return S
# nothing worked
return T
def randomise(T, steps, beta):
# initialise number of steps
st = 0
while st < steps:
st += 1
T = choosemove(T,beta)
return T
#####################################################################
#####################################################################
# end functions for random walk
#####################################################################
#####################################################################
def search_for_friend(knot,effort='low',max_number_of_friends=1,Regina=True,SnapPy_dual_curves=True,SnapPy_length_spectrum=True,MCMC=True,verbose=False):
'''
This functions takes as input a triangulation of the exterior of a knot K and searchs for friends of K.
(If it is not a knot exterior it still searchs for a knot F on S3 such that 0-surgery on F yields the
homological filling on K.)
Method:
First we create the 0-surgery K(0,1) of K.
Then we create a list of knot complements in K(0,1). We use the 6-theorem to check if that knot complement
has a filling to S3 and thus represents a knot F in S3. If that knot appears to not be isometric to K,
we return F.
WARNING: It is then not rigoursly proven that F and K are different. But that will usually be the case.
It needs to be double-checked for example using the volume or another knot invariant.
There are three options to create the list of knot complements in K(0,1).
(1) SnapPy_dual_curves=True:
This drills out dual curves of a triangulation of K(0,1)
(which only works if the triangulation yields a hyperbolic structure).
(2) SnapPy_length_spectrum=True:
Uses the verified length spectrum computation of K(0,1) and drills out short geodesics from K(0,1).
(3) Regina=True:
This creates a one-vertex triangulation of K(0,1) in regina and then drills out edges of that triangulation. Uses
Regina retriangulate function to go through Pachner graph in breadth first search
(4) MCMC=True:
Same as (3), but the next triangulation is found by a random walk rather than by breadth first search in the Pachner
graph (as done by "retriangulate").
If Regina is not installed put regina=False. In general it is recommended to use all three methods, since there
exist friends that can only be found effectively with one of the methods.
Options:
We can put effort='low','medium', 'high' to choose pre-chosen values of parameters to search for friends.
Or one can put effort=None and choose the parameters freely. See the documentation in the code for that.
The other options affect the runtime and efficiency of the code:
--
How fast the code will run depends of course heavily on the input triangulation.
The default options are choosen for maximal efficiency. But if one wants to search harder for friends one
should increase the parameters. The following options have turned out to run reasonable fast and find
most friends on reasonable small examples.
'''
#We have the following parameters:
#General:
random=True #If true chooses random dual_curves, geodesics, edges to drill.
random_upper_bound=100 #Number of random elements that we drill.
exterior_index=2 #Number of tries to check if a drilled out object is a knot complement.
try_hard=False #If True it searches very hard for an isometry of a potential friend to K.
isometry_index=5 #Number of tries to check if two manifolds are isometric
#For drilling dual curves:
max_segments=100 #Maximal number of segements in dual curves.
upper_bound_dual_curves=2000 #An upper bound on the number of dual curves that we check.
#For drilling geodesics
max_length=5.0 #maximal length of a geodesic in the length spectrum.
high_precision=False #If true uses high precision to compute the length spectrum.
recursion_limit=50000 #The recursion limit for drilling out geodesics.
upper_bound_geodesics=2000 #Upper bound on the number of geodesics we check
#For drilling edges with regina:
regina_simplify=False #Simplifies the input triangulation if set to True
regina_retriangulate_index=2 #The maximal difference of the number of simplices of a triangulation from the input triangulation.
regina_cores_used=1 #If this number gets increased regina uses more cores and the code runs quicker but might also crush your computer.
max_regina_submanifolds=5000 #The maximal number of submanifolds that regina creates.
maximal_number_of_Pachner_moves=250 #The maximal number of Pachner moves regina performs to create more triangulations.
if effort=='low':
random=False
random_upper_bound=100
exterior_index=1
try_hard=False
isometry_index=1
max_segments=6
upper_bound_dual_curves=15
max_length=1.0
high_precision=False
recursion_limit=10000
upper_bound_geodesics=15
regina_simplify=True
regina_retriangulate_index=0
regina_cores_used=1
max_regina_submanifolds=50
maximal_number_of_Pachner_moves=10
rounds = 10
if effort=='medium':
random=False
random_upper_bound=100
exterior_index=2
try_hard=False
isometry_index=2
max_segments=25
upper_bound_dual_curves=100
max_length=3.0
high_precision=False
recursion_limit=40000
upper_bound_geodesics=100
regina_simplify=True
regina_retriangulate_index=0
regina_cores_used=1
max_regina_submanifolds=100
maximal_number_of_Pachner_moves=10
rounds = 30
if effort=='high':
random=False
random_upper_bound=100
exterior_index=2
try_hard=False
isometry_index=2
max_segments=50
upper_bound_dual_curves=250
max_length=4.0
high_precision=False
recursion_limit=50000
upper_bound_geodesics=250
regina_simplify=True
regina_retriangulate_index=2
regina_cores_used=1
max_regina_submanifolds=5000
maximal_number_of_Pachner_moves=100
rounds = 1000
if verbose:
print('We have choosen the following parameters to search for friends:')
print('random',random)
print('random_upper_bound',random_upper_bound)
print('exterior_index',exterior_index)
print('try_hard',try_hard)
print('isometry_index',isometry_index)
print('max_segments',max_segments)
print('upper_bound_dual_curves',upper_bound_dual_curves)
print('max_length',max_length)
print('high_precision',high_precision)
print('recursion_limit',recursion_limit)
print('upper_bound_geodesics',upper_bound_geodesics)
print('regina_simplify',regina_simplify)
print('regina_retriangulate_index',regina_retriangulate_index)
print('regina_cores_used',regina_cores_used)
print('max_regina_submanifolds',max_regina_submanifolds)
print('maximal_number_of_Pachner_moves',maximal_number_of_Pachner_moves)
print('number of rounds for random walk',rounds)
print('--------------')
#M is the knot exterior and K the 0-filling
M=snappy.Manifold(knot)
K=snappy.Manifold(knot)
if is_homology_solid_torus(K)==False:
raise ValueError('The homology of K is not Z and thus it is not a knot in S3.')
K.dehn_fill(K.homological_longitude())
#Lists of possible knot exteriors and friends
possible_knot_exteriors=[]
friends=[]
##### SNAPPY DUAL CURVES ######
if SnapPy_dual_curves:
dual_curves=K.dual_curves(max_segments=max_segments)
if verbose:
print('--------------')
print('We check dual curves with SnapPy and search for a friend.')
print('Number of dual curves:',len(dual_curves))
if random==False:
if verbose:
print('We check all dual curves.')
for c in dual_curves:
try:
E=K.drill(c)
E=E.filled_triangulation()
if better_is_isometric_to(E,M,index=isometry_index)==False:
if is_homology_solid_torus(E)==True:
already_known=False
for X in possible_knot_exteriors:
if better_is_isometric_to(X,E,index=isometry_index):
already_known=True
break
if already_known==False:
if verbose:
print('We found a new potential knot exterior:',E)
possible_knot_exteriors.append(E)
if verbose:
print('Checking for knot complement:',E)
if is_knot_complement(E,index=exterior_index):
if better_is_isometric_to(E,M,try_hard=try_hard)==False:
already_known=False
for X in friends:
if better_is_isometric_to(X,E,index=isometry_index,try_hard=try_hard):
already_known=True
break
if already_known==False:
if verbose:
print('We found a friend:',E)
friends.append(E)
if len(friends)>max_number_of_friends-1:
if verbose:
print('Number of potential knot exteriors checked:',len(possible_knot_exteriors))
print('Number of friends found:',len(friends))
return friends, dual_curve.index(c)
if c.index>upper_bound_dual_curves:
break
except:
pass
if random==True:
if verbose:
print('We check a random collection of dual curves.')
for i in range(random_upper_bound):
try:
c=dual_curves[random.randint(0,len(dual_curves)-1)]
E=K.drill(c)
E=E.filled_triangulation()
if better_is_isometric_to(E,M,index=isometry_index)==False:
if is_homology_solid_torus(E)==True:
already_known=False
for X in possible_knot_exteriors:
if better_is_isometric_to(X,E,index=isometry_index):
already_known=True
break
if already_known==False:
if verbose:
print('We found a new potential knot exterior:',E)
possible_knot_exteriors.append(E)
if verbose:
print('Checking for knot complement:',E)
if is_knot_complement(E,index=exterior_index):
if better_is_isometric_to(E,M,try_hard=try_hard)==False:
already_known=False
for X in friends:
if better_is_isometric_to(X,E,index=isometry_index,try_hard=try_hard):
already_known=True
break
if already_known==False:
if verbose:
print('We found a friend:',E)
friends.append(E)
if len(friends)>max_number_of_friends-1:
if verbose:
print('Number of potential knot exteriors checked:',len(possible_knot_exteriors))
print('Number of friends found:',len(friends))
return friends
except:
pass
##### SNAPPY LENGTH SPECTRUM ######
if SnapPy_length_spectrum:
sys.setrecursionlimit(recursion_limit)
if verbose:
print('--------------')
print('We check short geodescis with SnapPy and search for a friend.')
# Compute the length spectrum
spec=better_length_spectrum(K,max_length=max_length,index=10,high_precision=False)
if spec==False:
if verbose:
print('We could not compute the length spectrum of the 0-surgery.')
else:
if verbose:
print('Number of geodesics in the length spectrum:',len(spec))
if random==False:
if verbose:
print('We check all geodesics.')
for c in spec:
try:
E=K.drill_word(c.word)
E=E.filled_triangulation()
if better_is_isometric_to(E,M,index=isometry_index)==False:
if is_homology_solid_torus(E)==True:
already_known=False
for X in possible_knot_exteriors:
if better_is_isometric_to(X,E,index=isometry_index):
already_known=True
break
if already_known==False:
possible_knot_exteriors.append(E)
if is_knot_complement(E,index=exterior_index):
if better_is_isometric_to(E,M,try_hard=try_hard)==False:
already_known=False
for X in friends:
if better_is_isometric_to(X,E,index=isometry_index,try_hard=try_hard):
already_known=True
break
if already_known==False:
if verbose:
print('We found a friend:',E)
friends.append(E)
if len(friends)>max_number_of_friends-1:
if verbose:
print('Number of potential knot exteriors checked:',len(possible_knot_exteriors))
print('Number of friends found:',len(friends))
return friends
except:
pass
if spec.index(c)>upper_bound_geodesics:
break
if random==True:
if verbose:
print('We check a random collection of geodesics.')
for i in range(random_upper_bound):
c=spec[random.randint(0,len(spec)-1)]
try:
E=K.drill_word(c.word)
E=E.filled_triangulation()
if better_is_isometric_to(E,M,index=isometry_index)==False:
if is_homology_solid_torus(E)==True:
already_known=False
for X in possible_knot_exteriors:
if better_is_isometric_to(X,E,index=isometry_index):
already_known=True
break
if already_known==False:
possible_knot_exteriors.append(E)
if is_knot_complement(E,index=exterior_index):
if better_is_isometric_to(E,M,try_hard=try_hard)==False:
already_known=False
for X in friends:
if better_is_isometric_to(X,E,index=isometry_index,try_hard=try_hard):
already_known=True
break
if already_known==False:
if verbose:
print('We found a friend:',E)
friends.append(E)
if len(friends)>max_number_of_friends-1:
if verbose:
print('Number of potential knot exteriors checked:',len(possible_knot_exteriors))
print('Number of friends found:',len(friends))
return friends
except:
pass
##### REGIN DRILL EDGES ######
if Regina:
if verbose:
print('--------------')
print('We drill out knots via Regina.')
T=to_regina(K.filled_triangulation())
if regina_simplify:
T.intelligentSimplify()
if random==False:
if verbose:
print('We check all edges.')
sigs=drill_edges(T,index=regina_retriangulate_index,cores=regina_cores_used,max_submanifolds=max_regina_submanifolds,max_triangulations=maximal_number_of_Pachner_moves)
if verbose:
print('Total number of submanifolds found via regina:',len(sigs))
if random==True:
if verbose:
print('We check random edges.')
sigs=drill_edges(T,index=regina_retriangulate_index,cores=regina_cores_used,max_submanifolds=max_regina_submanifolds,max_triangulations=maximal_number_of_Pachner_moves,randomized=True)
if verbose:
print('Total number of submanifolds found via regina:',len(sigs))
for sig in sigs:
try:
T=regina.Triangulation3(sig)
E=snappy.Manifold(T.snapPea())
if better_is_isometric_to(E,M,index=isometry_index)==False:
if is_homology_solid_torus(E)==True:
already_known=False
for X in possible_knot_exteriors:
if better_is_isometric_to(X,E):
already_known=True
break
if already_known==False:
if verbose:
print('We found a new potential knot exterior:',E)
possible_knot_exteriors.append(E)
if verbose:
print('Checking for knot complement:',E)
if is_knot_complement(E,index=exterior_index):
if better_is_isometric_to(E,M,try_hard=try_hard)==False:
already_known=False
for X in friends:
if better_is_isometric_to(X,E,index=isometry_index,try_hard=try_hard):
already_known=True
break
if already_known==False:
if verbose:
print('We found a friend:',E)
friends.append(E)
if len(friends)>max_number_of_friends-1:
if verbose:
print('Number of potential knot exteriors checked:',len(possible_knot_exteriors))
print('Number of friends found:',len(friends))
return friends
except:
pass
##### MCMC to replace retriangulation (more variance for other results -- hopefully) ######
if MCMC:
if verbose:
print('--------------')
print('We drill out knots via Regina, using a random walk method to choose next triangulation.')
T=to_regina(K.filled_triangulation())
if regina_simplify:
T.intelligentSimplify()
if random==False:
if verbose:
print('We check all edges.')
sigs=drill_edges(T,index=(-1)*rounds,cores=regina_cores_used,max_submanifolds=max_regina_submanifolds)
if verbose:
print('Total number of submanifolds found via regina:',len(sigs))
if random==True:
if verbose:
print('We check random edges.')
sigs=drill_edges(T,index=(-1)*rounds,cores=regina_cores_used,randomized=True,max_submanifolds=max_regina_submanifolds)
if verbose:
print('Total number of submanifolds found via regina:',len(sigs))
ctr=0
print("found",len(sigs),"triangulations to check")
for sig in sigs:
try:
T=regina.Triangulation3(sig)
E=snappy.Manifold(T.snapPea())
if better_is_isometric_to(E,M,index=isometry_index)==False:
if is_homology_solid_torus(E)==True:
already_known=False
for X in possible_knot_exteriors:
if better_is_isometric_to(X,E):
already_known=True
break
if already_known==False:
if verbose:
print('We found a new potential knot exterior:',E)
possible_knot_exteriors.append(E)
if verbose:
print('Checking for knot complement:',E)
if is_knot_complement(E,index=exterior_index):
if better_is_isometric_to(E,M,try_hard=try_hard)==False:
already_known=False
for X in friends:
if better_is_isometric_to(X,E,index=isometry_index,try_hard=try_hard):
already_known=True
break
if already_known==False:
if verbose:
print('We found a friend:',E)
friends.append(E)
if len(friends)>max_number_of_friends-1:
if verbose:
print('Number of potential knot exteriors checked:',len(possible_knot_exteriors))
print('Number of friends found:',len(friends))
return friends
except:
pass
if verbose:
print('Number of potential knot exteriors checked:',len(possible_knot_exteriors))
print('Number of friends found:',len(friends))
return friends
def find_S3_filling(manifold,index=2):
'''
Checks the short fillings to be S3.
'''
assert manifold.num_cusps() == 1
if manifold.homology().elementary_divisors() != [0]:
return False
try:
slopes = manifold.short_slopes(3.5)[0]
except RuntimeError:
slopes = []
(a, b) = manifold.homological_longitude()
slopes = [s for s in slopes if abs(a*s[1] - b*s[0]) == 1]
for s in slopes:
M = snappy.Triangulation(manifold)
M.dehn_fill(s)
if is_three_sphere(M,tries=index):
return s
return False
def create_diagram(knot_complement,verbose=False):
'''
Takes a list of complements of a knot and creates a diagram.
'''
M=knot_complement
M.dehn_fill((0,0))
D=False
try:
M.set_peripheral_curves('shortest')
except:
pass
try:
M.dehn_fill((1,0))
if is_three_sphere(M):
D=M.exterior_to_link()
if D!=False:
D.simplify('global')
PD_friend=D.PD_code()
return PD_friend
M.dehn_fill((0,0))
M.dehn_fill(find_S3_filling(M))
D=M.exterior_to_link()
if D!=False:
D.simplify('global')
PD_friend=D.PD_code()
return PD_friend
except:
pass
print('COULD NOT FIND A DIAGRAM!')
return D
Examples:
exteriors=search_for_friend('K8a4',verbose=True)
We have choosen the following parameters to search for friends: random False random_upper_bound 100 exterior_index 1 try_hard False isometry_index 1 max_segments 6 upper_bound_dual_curves 15 max_length 1.00000000000000 high_precision False recursion_limit 10000 upper_bound_geodesics 15 regina_simplify True regina_retriangulate_index 0 regina_cores_used 1 max_regina_submanifolds 50 maximal_number_of_Pachner_moves 10 number of rounds for random walk 10 -------------- -------------- We check dual curves with SnapPy and search for a friend. Number of dual curves: 20 We check all dual curves. We found a new potential knot exterior: K8a4-6_filled(0,0) Checking for knot complement: K8a4-6_filled(0,0) We found a new potential knot exterior: K8a4-8_filled(0,0) Checking for knot complement: K8a4-8_filled(0,0) We found a new potential knot exterior: K8a4-10_filled(0,0) Checking for knot complement: K8a4-10_filled(0,0) We found a friend: K8a4-10_filled(0,0) Number of potential knot exteriors checked: 3 Number of friends found: 1 -------------- We check short geodescis with SnapPy and search for a friend. Number of geodesics in the length spectrum: 2 We check all geodesics. -------------- We drill out knots via Regina. We check all edges. Total number of submanifolds found via regina: 10 -------------- We drill out knots via Regina, using a random walk method to choose next triangulation. We check all edges. Total number of submanifolds found via regina: 51 found 51 triangulations to check Number of potential knot exteriors checked: 3 Number of friends found: 1
start_time=time.time()
with_friends=[]
for c in range(5,10):
for K in snappy.HTLinkExteriors(knots_vs_links='knots',crossings=c):
display('Currently checking '+K.name())
exteriors=search_for_friend(K,verbose=True)
for X in exteriors:
D=create_diagram(X)
with_friends.append([K.name(),D])
clear_output(wait=True)
print('Number of friends found:',len(with_friends))
print('Minutes taken:',(time.time()-start_time)/60)
Number of friends found: 16 Minutes taken: 1.9175494194030762
with_friends
[['K6a2', [(11, 4, 12, 5), (22, 5, 23, 6), (9, 26, 10, 27), (33, 11, 34, 10), (16, 26, 17, 25), (14, 32, 15, 31), (17, 38, 18, 39), (20, 35, 21, 36), (23, 31, 24, 30), (0, 15, 1, 16), (6, 21, 7, 22), (7, 35, 8, 34), (29, 19, 30, 18), (28, 37, 29, 38), (13, 2, 14, 3), (27, 8, 28, 9), (3, 12, 4, 13), (39, 24, 0, 25), (1, 32, 2, 33), (36, 19, 37, 20)]], ['K7a2', [(41, 15, 42, 14), (11, 45, 12, 44), (30, 13, 31, 14), (15, 5, 16, 4), (16, 27, 17, 28), (33, 23, 34, 22), (18, 2, 19, 1), (2, 18, 3, 17), (40, 26, 41, 25), (3, 29, 4, 28), (26, 6, 27, 5), (36, 53, 37, 0), (0, 37, 1, 38), (39, 6, 40, 7), (24, 49, 25, 50), (31, 51, 32, 50), (51, 13, 52, 12), (52, 43, 53, 44), (47, 35, 48, 34), (48, 21, 49, 22), (23, 33, 24, 32), (9, 47, 10, 46), (8, 35, 9, 36), (7, 21, 8, 20), (29, 43, 30, 42), (19, 39, 20, 38), (45, 11, 46, 10)]], ['K8a4', [(31, 14, 32, 15), (30, 2, 31, 1), (27, 20, 28, 21), (18, 29, 19, 30), (35, 29, 36, 28), (25, 4, 26, 5), (3, 24, 4, 25), (10, 22, 11, 21), (34, 19, 35, 20), (17, 9, 18, 8), (16, 37, 17, 0), (6, 16, 7, 15), (12, 6, 13, 5), (36, 9, 37, 10), (7, 0, 8, 1), (2, 34, 3, 33), (13, 32, 14, 33), (23, 26, 24, 27), (22, 12, 23, 11)]], ['K8a10', [(8, 17, 9, 18), (4, 34, 5, 33), (9, 29, 10, 28), (12, 36, 13, 35), (38, 16, 39, 15), (14, 0, 15, 39), (32, 6, 33, 5), (19, 10, 20, 11), (0, 14, 1, 13), (2, 25, 3, 26), (11, 22, 12, 23), (36, 22, 37, 21), (29, 17, 30, 16), (30, 8, 31, 7), (26, 24, 27, 23), (20, 38, 21, 37), (24, 3, 25, 4), (18, 28, 19, 27), (1, 34, 2, 35), (6, 32, 7, 31)]], ['K8a10', [(49, 6, 50, 7), (58, 14, 59, 13), (12, 29, 13, 30), (10, 47, 11, 48), (15, 61, 16, 60), (14, 43, 15, 44), (39, 18, 40, 19), (20, 37, 21, 38), (2, 18, 3, 17), (0, 25, 1, 26), (63, 40, 0, 41), (59, 44, 60, 45), (53, 4, 54, 5), (19, 57, 20, 56), (26, 61, 27, 62), (31, 49, 32, 48), (32, 9, 33, 10), (3, 22, 4, 23), (54, 22, 55, 21), (5, 52, 6, 53), (38, 55, 39, 56), (36, 52, 37, 51), (34, 7, 35, 8), (8, 33, 9, 34), (50, 36, 51, 35), (57, 28, 58, 29), (45, 31, 46, 30), (41, 62, 42, 63), (46, 11, 47, 12), (24, 1, 25, 2), (27, 43, 28, 42), (23, 16, 24, 17)]], ['K9a1', [(35, 7, 36, 6), (22, 9, 23, 10), (58, 13, 59, 14), (79, 9, 80, 8), (5, 85, 6, 84), (23, 33, 24, 32), (21, 68, 22, 69), (49, 24, 50, 25), (0, 26, 1, 25), (59, 29, 60, 28), (78, 33, 79, 34), (36, 81, 37, 82), (50, 78, 51, 77), (57, 72, 58, 73), (82, 66, 83, 65), (85, 76, 0, 77), (64, 84, 65, 83), (75, 16, 76, 17), (67, 54, 68, 55), (34, 52, 35, 51), (73, 62, 74, 63), (14, 61, 15, 62), (7, 52, 8, 53), (37, 67, 38, 66), (4, 17, 5, 18), (39, 21, 40, 20), (63, 18, 64, 19), (56, 20, 57, 19), (27, 61, 28, 60), (12, 42, 13, 41), (71, 41, 72, 40), (29, 42, 30, 43), (43, 30, 44, 31), (45, 71, 46, 70), (44, 12, 45, 11), (26, 2, 27, 1), (74, 3, 75, 4), (15, 2, 16, 3), (80, 54, 81, 53), (10, 48, 11, 47), (55, 39, 56, 38), (69, 47, 70, 46), (31, 48, 32, 49)]], ['K9a3', [(35, 22, 36, 23), (23, 34, 24, 35), (13, 26, 14, 27), (24, 4, 25, 3), (20, 2, 21, 1), (0, 26, 1, 25), (16, 8, 17, 7), (39, 8, 40, 9), (5, 38, 6, 39), (32, 38, 33, 37), (28, 0, 29, 41), (27, 14, 28, 15), (31, 18, 32, 19), (6, 18, 7, 17), (2, 22, 3, 21), (36, 12, 37, 11), (19, 12, 20, 13), (10, 34, 11, 33), (9, 4, 10, 5), (15, 30, 16, 31), (40, 30, 41, 29)]], ['K9a3', [(12, 36, 13, 35), (14, 32, 15, 31), (16, 63, 17, 64), (49, 30, 50, 31), (51, 34, 52, 35), (47, 65, 48, 64), (4, 40, 5, 39), (27, 63, 28, 62), (29, 48, 30, 49), (28, 16, 29, 15), (18, 26, 19, 25), (45, 24, 46, 25), (0, 17, 1, 18), (65, 47, 0, 46), (1, 27, 2, 26), (55, 21, 56, 20), (8, 21, 9, 22), (37, 52, 38, 53), (36, 12, 37, 11), (9, 55, 10, 54), (33, 50, 34, 51), (23, 38, 24, 39), (7, 43, 8, 42), (56, 43, 57, 44), (32, 14, 33, 13), (58, 6, 59, 5), (41, 7, 42, 6), (40, 57, 41, 58), (22, 60, 23, 59), (61, 10, 62, 11), (60, 54, 61, 53), (44, 4, 45, 3), (19, 2, 20, 3)]], ['K9a4', [(28, 46, 29, 45), (58, 13, 59, 14), (23, 69, 24, 68), (26, 93, 27, 94), (15, 100, 16, 101), (29, 112, 30, 113), (27, 1, 28, 0), (65, 44, 66, 45), (60, 78, 61, 77), (67, 95, 68, 94), (57, 98, 58, 99), (80, 102, 81, 101), (62, 116, 63, 115), (66, 121, 67, 0), (70, 22, 71, 21), (75, 19, 76, 18), (79, 17, 80, 16), (110, 2, 111, 1), (109, 92, 110, 93), (111, 47, 112, 46), (119, 11, 120, 10), (120, 83, 121, 84), (3, 91, 4, 90), (6, 114, 7, 113), (7, 64, 8, 65), (2, 32, 3, 31), (8, 86, 9, 85), (49, 89, 50, 88), (43, 84, 44, 85), (42, 10, 43, 9), (48, 5, 49, 6), (12, 53, 13, 54), (117, 53, 118, 52), (39, 55, 40, 54), (97, 56, 98, 57), (99, 14, 100, 15), (96, 82, 97, 81), (118, 41, 119, 42), (55, 39, 56, 38), (11, 41, 12, 40), (82, 37, 83, 38), (95, 37, 96, 36), (91, 32, 92, 33), (86, 64, 87, 63), (87, 114, 88, 115), (51, 117, 52, 116), (50, 61, 51, 62), (47, 31, 48, 30), (71, 105, 72, 104), (24, 107, 25, 108), (108, 25, 109, 26), (106, 70, 107, 69), (17, 77, 18, 76), (35, 103, 36, 102), (33, 74, 34, 75), (34, 20, 35, 19), (20, 74, 21, 73), (105, 22, 106, 23), (103, 73, 104, 72), (78, 60, 79, 59), (89, 5, 90, 4)]], ['K9a10', [(5, 23, 6, 22), (13, 50, 14, 51), (20, 47, 21, 48), (37, 26, 38, 27), (21, 5, 22, 4), (28, 50, 29, 49), (48, 34, 49, 33), (38, 53, 39, 0), (46, 7, 47, 8), (0, 28, 1, 27), (12, 29, 13, 30), (31, 10, 32, 11), (8, 43, 9, 44), (52, 39, 53, 40), (16, 42, 17, 41), (19, 32, 20, 33), (25, 44, 26, 45), (40, 16, 41, 15), (3, 34, 4, 35), (1, 36, 2, 37), (51, 14, 52, 15), (30, 17, 31, 18), (11, 19, 12, 18), (35, 2, 36, 3), (45, 24, 46, 25), (42, 9, 43, 10), (23, 7, 24, 6)]], ['K9a10', [(52, 12, 53, 11), (51, 76, 52, 77), (48, 70, 49, 69), (42, 64, 43, 63), (43, 2, 44, 3), (59, 39, 60, 38), (35, 73, 36, 72), (57, 30, 58, 31), (62, 25, 63, 26), (23, 64, 24, 65), (75, 12, 76, 13), (10, 71, 11, 72), (65, 0, 66, 1), (67, 18, 68, 19), (41, 24, 42, 25), (45, 20, 46, 21), (9, 17, 10, 16), (36, 15, 37, 16), (17, 68, 18, 69), (74, 53, 75, 54), (13, 55, 14, 54), (28, 37, 29, 38), (22, 2, 23, 1), (31, 56, 32, 57), (14, 33, 15, 34), (55, 32, 56, 33), (73, 35, 74, 34), (3, 27, 4, 26), (5, 40, 6, 41), (4, 61, 5, 62), (21, 44, 22, 45), (66, 48, 67, 47), (29, 58, 30, 59), (77, 50, 0, 51), (19, 46, 20, 47), (70, 50, 71, 49), (60, 7, 61, 8), (39, 6, 40, 7), (27, 9, 28, 8)]], ['K9a10', [(68, 18, 69, 17), (22, 89, 23, 90), (18, 100, 19, 99), (28, 44, 29, 43), (48, 30, 49, 29), (27, 74, 28, 75), (31, 100, 32, 101), (36, 5, 37, 6), (34, 82, 35, 81), (49, 42, 50, 43), (57, 46, 58, 47), (97, 45, 98, 44), (47, 99, 48, 98), (50, 76, 51, 75), (58, 70, 59, 69), (61, 93, 62, 92), (65, 81, 66, 80), (96, 73, 97, 74), (0, 86, 1, 85), (67, 4, 68, 5), (84, 2, 85, 1), (78, 87, 79, 88), (79, 65, 80, 64), (77, 20, 78, 21), (76, 42, 77, 41), (39, 25, 40, 24), (37, 60, 38, 61), (38, 94, 39, 93), (94, 12, 95, 11), (59, 16, 60, 17), (25, 11, 26, 10), (53, 12, 54, 13), (8, 22, 9, 21), (6, 63, 7, 64), (7, 89, 8, 88), (3, 83, 4, 82), (9, 40, 10, 41), (45, 56, 46, 57), (95, 53, 96, 52), (72, 56, 73, 55), (13, 54, 14, 55), (26, 52, 27, 51), (71, 15, 72, 14), (66, 35, 67, 36), (2, 33, 3, 34), (15, 71, 16, 70), (19, 31, 20, 30), (91, 63, 92, 62), (90, 23, 91, 24), (83, 33, 84, 32), (86, 0, 87, 101)]], ['K9a12', [(101, 17, 102, 16), (95, 83, 96, 82), (88, 44, 89, 43), (65, 86, 66, 87), (30, 85, 31, 86), (55, 80, 56, 81), (12, 79, 13, 80), (64, 30, 65, 29), (66, 3, 67, 4), (28, 64, 29, 63), (61, 42, 62, 43), (17, 46, 18, 47), (49, 14, 50, 15), (6, 13, 7, 14), (62, 108, 63, 107), (87, 106, 88, 107), (18, 104, 19, 103), (27, 109, 28, 108), (26, 41, 27, 42), (25, 75, 26, 74), (32, 68, 33, 67), (1, 68, 2, 69), (0, 83, 1, 84), (110, 98, 111, 97), (112, 9, 113, 10), (111, 52, 112, 53), (109, 71, 110, 70), (84, 69, 85, 70), (73, 25, 74, 24), (60, 24, 61, 23), (90, 21, 91, 22), (45, 22, 46, 23), (104, 20, 105, 19), (76, 100, 77, 99), (78, 7, 79, 8), (77, 50, 78, 51), (75, 73, 76, 72), (4, 94, 5, 93), (105, 92, 106, 93), (20, 91, 21, 92), (44, 90, 45, 89), (34, 82, 35, 81), (40, 71, 41, 72), (38, 52, 39, 51), (37, 9, 38, 8), (39, 98, 40, 99), (48, 57, 49, 58), (5, 56, 6, 57), (100, 60, 101, 59), (15, 59, 16, 58), (102, 47, 103, 48), (11, 37, 12, 36), (94, 33, 95, 34), (54, 36, 55, 35), (2, 32, 3, 31), (53, 114, 54, 115), (96, 0, 97, 115), (10, 113, 11, 114)]], ['K9a29', [(35, 10, 36, 11), (70, 11, 71, 12), (43, 16, 44, 17), (36, 54, 37, 53), (71, 53, 72, 52), (8, 67, 9, 68), (56, 70, 57, 69), (2, 48, 3, 47), (3, 75, 4, 74), (83, 18, 0, 19), (7, 32, 8, 33), (55, 35, 56, 34), (27, 48, 28, 49), (28, 16, 29, 15), (26, 75, 27, 76), (30, 41, 31, 42), (65, 40, 66, 41), (68, 34, 69, 33), (61, 46, 62, 47), (64, 18, 65, 17), (60, 73, 61, 74), (44, 63, 45, 64), (42, 29, 43, 30), (45, 1, 46, 0), (13, 6, 14, 7), (77, 5, 78, 4), (50, 6, 51, 5), (82, 40, 83, 39), (49, 24, 50, 25), (14, 24, 15, 23), (76, 25, 77, 26), (22, 32, 23, 31), (21, 67, 22, 66), (19, 38, 20, 39), (51, 58, 52, 59), (12, 58, 13, 57), (78, 59, 79, 60), (9, 54, 10, 55), (20, 81, 21, 82), (62, 1, 63, 2), (37, 81, 38, 80), (72, 80, 73, 79)]], ['K9n2', [(16, 29, 17, 30), (30, 15, 31, 16), (35, 8, 36, 9), (1, 34, 2, 35), (31, 42, 32, 43), (25, 10, 26, 11), (28, 38, 29, 37), (3, 20, 4, 21), (19, 4, 20, 5), (0, 10, 1, 9), (14, 42, 15, 41), (12, 23, 13, 24), (43, 26, 0, 27), (36, 28, 37, 27), (21, 2, 22, 3), (24, 34, 25, 33), (39, 6, 40, 7), (22, 13, 23, 14), (11, 32, 12, 33), (5, 18, 6, 19), (40, 18, 41, 17), (7, 38, 8, 39)]], ['K9n4', [(21, 29, 22, 28), (25, 12, 26, 13), (6, 27, 7, 28), (34, 29, 35, 30), (26, 5, 27, 6), (24, 31, 25, 32), (19, 0, 20, 1), (17, 4, 18, 5), (16, 11, 17, 12), (10, 4, 11, 3), (13, 33, 14, 32), (2, 10, 3, 9), (8, 0, 9, 35), (14, 23, 15, 24), (7, 20, 8, 21), (33, 22, 34, 23), (30, 16, 31, 15), (1, 18, 2, 19)]]]
exteriors=search_for_friend('K11n34',effort='high',max_number_of_friends=6,verbose=True)
We have choosen the following parameters to search for friends: random False random_upper_bound 100 exterior_index 2 try_hard False isometry_index 2 max_segments 50 upper_bound_dual_curves 250 max_length 4.00000000000000 high_precision False recursion_limit 50000 upper_bound_geodesics 250 regina_simplify True regina_retriangulate_index 2 regina_cores_used 1 max_regina_submanifolds 1000 maximal_number_of_Pachner_moves 100 -------------- -------------- We check dual curves with SnapPy and search for a friend. Number of dual curves: 270 We check all dual curves. We found a new potential knot exterior: K11n34-0_filled(0,0) Checking for knot complement: K11n34-0_filled(0,0) We found a new potential knot exterior: K11n34-1_filled(0,0) Checking for knot complement: K11n34-1_filled(0,0) We found a new potential knot exterior: K11n34-16_filled(0,0) Checking for knot complement: K11n34-16_filled(0,0) We found a new potential knot exterior: K11n34-24_filled(0,0) Checking for knot complement: K11n34-24_filled(0,0) We found a new potential knot exterior: K11n34-26_filled(0,0) Checking for knot complement: K11n34-26_filled(0,0) We found a new potential knot exterior: K11n34-28_filled(0,0) Checking for knot complement: K11n34-28_filled(0,0) We found a friend: K11n34-28_filled(0,0) We found a new potential knot exterior: K11n34-32_filled(0,0) Checking for knot complement: K11n34-32_filled(0,0) We found a new potential knot exterior: K11n34-49_filled(0,0) Checking for knot complement: K11n34-49_filled(0,0) We found a new potential knot exterior: K11n34-51_filled(0,0) Checking for knot complement: K11n34-51_filled(0,0) We found a new potential knot exterior: K11n34-53_filled(0,0) Checking for knot complement: K11n34-53_filled(0,0) We found a new potential knot exterior: K11n34-55_filled(0,0) Checking for knot complement: K11n34-55_filled(0,0) We found a friend: K11n34-55_filled(0,0) We found a new potential knot exterior: K11n34-56_filled(0,0) Checking for knot complement: K11n34-56_filled(0,0) We found a new potential knot exterior: K11n34-64_filled(0,0) Checking for knot complement: K11n34-64_filled(0,0) We found a friend: K11n34-64_filled(0,0) We found a new potential knot exterior: K11n34-72_filled(0,0) Checking for knot complement: K11n34-72_filled(0,0) We found a new potential knot exterior: K11n34-86_filled(0,0) Checking for knot complement: K11n34-86_filled(0,0) We found a new potential knot exterior: K11n34-87_filled(0,0) Checking for knot complement: K11n34-87_filled(0,0) We found a new potential knot exterior: K11n34-88_filled(0,0) Checking for knot complement: K11n34-88_filled(0,0) We found a new potential knot exterior: K11n34-91_filled(0,0) Checking for knot complement: K11n34-91_filled(0,0) We found a new potential knot exterior: K11n34-94_filled(0,0) Checking for knot complement: K11n34-94_filled(0,0) We found a new potential knot exterior: K11n34-97_filled(0,0) Checking for knot complement: K11n34-97_filled(0,0) We found a new potential knot exterior: K11n34-100_filled(0,0) Checking for knot complement: K11n34-100_filled(0,0) We found a new potential knot exterior: K11n34-101_filled(0,0) Checking for knot complement: K11n34-101_filled(0,0) We found a new potential knot exterior: K11n34-103_filled(0,0) Checking for knot complement: K11n34-103_filled(0,0) We found a new potential knot exterior: K11n34-104_filled(0,0) Checking for knot complement: K11n34-104_filled(0,0) We found a new potential knot exterior: K11n34-105_filled(0,0) Checking for knot complement: K11n34-105_filled(0,0) We found a new potential knot exterior: K11n34-107_filled(0,0) Checking for knot complement: K11n34-107_filled(0,0) We found a new potential knot exterior: K11n34-109_filled(0,0) Checking for knot complement: K11n34-109_filled(0,0) We found a new potential knot exterior: K11n34-111_filled(0,0) Checking for knot complement: K11n34-111_filled(0,0) We found a new potential knot exterior: K11n34-120_filled(0,0) Checking for knot complement: K11n34-120_filled(0,0) We found a new potential knot exterior: K11n34-122_filled(0,0) Checking for knot complement: K11n34-122_filled(0,0) We found a new potential knot exterior: K11n34-124_filled(0,0) Checking for knot complement: K11n34-124_filled(0,0) We found a new potential knot exterior: K11n34-126_filled(0,0) Checking for knot complement: K11n34-126_filled(0,0) We found a new potential knot exterior: K11n34-127_filled(0,0) Checking for knot complement: K11n34-127_filled(0,0) We found a new potential knot exterior: K11n34-146_filled(0,0) Checking for knot complement: K11n34-146_filled(0,0) We found a new potential knot exterior: K11n34-156_filled(0,0) Checking for knot complement: K11n34-156_filled(0,0) We found a new potential knot exterior: K11n34-159_filled(0,0) Checking for knot complement: K11n34-159_filled(0,0) We found a new potential knot exterior: K11n34-161_filled(0,0) Checking for knot complement: K11n34-161_filled(0,0) We found a new potential knot exterior: K11n34-170_filled(0,0) Checking for knot complement: K11n34-170_filled(0,0) We found a new potential knot exterior: K11n34-173_filled(0,0) Checking for knot complement: K11n34-173_filled(0,0) We found a new potential knot exterior: K11n34-178_filled(0,0) Checking for knot complement: K11n34-178_filled(0,0) We found a new potential knot exterior: K11n34-190_filled(0,0) Checking for knot complement: K11n34-190_filled(0,0) We found a new potential knot exterior: K11n34-196_filled(0,0) Checking for knot complement: K11n34-196_filled(0,0) We found a new potential knot exterior: K11n34-200_filled(0,0) Checking for knot complement: K11n34-200_filled(0,0) We found a new potential knot exterior: K11n34-207_filled(0,0) Checking for knot complement: K11n34-207_filled(0,0) We found a new potential knot exterior: K11n34-208_filled(0,0) Checking for knot complement: K11n34-208_filled(0,0) We found a new potential knot exterior: K11n34-211_filled(0,0) Checking for knot complement: K11n34-211_filled(0,0) We found a new potential knot exterior: K11n34-212_filled(0,0) Checking for knot complement: K11n34-212_filled(0,0) We found a new potential knot exterior: K11n34-213_filled(0,0) Checking for knot complement: K11n34-213_filled(0,0) We found a new potential knot exterior: K11n34-219_filled(0,0) Checking for knot complement: K11n34-219_filled(0,0) We found a new potential knot exterior: K11n34-222_filled(0,0) Checking for knot complement: K11n34-222_filled(0,0) We found a new potential knot exterior: K11n34-232_filled(0,0) Checking for knot complement: K11n34-232_filled(0,0) We found a new potential knot exterior: K11n34-233_filled(0,0) Checking for knot complement: K11n34-233_filled(0,0) We found a new potential knot exterior: K11n34-239_filled(0,0) Checking for knot complement: K11n34-239_filled(0,0) We found a new potential knot exterior: K11n34-243_filled(0,0) Checking for knot complement: K11n34-243_filled(0,0) We found a new potential knot exterior: K11n34-248_filled(0,0) Checking for knot complement: K11n34-248_filled(0,0) -------------- We check short geodescis with SnapPy and search for a friend. Number of geodesics in the length spectrum: 212 We check all geodesics. We found a friend: K11n34_drilled_filled(0,0) -------------- We drill out knots via Regina. We check all edges. Total number of submanifolds found via regina: 829 Number of potential knot exteriors checked: 62 Number of friends found: 4
exteriors
[K11n34-28_filled(0,0), K11n34-55_filled(0,0), K11n34-64_filled(0,0), K11n34_drilled_filled(0,0)]
print(snappy.Manifold('K11n34').volume(verified=True))
for F in exteriors:
print(F.volume(verified=True))
11.21911772538? 13.2204588706? 14.3011631097? 14.409961289? 14.301163110?
diagrams=[]
for F in exteriors:
D=create_diagram(F)
print(D)
diagrams.append(D)
[(36, 24, 37, 23), (15, 39, 16, 38), (34, 43, 35, 44), (53, 40, 54, 41), (19, 48, 20, 49), (37, 11, 38, 10), (35, 58, 36, 59), (50, 17, 51, 18), (21, 46, 22, 47), (2, 14, 3, 13), (6, 67, 7, 0), (1, 54, 2, 55), (9, 17, 10, 16), (8, 51, 9, 52), (59, 45, 60, 44), (57, 24, 58, 25), (42, 5, 43, 6), (41, 1, 42, 0), (52, 29, 53, 30), (14, 28, 15, 27), (60, 33, 61, 34), (7, 31, 8, 30), (26, 12, 27, 11), (25, 56, 26, 57), (32, 61, 33, 62), (28, 40, 29, 39), (55, 4, 56, 5), (12, 4, 13, 3), (22, 63, 23, 64), (45, 63, 46, 62), (47, 20, 48, 21), (66, 31, 67, 32), (64, 50, 65, 49), (65, 18, 66, 19)] [(12, 79, 13, 80), (17, 94, 18, 95), (24, 89, 25, 90), (26, 4, 27, 3), (25, 68, 26, 69), (84, 29, 85, 30), (5, 29, 6, 28), (96, 36, 97, 35), (37, 73, 38, 72), (42, 56, 43, 55), (82, 48, 83, 47), (13, 44, 14, 45), (50, 68, 51, 67), (51, 89, 52, 88), (49, 4, 50, 5), (76, 54, 77, 53), (103, 54, 104, 55), (11, 58, 12, 59), (85, 65, 86, 64), (8, 61, 9, 62), (87, 67, 88, 66), (2, 69, 3, 70), (74, 94, 75, 93), (81, 98, 82, 99), (83, 6, 84, 7), (106, 95, 107, 96), (1, 90, 2, 91), (9, 101, 10, 100), (57, 79, 58, 78), (59, 10, 60, 11), (63, 30, 64, 31), (56, 44, 57, 43), (60, 101, 61, 102), (32, 75, 33, 76), (33, 17, 34, 16), (34, 106, 35, 105), (31, 52, 32, 53), (18, 108, 19, 107), (73, 108, 74, 109), (102, 77, 103, 78), (104, 16, 105, 15), (48, 27, 49, 28), (0, 24, 1, 23), (36, 19, 37, 20), (71, 20, 72, 21), (91, 22, 92, 23), (41, 14, 42, 15), (46, 99, 47, 100), (45, 81, 46, 80), (92, 109, 93, 0), (65, 87, 66, 86), (62, 7, 63, 8), (97, 40, 98, 41), (70, 40, 71, 39), (21, 38, 22, 39)] [(34, 78, 35, 77), (22, 75, 23, 76), (89, 76, 0, 77), (58, 69, 59, 70), (67, 48, 68, 49), (38, 49, 39, 50), (18, 52, 19, 51), (85, 51, 86, 50), (63, 21, 64, 20), (52, 18, 53, 17), (24, 20, 25, 19), (28, 47, 29, 48), (59, 30, 60, 31), (81, 42, 82, 43), (65, 27, 66, 26), (56, 6, 57, 5), (73, 0, 74, 1), (78, 32, 79, 31), (79, 71, 80, 70), (80, 3, 81, 4), (43, 5, 44, 4), (45, 68, 46, 69), (46, 29, 47, 30), (74, 23, 75, 24), (6, 56, 7, 55), (9, 16, 10, 17), (1, 10, 2, 11), (33, 13, 34, 12), (41, 82, 42, 83), (72, 12, 73, 11), (14, 72, 15, 71), (13, 33, 14, 32), (15, 2, 16, 3), (44, 57, 45, 58), (21, 63, 22, 62), (35, 60, 36, 61), (88, 62, 89, 61), (27, 36, 28, 37), (54, 39, 55, 40), (7, 41, 8, 40), (66, 37, 67, 38), (64, 88, 65, 87), (8, 83, 9, 84), (53, 85, 54, 84), (25, 87, 26, 86)] [(78, 27, 79, 28), (40, 20, 41, 19), (22, 44, 23, 43), (45, 31, 46, 30), (32, 48, 33, 47), (74, 18, 75, 17), (3, 28, 4, 29), (9, 20, 10, 21), (42, 83, 43, 84), (81, 44, 82, 45), (105, 52, 106, 53), (80, 63, 81, 64), (5, 62, 6, 63), (70, 87, 71, 88), (77, 97, 78, 96), (79, 5, 80, 4), (7, 85, 8, 84), (0, 94, 1, 93), (21, 82, 22, 83), (85, 18, 86, 19), (8, 41, 9, 42), (67, 39, 68, 38), (92, 37, 93, 38), (39, 10, 40, 11), (89, 13, 90, 12), (68, 11, 69, 12), (88, 53, 89, 54), (97, 60, 98, 61), (98, 25, 99, 26), (64, 30, 65, 29), (69, 55, 70, 54), (91, 109, 92, 108), (71, 104, 72, 105), (33, 2, 34, 3), (58, 101, 59, 102), (51, 14, 52, 15), (49, 35, 50, 34), (109, 36, 0, 37), (106, 14, 107, 13), (103, 72, 104, 73), (56, 74, 57, 73), (31, 67, 32, 66), (35, 94, 36, 95), (55, 86, 56, 87), (107, 91, 108, 90), (15, 103, 16, 102), (16, 57, 17, 58), (100, 76, 101, 75), (59, 76, 60, 77), (46, 66, 47, 65), (50, 95, 51, 96), (48, 1, 49, 2), (23, 6, 24, 7), (24, 99, 25, 100), (26, 62, 27, 61)]
for D in diagrams:
print(len(D))
34 55 45 55
D=snappy.Link([(191, 4, 192, 5), (201, 48, 202, 49), (82, 48, 83, 47), (85, 152, 86, 153), (195, 90, 196, 91), (190, 142, 191, 141), (193, 147, 194, 146), (1, 87, 2, 86), (113, 52, 114, 53), (114, 150, 115, 149), (110, 87, 111, 88), (148, 89, 149, 90), (144, 110, 145, 109), (142, 3, 143, 4), (145, 193, 146, 192), (66, 100, 67, 99), (69, 132, 70, 133), (64, 181, 65, 182), (65, 17, 66, 16), (67, 33, 68, 32), (115, 197, 116, 196), (107, 2, 108, 3), (49, 198, 50, 199), (51, 150, 52, 151), (58, 6, 59, 5), (53, 112, 54, 113), (55, 89, 56, 88), (136, 166, 137, 165), (184, 162, 185, 161), (12, 163, 13, 164), (27, 160, 28, 161), (63, 158, 64, 159), (34, 213, 35, 214), (33, 69, 34, 68), (30, 98, 31, 97), (35, 134, 36, 135), (28, 183, 29, 184), (31, 15, 32, 14), (153, 46, 154, 47), (20, 38, 21, 37), (178, 39, 179, 40), (105, 39, 106, 38), (75, 41, 76, 40), (211, 36, 212, 37), (129, 102, 130, 103), (131, 70, 132, 71), (123, 42, 124, 43), (44, 121, 45, 122), (73, 126, 74, 127), (103, 128, 104, 129), (180, 126, 181, 125), (18, 127, 19, 128), (79, 120, 80, 121), (202, 118, 203, 117), (45, 208, 46, 209), (80, 207, 81, 208), (106, 209, 107, 210), (174, 206, 175, 205), (21, 210, 22, 211), (84, 199, 85, 200), (119, 207, 120, 206), (139, 189, 140, 188), (137, 10, 138, 11), (135, 22, 136, 23), (186, 25, 187, 26), (11, 25, 12, 24), (108, 144, 109, 143), (104, 19, 105, 20), (214, 13, 215, 14), (218, 160, 219, 159), (216, 29, 217, 30), (212, 134, 213, 133), (217, 183, 218, 182), (219, 62, 220, 63), (215, 96, 216, 97), (91, 61, 92, 60), (94, 185, 95, 186), (93, 27, 94, 26), (95, 162, 96, 163), (98, 16, 99, 15), (101, 130, 102, 131), (168, 7, 169, 8), (164, 23, 165, 24), (167, 141, 168, 140), (166, 190, 167, 189), (169, 92, 170, 93), (170, 61, 171, 62), (78, 175, 79, 176), (204, 174, 205, 173), (122, 178, 123, 177), (43, 176, 44, 177), (157, 173, 158, 172), (155, 119, 156, 118), (156, 204, 157, 203), (17, 73, 18, 72), (100, 72, 101, 71), (41, 77, 42, 76), (124, 77, 125, 78), (154, 81, 155, 82), (200, 83, 201, 84), (179, 74, 180, 75), (147, 56, 148, 57), (111, 54, 112, 55), (194, 57, 195, 58), (6, 60, 7, 59), (9, 138, 10, 139), (8, 187, 9, 188), (171, 221, 172, 220), (116, 222, 117, 221), (197, 223, 198, 222), (50, 223, 51, 0), (151, 1, 152, 0)])
D
<Link: 1 comp; 112 cross>
E=D.exterior()
E.volume(verified=True)
14.3011631097?
for F in exteriors:
print(F.is_isometric_to(E))
False True False False