Section 7
Proving the theorem for \(d\leq 41\)
We start by computing for \(d=8,\ldots,41\) the set of valid solutions \(s\) over the sign hyperfield \(H\) of the equations
and using the Invertibility Criterium to show that there exist no valid outcome \(w\in\mathbb{Z}^{V_d}\) such that \(\mathrm{sign}(w)=s\) for each such \(s\).
[1]:
for d in range(8,42):
print('d: '+str(d))
def deg(i,j):
return i+j
Vd = [(i,j) for i in range(d+1) for j in range(d+1) if deg(i,j)<=d]
R = PolynomialRing(QQ,['x_'+str(i)+'_'+str(j) for i in range(d+1) for j in range(d+1) if deg(i,j)<=d])
xx = [[R('x_'+str(i)+'_'+str(j)) for j in range(d+1) if deg(i,j)<=d] for i in range(d+1)]
psi = [(-1)^k * sum([(-1)^j*binomial(i,k-j)*xx[i][j] for (i,j) in Vd]) for k in range(d+1)]
psibar = [(-1)^k * sum([(-1)^i*binomial(j,k-i)*xx[i][j] for (i,j) in Vd]) for k in range(d+1)]
varphi = [sum([binomial(d-deg(i,j),a-i)*xx[i][j] for (i,j) in Vd]) for a in range(d+1)]
eqns = psi+psibar+varphi
def var2tup(var):
for (i,j) in Vd:
if var==xx[i][j]:
return (i,j)
def make_conds(eqn):
res = []
if eqn==0:
return res
elif eqn.coefficient(xx[0][0])==0:
pos = [var2tup(var) for var in R.gens() if eqn.coefficient(var)>0]
res.append(pos)
neg = [var2tup(var) for var in R.gens() if eqn.coefficient(var)<0]
res.append(neg)
elif eqn.coefficient(xx[0][0])>0:
pos = [var2tup(var) for var in R.gens() if (eqn.coefficient(var)>0 and var!=xx[0][0])]
res.append(pos)
else:
neg = [var2tup(var) for var in R.gens() if (eqn.coefficient(var)<0 and var!=xx[0][0])]
res.append(neg)
return res
conds = []
for eqn in eqns:
conds = conds + make_conds(eqn)
conds.sort()
def unique(lst):
res = []
for el in lst:
if el not in res:
res.append(el)
return res
conds = unique(conds)
def sublist(lst1, lst2):
intersection = [element for element in lst1 if element in lst2]
return lst1 == intersection
keep = [True for i in range(len(conds))]
for i in range(len(conds)):
for j in range(len(conds)):
if i!=j:
if sublist(conds[j], conds[i]):
keep[i] = False
conds = [conds[i] for i in range(len(conds)) if keep[i]]
conds.sort(key=len)
poss=[[(0,0)]]
todo = [cond for cond in conds]
while len(todo)>0:
cond = todo[0]
todo.remove(cond)
poss_new = []
for supp in poss:
if len([True for pt in supp if pt in cond])>0:
poss_new.append(supp)
elif len(supp)<= 5:
for pt in cond:
poss_new.append(supp+[pt])
poss = poss_new
for supp in poss:
supp.sort()
poss = unique(poss)
print('possible support size all >= 6: '+str(min([len(supp)>=6 for supp in poss])))
print('hyperfield solutions: '+str(len(poss)))
poss2=[]
for supp in poss:
A = Matrix([[binomial(d-deg(i,j),a-i) for (i,j) in supp] for a in range(d+1)])
if A.rank()<6:
poss2.append(supp)
print('solutions left after Invertibility Criterium: '+str(len(poss2)))
print()
d: 8
possible support size all >= 6: True
hyperfield solutions: 792
solutions left after Invertibility Criterium: 0
d: 9
possible support size all >= 6: True
hyperfield solutions: 882
solutions left after Invertibility Criterium: 0
d: 10
possible support size all >= 6: True
hyperfield solutions: 950
solutions left after Invertibility Criterium: 0
d: 11
possible support size all >= 6: True
hyperfield solutions: 1084
solutions left after Invertibility Criterium: 0
d: 12
possible support size all >= 6: True
hyperfield solutions: 1102
solutions left after Invertibility Criterium: 0
d: 13
possible support size all >= 6: True
hyperfield solutions: 1212
solutions left after Invertibility Criterium: 0
d: 14
possible support size all >= 6: True
hyperfield solutions: 1248
solutions left after Invertibility Criterium: 0
d: 15
possible support size all >= 6: True
hyperfield solutions: 1400
solutions left after Invertibility Criterium: 0
d: 16
possible support size all >= 6: True
hyperfield solutions: 1400
solutions left after Invertibility Criterium: 0
d: 17
possible support size all >= 6: True
hyperfield solutions: 1530
solutions left after Invertibility Criterium: 0
d: 18
possible support size all >= 6: True
hyperfield solutions: 1553
solutions left after Invertibility Criterium: 0
d: 19
possible support size all >= 6: True
hyperfield solutions: 1723
solutions left after Invertibility Criterium: 0
d: 20
possible support size all >= 6: True
hyperfield solutions: 1710
solutions left after Invertibility Criterium: 0
d: 21
possible support size all >= 6: True
hyperfield solutions: 1856
solutions left after Invertibility Criterium: 0
d: 22
possible support size all >= 6: True
hyperfield solutions: 1863
solutions left after Invertibility Criterium: 0
d: 23
possible support size all >= 6: True
hyperfield solutions: 2049
solutions left after Invertibility Criterium: 0
d: 24
possible support size all >= 6: True
hyperfield solutions: 2020
solutions left after Invertibility Criterium: 0
d: 25
possible support size all >= 6: True
hyperfield solutions: 2182
solutions left after Invertibility Criterium: 0
d: 26
possible support size all >= 6: True
hyperfield solutions: 2173
solutions left after Invertibility Criterium: 0
d: 27
possible support size all >= 6: True
hyperfield solutions: 2375
solutions left after Invertibility Criterium: 0
d: 28
possible support size all >= 6: True
hyperfield solutions: 2330
solutions left after Invertibility Criterium: 0
d: 29
possible support size all >= 6: True
hyperfield solutions: 2508
solutions left after Invertibility Criterium: 0
d: 30
possible support size all >= 6: True
hyperfield solutions: 2483
solutions left after Invertibility Criterium: 0
d: 31
possible support size all >= 6: True
hyperfield solutions: 2701
solutions left after Invertibility Criterium: 0
d: 32
possible support size all >= 6: True
hyperfield solutions: 2640
solutions left after Invertibility Criterium: 0
d: 33
possible support size all >= 6: True
hyperfield solutions: 2834
solutions left after Invertibility Criterium: 0
d: 34
possible support size all >= 6: True
hyperfield solutions: 2793
solutions left after Invertibility Criterium: 0
d: 35
possible support size all >= 6: True
hyperfield solutions: 3027
solutions left after Invertibility Criterium: 0
d: 36
possible support size all >= 6: True
hyperfield solutions: 2950
solutions left after Invertibility Criterium: 0
d: 37
possible support size all >= 6: True
hyperfield solutions: 3160
solutions left after Invertibility Criterium: 0
d: 38
possible support size all >= 6: True
hyperfield solutions: 3103
solutions left after Invertibility Criterium: 0
d: 39
possible support size all >= 6: True
hyperfield solutions: 3353
solutions left after Invertibility Criterium: 0
d: 40
possible support size all >= 6: True
hyperfield solutions: 3260
solutions left after Invertibility Criterium: 0
d: 41
possible support size all >= 6: True
hyperfield solutions: 3486
solutions left after Invertibility Criterium: 0
Computing \(\Gamma^{\mathrm{even}}\) and \(\Gamma^{\mathrm{odd}}\)
Next we compute the set of elements of \(\Gamma^{\mathrm{even}}\) with a positive support of size \(\leq 5\). We do this by considering the equations defining \(\Gamma_{12}\).
[2]:
d = 12
def deg(i,j):
return i+j
Vd = [(i,j) for i in range(d+1) for j in range(d+1) if deg(i,j)<=d]
R = PolynomialRing(QQ,['x_'+str(i)+'_'+str(j) for i in range(d+1) for j in range(d+1) if deg(i,j)<=d])
xx = [[R('x_'+str(i)+'_'+str(j)) for j in range(d+1) if deg(i,j)<=d] for i in range(d+1)]
psi = [(-1)^k * sum([(-1)^j*binomial(i,k-j)*xx[i][j] for (i,j) in Vd]) for k in range(d+1)]
psibar = [(-1)^k * sum([(-1)^i*binomial(j,k-i)*xx[i][j] for (i,j) in Vd]) for k in range(d+1)]
varphi = [sum([binomial(d-deg(i,j),a-i)*xx[i][j] for (i,j) in Vd]) for a in range(d+1)]
eqns = psi[1:4]+psi[d-3:]+psibar[1:4]+psibar[d-3:]+varphi[1:4]+varphi[d-3:d]
def var2tup(var):
for (i,j) in Vd:
if var==xx[i][j]:
return (i,j)
def make_conds(eqn):
res = []
if eqn==0:
return res
elif eqn.coefficient(xx[0][0])==0:
pos = [var2tup(var) for var in R.gens() if eqn.coefficient(var)>0]
res.append(pos)
neg = [var2tup(var) for var in R.gens() if eqn.coefficient(var)<0]
res.append(neg)
elif eqn.coefficient(xx[0][0])>0:
pos = [var2tup(var) for var in R.gens() if (eqn.coefficient(var)>0 and var!=xx[0][0])]
res.append(pos)
else:
neg = [var2tup(var) for var in R.gens() if (eqn.coefficient(var)<0 and var!=xx[0][0])]
res.append(neg)
return res
conds = []
for eqn in eqns:
conds = conds + make_conds(eqn)
conds.sort()
def unique(lst):
res = []
for el in lst:
if el not in res:
res.append(el)
return res
conds = unique(conds)
def sublist(lst1, lst2):
intersection = [element for element in lst1 if element in lst2]
return lst1 == intersection
keep = [True for i in range(len(conds))]
for i in range(len(conds)):
for j in range(len(conds)):
if i!=j:
if sublist(conds[j], conds[i]):
keep[i] = False
conds = [conds[i] for i in range(len(conds)) if keep[i]]
xx = [['x'+str(i)+str(j) for j in range(4)] for i in range(4)]
yy = [['y'+str(i)+str(j) for j in range(4)] for i in range(4)]
zz = [['z'+str(i)+str(j) for j in range(4)] for i in range(4)]
bb = ['b'+str(j) for j in range(4)]
cc = ['c'+str(i) for i in range(4)]
dd = [['d'+str(bit)+str(k) for k in range(4)] for bit in [0,1]]
def contraction_cond(cond):
res = []
for i in range(4):
for j in range(4):
if (i,j) in cond:
res.append(xx[i][j])
for i in range(4):
for j in range(4):
if (i,d-3-i+j) in cond:
res.append(yy[i][j])
for i in range(4):
for j in range(4):
if (d-3-j+i,j) in cond:
res.append(zz[i][j])
for i in range(4):
if max([((i,j) in cond) for j in range(4,d-3-i)]):
res.append(cc[i])
for j in range(4):
if max([((i,j) in cond) for i in range(4,d-3-j)]):
res.append(bb[j])
for bit in [0,1]:
for k in range(4):
if max([((i,d-i-k) in cond) for i in range(4+bit,d-3-k) if i%2==bit]):
res.append(dd[bit][k])
return res
conds_even = []
for cond in conds:
conds_even.append(contraction_cond(cond))
conds_even.sort(key=len)
poss=[['x00']]
todo = [cond for cond in conds_even]
while len(todo)>0:
cond = todo[0]
todo.remove(cond)
poss_new = []
for supp in poss:
if len([True for pt in supp if pt in cond])>0:
poss_new.append(supp)
elif len(supp)<= 5:
for pt in cond:
poss_new.append(supp+[pt])
poss = poss_new
for pos in poss:
pos.sort()
poss_even = unique(poss)
print(sum([len(supp)<=5 for supp in poss_even]))
len(poss_even)
0
[2]:
1283
And, we compute the set of elements of \(\Gamma^{\mathrm{odd}}\) with a positive support of size \(\leq 5\). We do this by considering the equations defining \(\Gamma_{13}\).
[3]:
d = 13
def deg(i,j):
return i+j
Vd = [(i,j) for i in range(d+1) for j in range(d+1) if deg(i,j)<=d]
R = PolynomialRing(QQ,['x_'+str(i)+'_'+str(j) for i in range(d+1) for j in range(d+1) if deg(i,j)<=d])
xx = [[R('x_'+str(i)+'_'+str(j)) for j in range(d+1) if deg(i,j)<=d] for i in range(d+1)]
psi = [(-1)^k * sum([(-1)^j*binomial(i,k-j)*xx[i][j] for (i,j) in Vd]) for k in range(d+1)]
psibar = [(-1)^k * sum([(-1)^i*binomial(j,k-i)*xx[i][j] for (i,j) in Vd]) for k in range(d+1)]
varphi = [sum([binomial(d-deg(i,j),a-i)*xx[i][j] for (i,j) in Vd]) for a in range(d+1)]
eqns = psi[1:4]+psi[d-3:]+psibar[1:4]+psibar[d-3:]+varphi[1:4]+varphi[d-3:d]
def var2tup(var):
for (i,j) in Vd:
if var==xx[i][j]:
return (i,j)
def make_conds(eqn):
res = []
if eqn==0:
return res
elif eqn.coefficient(xx[0][0])==0:
pos = [var2tup(var) for var in R.gens() if eqn.coefficient(var)>0]
res.append(pos)
neg = [var2tup(var) for var in R.gens() if eqn.coefficient(var)<0]
res.append(neg)
elif eqn.coefficient(xx[0][0])>0:
pos = [var2tup(var) for var in R.gens() if (eqn.coefficient(var)>0 and var!=xx[0][0])]
res.append(pos)
else:
neg = [var2tup(var) for var in R.gens() if (eqn.coefficient(var)<0 and var!=xx[0][0])]
res.append(neg)
return res
conds = []
for eqn in eqns:
conds = conds + make_conds(eqn)
conds.sort()
def unique(lst):
res = []
for el in lst:
if el not in res:
res.append(el)
return res
conds = unique(conds)
def sublist(lst1, lst2):
intersection = [element for element in lst1 if element in lst2]
return lst1 == intersection
keep = [True for i in range(len(conds))]
for i in range(len(conds)):
for j in range(len(conds)):
if i!=j:
if sublist(conds[j], conds[i]):
keep[i] = False
conds = [conds[i] for i in range(len(conds)) if keep[i]]
xx = [['x'+str(i)+str(j) for j in range(4)] for i in range(4)]
yy = [['y'+str(i)+str(j) for j in range(4)] for i in range(4)]
zz = [['z'+str(i)+str(j) for j in range(4)] for i in range(4)]
bb = ['b'+str(j) for j in range(4)]
cc = ['c'+str(i) for i in range(4)]
dd = [['d'+str(bit)+str(k) for k in range(4)] for bit in [0,1]]
def contraction_cond(cond):
res = []
for i in range(4):
for j in range(4):
if (i,j) in cond:
res.append(xx[i][j])
for i in range(4):
for j in range(4):
if (i,d-3-i+j) in cond:
res.append(yy[i][j])
for i in range(4):
for j in range(4):
if (d-3-j+i,j) in cond:
res.append(zz[i][j])
for i in range(4):
if max([((i,j) in cond) for j in range(4,d-3-i)]):
res.append(cc[i])
for j in range(4):
if max([((i,j) in cond) for i in range(4,d-3-j)]):
res.append(bb[j])
for bit in [0,1]:
for k in range(4):
if max([((i,d-i-k) in cond) for i in range(4+bit,d-3-k) if i%2==bit]):
res.append(dd[bit][k])
return res
conds_odd = []
for cond in conds:
conds_odd.append(contraction_cond(cond))
conds_odd.sort(key=len)
poss=[['x00']]
todo = [cond for cond in conds_odd]
while len(todo)>0:
cond = todo[0]
todo.remove(cond)
poss_new = []
for supp in poss:
if len([True for pt in supp if pt in cond])>0:
poss_new.append(supp)
elif len(supp)<= 5:
for pt in cond:
poss_new.append(supp+[pt])
poss = poss_new
for pos in poss:
pos.sort()
poss_odd = unique(poss)
print(sum([len(supp)<=5 for supp in poss_odd]))
len(poss_odd)
0
[3]:
1265
Eliminating all possibilities
We take the union of these two sets.
[4]:
poss = unique(poss_even+poss_odd)
len(poss)
[4]:
2318
Next we find and remove the elements of \(\Gamma^{\mathrm{even}}\cup\Gamma^{\mathrm{odd}}\) whose support contain both \(d^{(0)}_k\) and \(d^{(1)}_k\) for some \(k\in\{0,1,2,3\}\).
[5]:
for supp in poss:
for i in range(4):
if 'd0'+str(i) in supp:
if 'd1'+str(i) in supp:
print(supp)
poss.remove(supp)
['d00', 'd10', 'x00', 'x03', 'x11', 'x30']
We deal with these cases by hand. Now we apply the map \(\mathrm{simp}\) to what remains.
[6]:
dd = [['d'+str(bit)+str(k) for k in range(4)] for bit in [0,1]]
dd_new = ['d'+str(k) for k in range(4)]
for supp in poss:
for k in range(4):
if dd[0][k] in supp:
supp.remove(dd[0][k])
supp.append(dd_new[k])
if dd[1][k] in supp:
supp.remove(dd[1][k])
supp.append(dd_new[k])
dd = dd_new
poss = unique(poss)
len(poss)
[6]:
2289
Next we check that in every case there are at most one \(i\) (resp \(j,k\)) such that the support contains \(c_i\) (resp. \(b_j,d_k\)).
[7]:
for supp in poss:
if sum([True for pt in supp if pt in bb])>1:
print(supp)
if sum([True for pt in supp if pt in cc])>1:
print(supp)
if sum([True for pt in supp if pt in dd])>1:
print(supp)
Now, for every case we compute a list of possible “relative” supports. This is a list of pairs \((i,j)\) with \(i,j\in\{0,\ldots,3,M,d-6,\ldots,d\}\). Here \(0,1,2,3\) indicate the first \(4\) rows/columns, \(d-6,\ldots,d\) indicate the last \(7\) rows/columns and \(M\) indicates all other rows/columns.
[8]:
start = [0,1,2,3]
middle = 50 # we pretend M=50.
end = [94,95,96,97,98,99,100] # we pretend here that d=100.
relcoords = start+[middle]+end
def relsets(supp):
if supp==[]:
return [[]]
resA = relsets(supp[1:])
pt = supp[0]
resB = []
for i in range(4):
for j in range(4):
if pt == xx[i][j]:
resB = [(start[i],start[j])]
if pt == yy[i][j]:
resB = [(start[i],end[3-i+j])]
if pt == zz[i][j]:
resB = [(end[3-j+i],start[j])]
if pt == cc[i]:
resB = [(start[i],j) for j in [middle]+end[:3-i]]
if pt == bb[i]:
resB = [(j,start[i]) for j in [middle]+end[:3-i]]
if pt == dd[i]:
resB = [(middle,end[j]) for j in range(3-i)]+[(middle,middle)]+[(end[j],middle) for j in range(3-i)]
return [tup+[el] for tup in resA for el in resB]
We then check for each of the relative supports whether such a support is possible.
[9]:
def check(relset):
while len(relset)>0:
c_start = relcoords.index(min([pt[0] for pt in relset]))
c_end = c_start
pts = [pt for pt in relset if relcoords[c_start] <= pt[0] <= relcoords[c_end]]
while len(pts)>c_end-c_start+1:
if c_end==11:
return False #if there are more point than columns left, we cannot continue
c_end = c_end+1
pts = [pt for pt in relset if relcoords[c_start] <= pt[0] <= relcoords[c_end]]
if not good_pts(pts):
return False
for pt in pts:
relset.remove(pt)
return True
def good_pts(pts):
if len(pts)<=2:
return True
# uses that there are at most one $i,j,k$ such that the support contains c_i,r_j,d_k
if len(pts)==3:
if pts[0][0]==pts[1][0] and pts[0][0]==pts[2][0]:
return True
c = min([pt[0] for pt in pts])
x = min([j for (i,j) in pts if i==c])
y = max([j for (i,j) in pts if i==c])
z = [j for (i,j) in pts if i>c][0]
if z not in midpoints(x,y):
return True
return False
def midpoints(x,y):
if y in start:
return [(x+y-1)/2]
if x in end:
return [(x+y-1)/2]
if y==middle:
if x in [0,1]:
return [2,3,middle]
if x in [2,3]:
return [3,middle]
if x==middle:
if y in end[:2]:
return [middle]
if y in end[2:4]:
return [middle,end[0]]
if y in end[4:6]:
return [middle,end[0],end[1]]
if y==end[6]:
return [middle,end[0],end[1],end[2]]
return [middle]
# assumes that x<=3 and y>=d-6 implies 3<(x+y-1)/2<d-6
# works since d>=15
[10]:
poss2 = []
for supp in poss:
toadd = False
for relset in relsets(supp):
if not check(relset):
toadd = True
if toadd:
poss2.append(supp)
len(poss2)
[10]:
1107
Next we continue by applying the same approach to points in the orbit.
[11]:
def action12_supp(supp):
res = []
for i in range(4):
for j in range(4):
if xx[i][j] in supp:
res.append(xx[j][i])
if yy[i][j] in supp:
res.append(zz[j][i])
if zz[i][j] in supp:
res.append(yy[j][i])
if cc[i] in supp:
res.append(bb[i])
if bb[i] in supp:
res.append(cc[i])
if dd[i] in supp:
res.append(dd[i])
return res
[12]:
poss3 = []
for supp in poss2:
toadd = False
for relset in relsets(action12_supp(supp)):
if not check(relset):
toadd = True
if toadd:
poss3.append(supp)
len(poss3)
[12]:
547
[13]:
def action13_supp(supp):
res = []
for i in range(4):
for j in range(4):
if xx[i][j] in supp:
res.append(zz[3-i][j])
if yy[i][j] in supp:
res.append(yy[3-j][3-i])
if zz[i][j] in supp:
res.append(xx[3-i][j])
if cc[i] in supp:
res.append(dd[i])
if bb[i] in supp:
res.append(bb[i])
if dd[i] in supp:
res.append(cc[i])
return res
[14]:
poss4 = []
for supp in poss3:
toadd = False
for relset in relsets(action13_supp(supp)):
if not check(relset):
toadd = True
if toadd:
poss4.append(supp)
len(poss4)
[14]:
349
Now it is time to apply the Hexagon Criterium. We remove the cases where the positive support shares no element with \(\{c_0,\ldots,c_3,b_0,\ldots,b_3,d_0,\ldots,d_3\}\).
[15]:
poss5 = []
for supp in poss4:
if sum([True for pt in supp if pt in cc+bb+dd])>=1:
supp.sort()
poss5.append(supp)
for supp in poss5:
print(supp)
['b1', 'x00', 'y03', 'y11', 'y13', 'z20']
['b1', 'x00', 'y03', 'y13', 'y22', 'z20']
['b1', 'x00', 'y03', 'y11', 'y13', 'z30']
['b1', 'x00', 'y03', 'y13', 'y22', 'z30']
['d1', 'x00', 'x10', 'x12', 'y03', 'z31']
['d1', 'x00', 'x12', 'x20', 'y03', 'z31']
['c1', 'x00', 'y03', 'z10', 'z22', 'z31']
['c1', 'x00', 'y03', 'z11', 'z20', 'z31']
['c1', 'x00', 'y03', 'z20', 'z22', 'z31']
['c1', 'x00', 'y03', 'z11', 'z30', 'z31']
['c1', 'x00', 'y03', 'z22', 'z30', 'z31']
['d1', 'x00', 'x01', 'x21', 'y13', 'z30']
['d1', 'x00', 'x02', 'x21', 'y13', 'z30']
['b1', 'x00', 'y01', 'y13', 'y22', 'z30']
['b1', 'x00', 'y02', 'y11', 'y13', 'z30']
['b1', 'x00', 'y02', 'y13', 'y22', 'z30']
['c1', 'x00', 'y02', 'z11', 'z30', 'z31']
['c1', 'x00', 'y02', 'z22', 'z30', 'z31']
['d0', 'x00', 'x03', 'x11', 'x30', 'y33']
['d0', 'x00', 'x03', 'x11', 'x30', 'z33']
['d1', 'x00', 'x12', 'x21', 'y03', 'z30']
['b1', 'x00', 'y03', 'y12', 'y21', 'z30']
['c1', 'x00', 'y03', 'z12', 'z21', 'z30']
['b1', 'c1', 'd1', 'x00', 'y03', 'z30']
We remove the cases where the positive support shares \(1\) elements with \(\{c_0,c_1,b_0,b_1,d_0,d_1\}\) and no element with \(\{c_2,c_3,b_2,b_3,d_2,d_3\}\).
[16]:
poss6 = []
for supp in poss5:
if sum([True for pt in supp if pt in cc[:2]+bb[:2]+dd[:2]])!=1 or sum([True for pt in supp if pt in cc[2:]+bb[2:]+dd[2:]])!=0:
supp.sort()
poss6.append(supp)
for supp in poss6:
print(supp)
['b1', 'c1', 'd1', 'x00', 'y03', 'z30']
This case is dealt with by hand.