#!/usr/bin/python

"""
  Calculate a the number of 4-boundaries of a linear
  representation of the number of circuit double covers.

  It uses cyclic ladder gadgets with sizes 2 up to 7 with
  permutations of all half-edges except the first one.
  This gives matrix of size 36 with rank 21 which matches
  the upper bound which is the rank of the join matrix.
"""

import _experiment
from itertools import permutations
from graph_tools.all import *

LadderGadget = lambda k: CyclicLadder().gadget(k)
ladders = list(map(LadderGadget, range(2, 8)))
gadgets = [ l.permute((1,) + p) 
  for l in ladders for p in permutations([2, 3, 4]) ]

M = parameter_matrix(CircuitDoubleCover, gadgets)
pivot_rows = M.pivot_rows()

gadgets = [ gadgets[i] for i in pivot_rows ]
MM = parameter_matrix(CircuitDoubleCover, gadgets)

B, J = edge_model_join_matrix(CircuitDoubleCover, 4, boundaries=True)
p = J.pivot_rows()

if __name__ == "__main__":
  print("Circuit double covers -- 4-boundaries:")
  print("Lower bound: Matrix of size %i with rank %i" % (M.nrows(), len(pivot_rows)))
  print("  Pivot rows: %s" % (pivot_rows,))
  print("  Rank of reduced matrix: %i" % (MM.rank(),))
  print("Upper bound: Join matrix of size %i with rank %i" % (J.nrows(), J.rank()))
  print("  Pivot rows: %s" % (p,))
  print("  Idependent boundaries:")
  for i in p: print("    %s" % (B[i],))
  print("\n  Unused boundaries:")
  for i in range(J.nrows()):
    if i not in p: print("    %s" % (B[i],))