def list_matrices_Z_2(g,Z,p=2):
"""
:g: A graph.
:Z: The zero forcing number of the given graph.
:returns: A set of tuples with entries corresponding to nonzero diagonal
entries of a potential universally optimal matrices.
:Example:
sage: g=graphs.CycleGraph(7)
....:
sage: list_matrices_Z_2(g,2)
....:
The graph has 21 matrices that achieve minimum rank of 5 over Z_2
{(0, 1, 2),
(0, 1, 2, 3, 5),
(0, 1, 2, 4, 6),
(0, 1, 3, 5, 6),
(0, 1, 4),
(0, 1, 6),
(0, 2, 3, 4, 5),
(0, 2, 4, 5, 6),
(0, 3, 4),
(0, 3, 6),
(0, 5, 6),
(1, 2, 3),
(1, 2, 3, 4, 6),
(1, 2, 5),
(1, 3, 4, 5, 6),
(1, 4, 5),
(2, 3, 4),
(2, 3, 6),
(2, 5, 6),
(3, 4, 5),
(4, 5, 6)}
"""
import itertools
n = g.order()
integer_set = [i for i in range(n)]
nonzero_set = set([ ])
for L in range(n+1):
for subset in itertools.combinations(integer_set, L):
A=g.am()
for i in range(L):
j = subset[i]
A[j,j]=1
A=matrix(GF(p),A)
if A.rank() == n-Z:
nonzero_set.add(subset)
print("The graph has {} matrices that achieve minimum rank"
" of {} over Z_{}".format(len(nonzero_set),n-Z,p))
return nonzero_set