def put(self): """ Inserts a graph into the GraphBrain """ parser = reqparse.RequestParser() parser.add_argument('graph6', required=True, help="Must include if all currently graphs currently marked as processing should be set to queued") args = parser.parse_args() graph6 = args['graph6'] from sage.graphs.graph import Graph G = Graph() try: from_graph6(G, str(graph6)) except RuntimeError as error: return str(error), 400 canon_g6 = G.canonical_label(algorithm='sage').graph6_string() with get_conn() as conn: with conn.cursor(cursor_factory=RealDictCursor) as cursor: try: cursor.execute("INSERT INTO public.graph(graph6) VALUES (%s)", (canon_g6,)) conn.commit() except UniqueViolation: return 'Graph already exists (canonical sage g6 string): %s' % canon_g6, 409 return canon_g6, 201
def to_undirected_graph(self): r""" Return the undirected graph obtained from the tree nodes and edges. The graph is endowed with an embedding, so that it will be displayed correctly. EXAMPLES:: sage: t = OrderedTree([]) sage: t.to_undirected_graph() Graph on 1 vertex sage: t = OrderedTree([[[]],[],[]]) sage: t.to_undirected_graph() Graph on 5 vertices If the tree is labelled, we use its labelling to label the graph. This will fail if the labels are not all distinct. Otherwise, we use the graph canonical labelling which means that two different trees can have the same graph. EXAMPLES:: sage: t = OrderedTree([[[]],[],[]]) sage: t.canonical_labelling().to_undirected_graph() Graph on 5 vertices TESTS:: sage: t.canonical_labelling().to_undirected_graph() == t.to_undirected_graph() False sage: OrderedTree([[],[]]).to_undirected_graph() == OrderedTree([[[]]]).to_undirected_graph() True sage: OrderedTree([[],[],[]]).to_undirected_graph() == OrderedTree([[[[]]]]).to_undirected_graph() False """ from sage.graphs.graph import Graph g = Graph() if self in LabelledOrderedTrees(): relabel = False else: self = self.canonical_labelling() relabel = True roots = [self] g.add_vertex(name=self.label()) emb = {self.label(): []} while roots: node = roots.pop() children = reversed([child.label() for child in node]) emb[node.label()].extend(children) for child in node: g.add_vertex(name=child.label()) emb[child.label()] = [node.label()] g.add_edge(child.label(), node.label()) roots.append(child) g.set_embedding(emb) if relabel: g = g.canonical_label() return g
def post(self): """ Retrieves a graph from the GraphBrain with computed properties and invariants """ parser = reqparse.RequestParser() parser.add_argument('graph6', required=True, help="Must include if all currently graphs currently marked as processing should be set to queued") args = parser.parse_args() graph6 = args['graph6'] #secretly accept int's representing graph id's local to the GraphBrain. if not graph6.isdigit(): from sage.graphs.graph import Graph G = Graph() try: from_graph6(G, str(graph6)) except RuntimeError as error: return str(error), 400 canon_g6 = G.canonical_label(algorithm='sage').graph6_string() with get_conn() as conn: with conn.cursor(cursor_factory=RealDictCursor) as cursor: if graph6.isdigit(): cursor.execute("select * from graph g where g.id = %s;", (graph6,)) else: cursor.execute("select * from graph g where g.graph6 = %s;", (canon_g6,)) graph = cursor.fetchone() if not graph: return "Graph not in database", 404 graph = dict(graph) graph['properties'] = dict() graph['invariants'] = dict() #Retrieve properties cursor.execute("select p.property, pv.value from properties p join property_value pv on p.id = pv.property_id where pv.graph_id = %s;", (graph['id'],)) properties = cursor.fetchall() if properties: graph['properties'].update({row['property']: row['value'] for row in properties}) #Retrieve invariants cursor.execute("select invariant, value from invariants i join invariant_value iv on i.id = iv.invariant_id where iv.graph_id = %s;", (graph['id'],)) invariants = cursor.fetchall() if invariants: graph['invariants'].update({row['invariant']: row['value'] for row in invariants}) return jsonify(graph)
def to_undirected_graph(self): r""" Return the undirected graph obtained from the tree nodes and edges. EXAMPLES:: sage: t = OrderedTree([]) sage: t.to_undirected_graph() Graph on 1 vertex sage: t = OrderedTree([[[]],[],[]]) sage: t.to_undirected_graph() Graph on 5 vertices If the tree is labelled, we use its labelling to label the graph. Otherwise, we use the graph canonical labelling which means that two different trees can have the same graph. EXAMPLES:: sage: t = OrderedTree([[[]],[],[]]) sage: t.canonical_labelling().to_undirected_graph() Graph on 5 vertices sage: t.canonical_labelling().to_undirected_graph() == t.to_undirected_graph() False sage: OrderedTree([[],[]]).to_undirected_graph() == OrderedTree([[[]]]).to_undirected_graph() True sage: OrderedTree([[],[],[]]).to_undirected_graph() == OrderedTree([[[[]]]]).to_undirected_graph() False """ from sage.graphs.graph import Graph g = Graph() if self in LabelledOrderedTrees(): relabel = False else: self = self.canonical_labelling() relabel = True roots = [self] g.add_vertex(name=self.label()) while len(roots) != 0: node = roots.pop() for child in node: g.add_vertex(name=child.label()) g.add_edge(child.label(), node.label()) roots.append(child) if relabel: g = g.canonical_label() return g
def to_undirected_graph(self): r""" Return the undirected graph obtained from the tree nodes and edges. EXAMPLES:: sage: t = OrderedTree([]) sage: t.to_undirected_graph() Graph on 1 vertex sage: t = OrderedTree([[[]],[],[]]) sage: t.to_undirected_graph() Graph on 5 vertices If the tree is labelled, we use its labelling to label the graph. Otherwise, we use the graph canonical labelling which means that two different trees can have the same graph. EXAMPLES:: sage: t = OrderedTree([[[]],[],[]]) sage: t.canonical_labelling().to_undirected_graph() Graph on 5 vertices sage: t.canonical_labelling().to_undirected_graph() == t.to_undirected_graph() False sage: OrderedTree([[],[]]).to_undirected_graph() == OrderedTree([[[]]]).to_undirected_graph() True sage: OrderedTree([[],[],[]]).to_undirected_graph() == OrderedTree([[[[]]]]).to_undirected_graph() False """ from sage.graphs.graph import Graph g = Graph() if self in LabelledOrderedTrees(): relabel = False else: self = self.canonical_labelling() relabel = True roots = [self] g.add_vertex(name=self.label()) while len(roots) != 0: node = roots.pop() for child in node: g.add_vertex(name=child.label()) g.add_edge(child.label(), node.label()) roots.append(child) if (relabel): g = g.canonical_label() return g
def canonical_label(graph, **kargs): r""" Return the canonical labeling of ``graph``. INPUT: - ``graph`` - the graph to compute the canonical labelling for. - ``algorithm`` - the algorithm to use to compute the canonical labelling. The default value ``None`` means that ``'bliss'`` will be used if available, and ``'sage'`` otherwise. """ algorithm = lookup(kargs, "algorithm", default=None) if isinstance(graph, ZooGraph): graph = Graph(graph) return graph.canonical_label(partition=None, edge_labels=False, algorithm=algorithm)