diff --git a/graph_tools/__main__.py b/graph_tools/__main__.py
index d2d94eb17568550dd42660bae229a8abca715f9d..15264be32692775a8d4901cbb4c00663966ca00a 100644
--- a/graph_tools/__main__.py
+++ b/graph_tools/__main__.py
@@ -8,6 +8,7 @@ to_test = [
"sequences",
"parameters",
"misc",
+ "voltage_graphs",
"tests"
]
diff --git a/graph_tools/all.py b/graph_tools/all.py
index cc664bb7cf641d5fc5f0d53e01f1b3836b88faa4..631ae0c08d02346c7ffc0fd5122031e2d2bb453b 100644
--- a/graph_tools/all.py
+++ b/graph_tools/all.py
@@ -2,4 +2,5 @@ from .base import *
from .sequences import *
from .parameters import *
from .misc import *
+from .voltage_graphs import *
diff --git a/graph_tools/voltage_graphs.py b/graph_tools/voltage_graphs.py
new file mode 100644
index 0000000000000000000000000000000000000000..d0217965bc2a949d1faae0db68c76dc766da8468
--- /dev/null
+++ b/graph_tools/voltage_graphs.py
@@ -0,0 +1,118 @@
+def _init_():
+ global voltage_graph_zn_to_sequence
+
+ from .base import Gadget, CUBIC_VERTEX, FREE_EDGE, GraphSequence
+ import itertools
+
+ def flatten(x): return list(itertools.chain.from_iterable(x))
+
+ class GadgetBuilder:
+ def __init__(self, subgadgets):
+ self._subgadgets = subgadgets
+ self._degree = { i: g.size() for i, g in enumerate(subgadgets) }
+ self._joins = []
+ self._outs = []
+
+ def _get_out(self, v):
+ ret = self._degree[v]
+ assert ret > 0
+ self._degree[v] = ret - 1
+ return ret
+
+ def extend(self, gadget):
+ i = len(self._subgadgets)
+ self._degree[i] = gadget.size()
+ self._subgadgets.append(gadget)
+ return i
+
+ def join(self, u, v):
+ ui = self._get_out(u)
+ vi = self._get_out(v)
+ self._joins.append(((u+1, ui), (v+1, vi)))
+ return self
+
+ def out(self, u):
+ ui = self._get_out(u)
+ self._outs.append((u+1, ui))
+ return self
+
+ def finish(self):
+ assert all( d == 0 for d in self._degree.values() )
+ return Gadget.join(
+ self._subgadgets,
+ self._joins,
+ self._outs
+ )
+
+
+ def voltage_graph_zn_to_sequence(template, assignment):
+ """Transform a voltage graph template into a graph sequence.
+
+ EXAMPLES:
+ >>> gs = voltage_graph_zn_to_sequence([2, [(0,0), (0,1), (1,1)]], [1,0,2])
+ >>> from sage.all import graphs
+ >>> from .parameters import UnderlyingGraph, EdgeColoring, CircuitDoubleCover
+ >>> gs.graph(5).eval(EdgeColoring(3))
+ 0
+ >>> gs.graph(5).eval(CircuitDoubleCover)
+ 52
+ >>> P = gs.graph(5).eval(UnderlyingGraph)
+ >>> P.is_isomorphic(graphs.PetersenGraph())
+ True
+
+ >>> gs = voltage_graph_zn_to_sequence([4, [(0,1), (0,2), (0,3), (1,1), (2,2), (3,3)]], [0,0,0, 1,2,3])
+ >>> C = gs.graph(7).eval(UnderlyingGraph)
+ >>> C.is_isomorphic(graphs.CoxeterGraph())
+ True
+
+ >>> gs = voltage_graph_zn_to_sequence([4, [(0,0), (0,1), (1,2), (1,3), (2,3), (2,3)]], [1, 0,0,0, 1,-1])
+ >>> gs.graph(5).eval(EdgeColoring(3))
+ 0
+ >>> F = gs.graph(5).eval(UnderlyingGraph)
+ >>> F.is_isomorphic(graphs.FlowerSnark())
+ True
+ """
+
+ n, E = template
+ m = max(map(abs, assignment))
+ s = 2*sum(map(abs, assignment))
+
+ E_zero = [ (u, v) for i, (u, v) in enumerate(E) if assignment[i] == 0 ]
+ E_nonzero = [ (u, v, assignment[i]) for i, (u, v) in enumerate(E) if assignment[i] != 0 ]
+
+ assert len(assignment) == len(E)
+ assert sorted(flatten(E)) == flatten( [i]*3 for i in range(n) )
+
+ gadget = GadgetBuilder([ CUBIC_VERTEX ] * n)
+
+ for u, v in E_zero:
+ gadget.join(u, v)
+
+ for u, v, a in E_nonzero:
+ free_edges = [ gadget.extend(FREE_EDGE) for _ in range(abs(a) - 1) ]
+ if a > 0:
+ for i in range(a):
+ gadget.out(free_edges[i] if i < a - 1 else u)
+ gadget.out(v if i == 0 else free_edges[i-1])
+ else:
+ for i in range(-a):
+ gadget.out(v if i == 0 else free_edges[i-1])
+ gadget.out(free_edges[i] if i < a - 1 else u)
+
+ gadget = gadget.finish()
+
+ @GraphSequence
+ class Sequence:
+ sequence_start = 1
+
+ base_gadget = gadget
+ step_gadget = gadget
+
+ step_join = [ ((1, 2*i-1), (2, 2*i)) for i in range(1, 1 + gadget.size() // 2) ]
+ step_out = [ (1 + (i % 2), i) for i in range(1, 1 + gadget.size()) ]
+ final_join = [ ((1, 2*i-1), (1, 2*i)) for i in range(1, 1 + gadget.size() // 2) ]
+
+ return Sequence
+
+_init_()
+