| 
																	
																	
																		
																	
																	
																 | 
																@@ -6,6 +6,10 @@ from collections import defaultdict | 
															
														
														
													
														
															
																 | 
																 | 
																import itertools as it | 
																 | 
																 | 
																import itertools as it | 
															
														
														
													
														
															
																 | 
																 | 
																import clifford | 
																 | 
																 | 
																import clifford | 
															
														
														
													
														
															
																 | 
																 | 
																import json | 
																 | 
																 | 
																import json | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																try: | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    import networkx as nx | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																except ImportError: | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    print "Could not import networkx: layout will not work" | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																class GraphState(object): | 
																 | 
																 | 
																class GraphState(object): | 
															
														
														
													
												
													
														
															
																| 
																	
																	
																	
																		
																	
																 | 
																@@ -13,6 +17,7 @@ class GraphState(object): | 
															
														
														
													
														
															
																 | 
																 | 
																    def __init__(self): | 
																 | 
																 | 
																    def __init__(self): | 
															
														
														
													
														
															
																 | 
																 | 
																        self.ngbh = defaultdict(set) | 
																 | 
																 | 
																        self.ngbh = defaultdict(set) | 
															
														
														
													
														
															
																 | 
																 | 
																        self.vops = defaultdict(int) | 
																 | 
																 | 
																        self.vops = defaultdict(int) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        self.meta = defaultdict(dict) | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    def add_vertex(self, v): | 
																 | 
																 | 
																    def add_vertex(self, v): | 
															
														
														
													
														
															
																 | 
																 | 
																        """ Add a vertex if it doesn't already exist """ | 
																 | 
																 | 
																        """ Add a vertex if it doesn't already exist """ | 
															
														
														
													
												
													
														
															
																| 
																	
																		
																	
																	
																		
																	
																	
																 | 
																@@ -84,7 +89,6 @@ class GraphState(object): | 
															
														
														
													
														
															
																 | 
																 | 
																        if self.ngbh[a] - {b}: | 
																 | 
																 | 
																        if self.ngbh[a] - {b}: | 
															
														
														
													
														
															
																 | 
																 | 
																            self.remove_vop(a, b) | 
																 | 
																 | 
																            self.remove_vop(a, b) | 
															
														
														
													
														
															
																 | 
																 | 
																        edge = self.has_edge(a, b) | 
																 | 
																 | 
																        edge = self.has_edge(a, b) | 
															
														
														
													
														
															
																 | 
																 | 
																        # TODO put this in a new function for diff hook | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        new_edge, self.vops[a], self.vops[b] = clifford.cz_table[edge, self.vops[a], self.vops[b]] | 
																 | 
																 | 
																        new_edge, self.vops[a], self.vops[b] = clifford.cz_table[edge, self.vops[a], self.vops[b]] | 
															
														
														
													
														
															
																 | 
																 | 
																        if new_edge != edge: | 
																 | 
																 | 
																        if new_edge != edge: | 
															
														
														
													
														
															
																 | 
																 | 
																            self.toggle_edge(a, b) | 
																 | 
																 | 
																            self.toggle_edge(a, b) | 
															
														
														
													
												
													
														
															
																| 
																	
																	
																	
																		
																	
																 | 
																@@ -97,22 +101,24 @@ class GraphState(object): | 
															
														
														
													
														
															
																 | 
																 | 
																    def to_json(self): | 
																 | 
																 | 
																    def to_json(self): | 
															
														
														
													
														
															
																 | 
																 | 
																        """ Convert the graph to JSON form """ | 
																 | 
																 | 
																        """ Convert the graph to JSON form """ | 
															
														
														
													
														
															
																 | 
																 | 
																        ngbh = {key: tuple(value) for key, value in self.ngbh.items()} | 
																 | 
																 | 
																        ngbh = {key: tuple(value) for key, value in self.ngbh.items()} | 
															
														
														
													
														
															
																 | 
																 | 
																        return json.dumps({"vops": self.vops, "ngbh": ngbh}) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																class DiffedGraphState(GraphState): | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    """ Just like a graph state, but tracks changes for rendering purposes """ | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    def __init__(self): | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        GraphState.__init__(self) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        self.diff = [] | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    def add_vertex(self, v): | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        GraphState.add_vertex(self, v) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        self.diff.append("add_vertex {}".format(v)) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    def add_edge(self, v1, v2): | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        GraphState.add_edge(self, v1, v2) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        self.diff.append("add_edge {} {}".format(v1, v2)) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        meta = {key: value for key, value in self.meta.items()} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return json.dumps({"vops": self.vops, "ngbh": ngbh, "meta": meta}) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    def to_networkx(self): | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        """ Convert the graph to a networkx graph """ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        g = nx.Graph() | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        g.edge = {node: {neighbour: {} for neighbour in neighbours}  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                for node, neighbours in self.ngbh.items()} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        g.node = {node: {"vop": vop} for node, vop in self.vops.items()} | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        for node, metadata in self.meta.items(): | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            g.node[node].update(metadata) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return g | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    def layout(self): | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        """ Automatically lay out the graph """ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        g = self.to_networkx() | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        pos = nx.spring_layout(g, dim=3, scale=10) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        for key, (x, y, z) in pos.items(): | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            self.meta[key]["pos"] = {"x": round(x, 0), "y": round(y, 0), "z": round(z, 0)} | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																         | 
																 | 
																 | 
																         |