### Setting values of the parameters q0,qperp,pd,ptilde

q0=1/2
qperp=1/2
pd=1/4
ptilde=1/2

print('q0:')
print(q0)
print('qperp:')
print(qperp)
print('pd:')
print(pd)
print('ptilde:')
print(ptilde)
print('')

### Constructing the polytope of response functions under measurement noncontextuality

weakvaluespolysymbN=Polyhedron(ieqs=[[0,1,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0],[0,0,0,0,1,0,0,0,0],[0,0,0,0,0,1,0,0,0],[0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,0],[0,0,0,0,0,0,0,0,1],[ptilde,0,0,0,0,-1,-1,0,0]],eqns=[[-1,1,1,0,0,0,0,0,0],[-1,0,0,1,1,0,0,0,0],[-1,0,0,0,0,1,1,1,1],[0,1-pd,0,pd,0,-1,0,-1,0],[0,0,1-pd,0,pd,0,-1,0,-1]])

print ('Polytope of response functions, weakvaluespolysymbN:')
print weakvaluespolysymbN
print('')

### Theorem 1: noncontextuality inequality from "transformation noncontextuality", or
### "measurement noncontextuality and outcome determinism"

##1. Filtering out vertices of weakvaluespolysymbN that are outcome-deterministic for the postselection: mncdetverticeswvN.

mncverticeswvN=weakvaluespolysymbN.vertices_matrix().transpose()
mncverticeswvN #matrix of all the vertices

print('Vertices of weakvaluespolysymbN, given by mncverticeswvN:')
print mncverticeswvN
print('')

mncdetverticeswvN=[]
j=0
for i in range(len(mncverticeswvN.rows())):
if mncverticeswvN[i][0]^2==mncverticeswvN[i][0]:
mncdetverticeswvN.append(mncverticeswvN[i].list())

mncdetverticeswvN=matrix(mncdetverticeswvN) #matrix of vertices outcome-deterministic for the postselection

print('Vertices of weakvaluespolysymbN deterministic for the postselection, given by mncdetverticeswvN:')
print mncdetverticeswvN
print('')

##2. Extracting the (x_1,x_5) entries from the vertices in mncdetverticeswvN. These are stored in mncx1x5detverticesN.
##   Here we denote a vertex of weakvaluespolysymbN by (x_1,x_2,...,x_8).

mncx1x5detverticesN=[]
for i in range(len(mncdetverticeswvN.rows())):
mncx1x5detverticesN.append([mncdetverticeswvN[i][0],mncdetverticeswvN[i][4]])

mncx1x5detverticesN=matrix(mncx1x5detverticesN)

print('(x_1,x_5) entries of the vertices in mncdetverticeswvN:')
print mncx1x5detverticesN
print('')

##3. Constructing the polytope mncreduceddetpolyN that is outcome-deterministic for the postselection

mncreduceddetpolyN=Polyhedron(vertices=mncx1x5detverticesN)

print('Polytope of (x_1,x_5) deterministic for the postselection, mncreduceddetpolyN:')
print mncreduceddetpolyN
print mncreduceddetpolyN.Vrepresentation()
print('')

##4. Noncontextuality inequality from the facets of mncreducedpolyN

print('Facets of the polytope mncreduceddetpolyN including the noncontextuality inequality of Theorem 1:')
print mncreduceddetpolyN.Hrepresentation()
print('')

### Theorem 5: noncontextuality inequality from preparation and measurement noncontextuality

##1. Extracting the (x_1,x_5) entries from the vertices in mncverticeswvN. These are stored in mncx1x5verticesN.

mncx1x5verticesN=[]
for i in range(len(mncverticeswvN.rows())):
mncx1x5verticesN.append([mncverticeswvN[i][0],mncverticeswvN[i][4]])
mncx1x5verticesN=matrix(mncx1x5verticesN)

print('(x_1,x_5) entries of the vertices of weakvaluespolysymbN:')
print mncx1x5verticesN
print('')

##2. Constructing the polytope mncreducedpolyN and extracting the relevant vertices in the matrix redvtxN

mncreducedpolyN=Polyhedron(vertices=mncx1x5verticesN)
print('Polytope of (x_1,x_5) valuations, mncreducedpolyN:')
print mncreducedpolyN
print('')

redvtxN=mncreducedpolyN.vertices_matrix().transpose()
print redvtxN
print('')

##3. Implementing preparation noncontextuality: constructing the polytope robustawvpolyN

robustawvpolyN=Polyhedron(
ieqs=[
[0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,0],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1],
[0,-(1-qperp),0,0,0,0,q0,0,0,0,0,(1-q0),0,0,0,0,0,0,0],
[0,0,-(1-qperp),0,0,0,0,q0,0,0,0,0,(1-q0),0,0,0,0,0,0],
[0,0,0,-(1-qperp),0,0,0,0,q0,0,0,0,0,(1-q0),0,0,0,0,0],
[0,0,0,0,-(1-qperp),0,0,0,0,q0,0,0,0,0,(1-q0),0,0,0,0],
[0,0,0,0,0,-(1-qperp),0,0,0,0,q0,0,0,0,0,(1-q0),0,0,0]],
eqns=[
[-1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[-1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
[-1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0],
[0,redvtxN[0][0],redvtxN[1][0],redvtxN[2][0],redvtxN[3][0],redvtxN[4][0],0,0,0,0,0,0,0,0,0,0,-1,0,0],
[0,redvtxN[0][1],redvtxN[1][1],redvtxN[2][1],redvtxN[3][1],redvtxN[4][1],0,0,0,0,0,0,0,0,0,0,0,0,-1],
[0,0,0,0,0,0,q0*(1-redvtxN[0][0]),q0*(1-redvtxN[1][0]),q0*(1-redvtxN[2][0]),q0*(1-redvtxN[3][0]),q0*(1-redvtxN[4][0]),(1-q0)*redvtxN[0][0],(1-q0)*redvtxN[1][0],(1-q0)*redvtxN[2][0],(1-q0)*redvtxN[3][0],(1-q0)*redvtxN[4][0],0,-1,0]
])

print('Polytope of preparation distributions and (p_F,C_P,p_-p_F), robustawvpolyN:')
print robustawvpolyN
print('')

##4. Extracting the valuations of (p_F,C_P,p_-p_F) from the vertices of robustawvpolyN and constructing the reduced polytope ##   redawvpolyN of valuations for (p_F,C_P,p_-p_F).

robustawvpolyverticesN=robustawvpolyN.vertices_matrix().transpose()
robustawvpolyverticesN

redawvpolyverticesN=[]
numvtx=len(robustawvpolyverticesN.rows())
numvar=len(robustawvpolyverticesN.columns())
for i in range(numvtx):
redawvpolyverticesN.append([robustawvpolyverticesN[i][numvar-3],robustawvpolyverticesN[i][numvar-
2],robustawvpolyverticesN[i][numvar-1]])
redawvpolyverticesN=matrix(redawvpolyverticesN)

redawvpolyN=Polyhedron(vertices=redawvpolyverticesN)
print('Polytope of valuations of (p_F,C_P,p_-p_F), redawvpolyN:')
print redawvpolyN
print('')

##5. Noncontextuality inequality from the facets of redawvpolyN
print('Facets of the polytope redawvpolyN including the noncontextuality inequality of Theorem 2')
print redawvpolyN.Hrepresentation()

q0: 1/2 qperp: 1/2 pd: 1/4 ptilde: 1/2 Polytope of response functions, weakvaluespolysymbN: A 4-dimensional polyhedron in QQ^8 defined as the convex hull of 16 vertices [ 0 1 0 1 0 1/2 0 1/2] [ 0 1 0 1 0 0 0 1] [ 1 0 0 1 1/2 0 1/4 1/4] [1/3 2/3 1 0 0 1/2 1/2 0] [1/3 2/3 1 0 1/2 0 0 1/2] [ 1 0 0 1 0 0 3/4 1/4] [ 1 0 1 0 1/2 0 1/2 0] [ 1 0 1 0 0 0 1 0] [2/3 1/3 0 1 1/2 0 0 1/2] [2/3 1/3 0 1 0 1/2 1/2 0] [ 1 0 0 1 1/4 1/4 1/2 0] [ 1 0 0 1 0 1/4 3/4 0] [ 0 1 1 0 0 0 1/4 3/4] [ 0 1 1 0 1/4 0 0 3/4] [ 0 1 1 0 0 1/2 1/4 1/4] [ 0 1 1 0 1/4 1/4 0 1/2] Vertices of weakvaluespolysymbN, given by mncverticeswvN: [ 0 1 0 1 0 1/2 0 1/2] [ 0 1 0 1 0 0 0 1] [ 1 0 0 1 1/2 0 1/4 1/4] [1/3 2/3 1 0 0 1/2 1/2 0] [1/3 2/3 1 0 1/2 0 0 1/2] [ 1 0 0 1 0 0 3/4 1/4] [ 1 0 1 0 1/2 0 1/2 0] [ 1 0 1 0 0 0 1 0] [2/3 1/3 0 1 1/2 0 0 1/2] [2/3 1/3 0 1 0 1/2 1/2 0] [ 1 0 0 1 1/4 1/4 1/2 0] [ 1 0 0 1 0 1/4 3/4 0] [ 0 1 1 0 0 0 1/4 3/4] [ 0 1 1 0 1/4 0 0 3/4] [ 0 1 1 0 0 1/2 1/4 1/4] [ 0 1 1 0 1/4 1/4 0 1/2] Vertices of weakvaluespolysymbN deterministic for the postselection, given by mncdetverticeswvN: [ 0 1 0 1 0 1/2 0 1/2] [ 0 1 0 1 0 0 0 1] [ 1 0 0 1 1/2 0 1/4 1/4] [ 1 0 0 1 0 0 3/4 1/4] [ 1 0 1 0 1/2 0 1/2 0] [ 1 0 1 0 0 0 1 0] [ 1 0 0 1 1/4 1/4 1/2 0] [ 1 0 0 1 0 1/4 3/4 0] [ 0 1 1 0 0 0 1/4 3/4] [ 0 1 1 0 1/4 0 0 3/4] [ 0 1 1 0 0 1/2 1/4 1/4] [ 0 1 1 0 1/4 1/4 0 1/2] (x_1,x_5) entries of the vertices in mncdetverticeswvN: [ 0 0] [ 0 0] [ 1 1/2] [ 1 0] [ 1 1/2] [ 1 0] [ 1 1/4] [ 1 0] [ 0 0] [ 0 1/4] [ 0 0] [ 0 1/4] Polytope of (x_1,x_5) deterministic for the postselection, mncreduceddetpolyN: A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices (A vertex at (0, 0), A vertex at (0, 1/4), A vertex at (1, 0), A vertex at (1, 1/2)) Facets of the polytope mncreduceddetpolyN including the noncontextuality inequality of Theorem 1: (An inequality (-1, 0) x + 1 >= 0, An inequality (0, 1) x + 0 >= 0, An inequality (1, 0) x + 0 >= 0, An inequality (1, -4) x + 1 >= 0) (x_1,x_5) entries of the vertices of weakvaluespolysymbN: [ 0 0] [ 0 0] [ 1 1/2] [1/3 0] [1/3 1/2] [ 1 0] [ 1 1/2] [ 1 0] [2/3 1/2] [2/3 0] [ 1 1/4] [ 1 0] [ 0 0] [ 0 1/4] [ 0 0] [ 0 1/4] Polytope of (x_1,x_5) valuations, mncreducedpolyN: A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 5 vertices [ 0 0] [ 0 1/4] [ 1 0] [ 1 1/2] [1/3 1/2] Polytope of preparation distributions and (p_F,C_P,p_-p_F), robustawvpolyN: A 12-dimensional polyhedron in QQ^18 defined as the convex hull of 45 vertices 45 x 18 dense matrix over Rational Field Polytope of valuations of (p_F,C_P,p_-p_F), redawvpolyN: A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 10 vertices Facets of the polytope redawvpolyN including the noncontextuality inequality of Theorem 2 (An inequality (-1, 0, 0) x + 1 >= 0, An inequality (0, 0, -2) x + 1 >= 0, An inequality (0, 0, 1) x + 0 >= 0, An inequality (1, 0, 0) x + 0 >= 0, An inequality (3, 0, -4) x + 1 >= 0, An inequality (0, 1, 0) x + 0 >= 0, An inequality (1, 4, -4) x + 1 >= 0, An inequality (0, -1, 0) x + 1 >= 0, An inequality (1, -4, -4) x + 5 >= 0)