pattern matching: convert tabs to spaces

This commit is contained in:
Joeri Exelmans 2024-09-04 09:34:26 +02:00
parent 88172d64c5
commit 3ae35a87d0
5 changed files with 929 additions and 915 deletions

View file

@ -1,8 +1,8 @@
# coding: utf-8 # coding: utf-8
""" """
Author: Sten Vercamman Author: Sten Vercamman
Univeristy of Antwerp Univeristy of Antwerp
Example code for paper: Efficient model transformations for novices Example code for paper: Efficient model transformations for novices
url: http://msdl.cs.mcgill.ca/people/hv/teaching/MSBDesign/projects/Sten.Vercammen url: http://msdl.cs.mcgill.ca/people/hv/teaching/MSBDesign/projects/Sten.Vercammen
@ -25,178 +25,178 @@ import collections
import random import random
class GraphGenerator(object): class GraphGenerator(object):
""" """
Generates a random Graph with dv an array containing all vertices (there type), Generates a random Graph with dv an array containing all vertices (there type),
de an array containing all edges (their type) and dc_inc an array representing de an array containing all edges (their type) and dc_inc an array representing
the incoming edges (analogue for dc_out) the incoming edges (analogue for dc_out)
""" """
def __init__(self, dv, de, dc_inc, dc_out, debug=False): def __init__(self, dv, de, dc_inc, dc_out, debug=False):
if len(de) != len(dc_inc): if len(de) != len(dc_inc):
raise ValueError('de and dc_inc should be the same length.') raise ValueError('de and dc_inc should be the same length.')
if len(de) != len(dc_out): if len(de) != len(dc_out):
raise ValueError('de and dc_out should be the same length.') raise ValueError('de and dc_out should be the same length.')
self.dv = dv self.dv = dv
self.de = de self.de = de
self.dc_inc = dc_inc self.dc_inc = dc_inc
self.dc_out = dc_out self.dc_out = dc_out
# print for debugging, so you know the used values # print for debugging, so you know the used values
if debug: if debug:
print('dv') print('dv')
print('[',','.join(map(str,dv)),']') print('[',','.join(map(str,dv)),']')
print('_____') print('_____')
print('de') print('de')
print('[',','.join(map(str,de)),']') print('[',','.join(map(str,de)),']')
print('_____') print('_____')
print('dc_inc') print('dc_inc')
print('[',','.join(map(str,dc_inc)),']') print('[',','.join(map(str,dc_inc)),']')
print('_____') print('_____')
print('dc_out') print('dc_out')
print('[',','.join(map(str,dc_out)),']') print('[',','.join(map(str,dc_out)),']')
print('_____') print('_____')
self.graph = graph.Graph() self.graph = graph.Graph()
self.vertices = [] self.vertices = []
# create all the vertices: # create all the vertices:
for v_type in self.dv: for v_type in self.dv:
# v_type represents the type of the vertex # v_type represents the type of the vertex
self.vertices.append(self.graph.addCreateVertex('v' + str(v_type))) self.vertices.append(self.graph.addCreateVertex('v' + str(v_type)))
index = 0 index = 0
# create all edges # create all edges
for e_type in self.de: for e_type in self.de:
# e_type represents the type of the edge # e_type represents the type of the edge
src = self.vertices[self.dc_out[index]] # get src vertex src = self.vertices[self.dc_out[index]] # get src vertex
tgt = self.vertices[self.dc_inc[index]] # get tgt vertex tgt = self.vertices[self.dc_inc[index]] # get tgt vertex
self.graph.addCreateEdge(src, tgt, 'e' + str(e_type)) # create edge self.graph.addCreateEdge(src, tgt, 'e' + str(e_type)) # create edge
index += 1 index += 1
def getRandomGraph(self): def getRandomGraph(self):
return self.graph return self.graph
def getRandomPattern(self, max_nr_of_v, max_nr_of_e, start=0, debug=False): def getRandomPattern(self, max_nr_of_v, max_nr_of_e, start=0, debug=False):
# create pattern # create pattern
pattern = graph.Graph() pattern = graph.Graph()
# map from graph to new pattern # map from graph to new pattern
graph_to_pattern = {} graph_to_pattern = {}
# map of possible edges # map of possible edges
# we don't need a dict, but python v2.7 does not have an OrderedSet # we don't need a dict, but python v2.7 does not have an OrderedSet
possible_edges = collections.OrderedDict() possible_edges = collections.OrderedDict()
# set of chosen edges # set of chosen edges
chosen_edges = set() chosen_edges = set()
# start node from graph # start node from graph
g_node = self.vertices[start] g_node = self.vertices[start]
p_node = pattern.addCreateVertex(g_node.type) p_node = pattern.addCreateVertex(g_node.type)
# for debuging, print the order in which the pattern gets created and # for debuging, print the order in which the pattern gets created and
# connects it edges # connects it edges
if debug: if debug:
print('v'+str(id(p_node))+'=pattern.addCreateVertex('+"'"+str(g_node.type)+"'"+')') print('v'+str(id(p_node))+'=pattern.addCreateVertex('+"'"+str(g_node.type)+"'"+')')
# save corrolation # save corrolation
graph_to_pattern[g_node] = p_node graph_to_pattern[g_node] = p_node
def insertAllEdges(edges, possible_edges, chosen_edges): def insertAllEdges(edges, possible_edges, chosen_edges):
for edge in edges: for edge in edges:
# if we did not chose the edge # if we did not chose the edge
if edge not in chosen_edges: if edge not in chosen_edges:
# if inc_edge not in possible edges, add it with value 1 # if inc_edge not in possible edges, add it with value 1
possible_edges[edge] = None possible_edges[edge] = None
def insertEdges(g_vertex, possible_edges, chosen_edges): def insertEdges(g_vertex, possible_edges, chosen_edges):
insertAllEdges(g_vertex.incoming_edges, possible_edges, chosen_edges) insertAllEdges(g_vertex.incoming_edges, possible_edges, chosen_edges)
insertAllEdges(g_vertex.outgoing_edges, possible_edges, chosen_edges) insertAllEdges(g_vertex.outgoing_edges, possible_edges, chosen_edges)
insertEdges(g_node, possible_edges, chosen_edges) insertEdges(g_node, possible_edges, chosen_edges)
while max_nr_of_v > len(graph_to_pattern) and max_nr_of_e > len(chosen_edges): while max_nr_of_v > len(graph_to_pattern) and max_nr_of_e > len(chosen_edges):
candidate = None candidate = None
if len(possible_edges) == 0: if len(possible_edges) == 0:
break break
# get a random number between 0 and len(possible_edges) # get a random number between 0 and len(possible_edges)
# We us a triangular distribution to approximate the fact that # We us a triangular distribution to approximate the fact that
# the first element is the longest in the possible_edges and # the first element is the longest in the possible_edges and
# already had the post chance of beeing choosen. # already had the post chance of beeing choosen.
# (The approximation is because the first few ellements where # (The approximation is because the first few ellements where
# added in the same itteration, but doing this exact is # added in the same itteration, but doing this exact is
# computationally expensive.) # computationally expensive.)
if len(possible_edges) == 1: if len(possible_edges) == 1:
randie = 0 randie = 0
else: else:
randie = int(round(random.triangular(1, len(possible_edges), len(possible_edges)))) - 1 randie = int(round(random.triangular(1, len(possible_edges), len(possible_edges)))) - 1
candidate = list(possible_edges.keys())[randie] candidate = list(possible_edges.keys())[randie]
del possible_edges[candidate] del possible_edges[candidate]
chosen_edges.add(candidate) chosen_edges.add(candidate)
src = graph_to_pattern.get(candidate.src) src = graph_to_pattern.get(candidate.src)
tgt = graph_to_pattern.get(candidate.tgt) tgt = graph_to_pattern.get(candidate.tgt)
src_is_new = True src_is_new = True
if src != None and tgt != None: if src != None and tgt != None:
# create edge between source and target # create edge between source and target
pattern.addCreateEdge(src, tgt, candidate.type) pattern.addCreateEdge(src, tgt, candidate.type)
if debug: if debug:
print('pattern.addCreateEdge('+'v'+str(id(src))+', '+'v'+str(id(tgt))+', '+"'"+str(candidate.type)+"'"+')') print('pattern.addCreateEdge('+'v'+str(id(src))+', '+'v'+str(id(tgt))+', '+"'"+str(candidate.type)+"'"+')')
# skip adding new edges # skip adding new edges
continue continue
elif src == None: elif src == None:
# create pattern vertex # create pattern vertex
src = pattern.addCreateVertex(candidate.src.type) src = pattern.addCreateVertex(candidate.src.type)
if debug: if debug:
print('v'+str(id(src))+'=pattern.addCreateVertex('+"'"+str(candidate.src.type)+"'"+')') print('v'+str(id(src))+'=pattern.addCreateVertex('+"'"+str(candidate.src.type)+"'"+')')
# map newly created pattern vertex # map newly created pattern vertex
graph_to_pattern[candidate.src] = src graph_to_pattern[candidate.src] = src
# create edge between source and target # create edge between source and target
pattern.addCreateEdge(src, tgt, candidate.type) pattern.addCreateEdge(src, tgt, candidate.type)
if debug: if debug:
print('pattern.addCreateEdge('+'v'+str(id(src))+', '+'v'+str(id(tgt))+', '+"'"+str(candidate.type)+"'"+')') print('pattern.addCreateEdge('+'v'+str(id(src))+', '+'v'+str(id(tgt))+', '+"'"+str(candidate.type)+"'"+')')
elif tgt == None: elif tgt == None:
src_is_new = False src_is_new = False
# create pattern vertex # create pattern vertex
tgt = pattern.addCreateVertex(candidate.tgt.type) tgt = pattern.addCreateVertex(candidate.tgt.type)
if debug: if debug:
print('v'+str(id(tgt))+'=pattern.addCreateVertex('+"'"+str(candidate.tgt.type)+"'"+')') print('v'+str(id(tgt))+'=pattern.addCreateVertex('+"'"+str(candidate.tgt.type)+"'"+')')
# map newly created pattern vertex # map newly created pattern vertex
graph_to_pattern[candidate.tgt] = tgt graph_to_pattern[candidate.tgt] = tgt
# create edge between source and target # create edge between source and target
pattern.addCreateEdge(src, tgt, candidate.type) pattern.addCreateEdge(src, tgt, candidate.type)
if debug: if debug:
print('pattern.addCreateEdge('+'v'+str(id(src))+', '+'v'+str(id(tgt))+', '+"'"+str(candidate.type)+"'"+')') print('pattern.addCreateEdge('+'v'+str(id(src))+', '+'v'+str(id(tgt))+', '+"'"+str(candidate.type)+"'"+')')
else: else:
raise RuntimeError('Bug: src or tgt of edge should be in out pattern') raise RuntimeError('Bug: src or tgt of edge should be in out pattern')
# select the vertex from the chosen edge that was not yet part of the pattern # select the vertex from the chosen edge that was not yet part of the pattern
if src_is_new: if src_is_new:
new_vertex = candidate.src new_vertex = candidate.src
else: else:
new_vertex = candidate.tgt new_vertex = candidate.tgt
# insert all edges from the new vertex # insert all edges from the new vertex
insertEdges(new_vertex, possible_edges, chosen_edges) insertEdges(new_vertex, possible_edges, chosen_edges)
return pattern return pattern
def createConstantPattern(): def createConstantPattern():
""" """
Use this to create the same pattern over and over again. Use this to create the same pattern over and over again.
""" """
# create pattern # create pattern
pattern = graph.Graph() pattern = graph.Graph()
# copy and paste printed pattern from debug output or create a pattern # copy and paste printed pattern from debug output or create a pattern
# below the following line: # below the following line:
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
v4447242448=pattern.addCreateVertex('v4') v4447242448=pattern.addCreateVertex('v4')
v4457323088=pattern.addCreateVertex('v6') v4457323088=pattern.addCreateVertex('v6')
pattern.addCreateEdge(v4447242448, v4457323088, 'e4') pattern.addCreateEdge(v4447242448, v4457323088, 'e4')
v4457323216=pattern.addCreateVertex('v8') v4457323216=pattern.addCreateVertex('v8')
pattern.addCreateEdge(v4457323216, v4447242448, 'e4') pattern.addCreateEdge(v4457323216, v4447242448, 'e4')
v4457323344=pattern.addCreateVertex('v7') v4457323344=pattern.addCreateVertex('v7')
pattern.addCreateEdge(v4457323216, v4457323344, 'e3') pattern.addCreateEdge(v4457323216, v4457323344, 'e3')
v4457323472=pattern.addCreateVertex('v7') v4457323472=pattern.addCreateVertex('v7')
pattern.addCreateEdge(v4457323344, v4457323472, 'e1') pattern.addCreateEdge(v4457323344, v4457323472, 'e1')
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
return pattern return pattern

View file

@ -1,8 +1,8 @@
# coding: utf-8 # coding: utf-8
""" """
Author: Sten Vercamman Author: Sten Vercamman
Univeristy of Antwerp Univeristy of Antwerp
Example code for paper: Efficient model transformations for novices Example code for paper: Efficient model transformations for novices
url: http://msdl.cs.mcgill.ca/people/hv/teaching/MSBDesign/projects/Sten.Vercammen url: http://msdl.cs.mcgill.ca/people/hv/teaching/MSBDesign/projects/Sten.Vercammen
@ -19,139 +19,139 @@ at the workings behind various techniques for efficient pattern matching.
""" """
class Properties(object): class Properties(object):
""" """
Holds all Properties. Holds all Properties.
""" """
def __init__(self): def __init__(self):
# member variables: # member variables:
self.properties = {} self.properties = {}
def addProperty(self, name, value): def addProperty(self, name, value):
""" """
Adds property (overrides if name already exists). Adds property (overrides if name already exists).
""" """
self.properties[name] = value self.properties[name] = value
def getProperty(self, name): def getProperty(self, name):
""" """
Returns property with given name or None if not found. Returns property with given name or None if not found.
""" """
return self.properties.get(name) return self.properties.get(name)
class Edge(Properties): class Edge(Properties):
""" """
Describes an Edge with source and target Node. Describes an Edge with source and target Node.
The Edge can have several properties, like a name, a weight, etc... The Edge can have several properties, like a name, a weight, etc...
""" """
def __init__(self, src, tgt, str_type=None): def __init__(self, src, tgt, str_type=None):
# Call parent class constructor # Call parent class constructor
Properties.__init__(self) Properties.__init__(self)
# member variables: # member variables:
self.src = src self.src = src
self.tgt = tgt self.tgt = tgt
self.type = str_type self.type = str_type
class Vertex(Properties): class Vertex(Properties):
""" """
Describes a Vertex with incoming, outgoing and undirected (both ways) edges. Describes a Vertex with incoming, outgoing and undirected (both ways) edges.
The vertex can have several properties, like a name, a weight, etc... The vertex can have several properties, like a name, a weight, etc...
""" """
def __init__(self, str_type): def __init__(self, str_type):
# Call parent class constructor # Call parent class constructor
Properties.__init__(self) Properties.__init__(self)
# member variables: # member variables:
self.incoming_edges = set() # undirected edges should be stored both in self.incoming_edges = set() # undirected edges should be stored both in
self.outgoing_edges = set() # incoming and outgoing edges self.outgoing_edges = set() # incoming and outgoing edges
self.type = str_type self.type = str_type
def addIncomingEdge(self, edge): def addIncomingEdge(self, edge):
""" """
Adds an incoming Edge. Adds an incoming Edge.
""" """
if not isinstance(edge, Edge): if not isinstance(edge, Edge):
raise TypeError('addIncomingEdge without it being an edge') raise TypeError('addIncomingEdge without it being an edge')
self.incoming_edges.add(edge) self.incoming_edges.add(edge)
def addOutgoingEdge(self, edge): def addOutgoingEdge(self, edge):
""" """
Adds an outgoing Edge. Adds an outgoing Edge.
""" """
if not isinstance(edge, Edge): if not isinstance(edge, Edge):
raise TypeError('addOutgoingEdge without it being an edge') raise TypeError('addOutgoingEdge without it being an edge')
self.outgoing_edges.add(edge) self.outgoing_edges.add(edge)
def addUndirectedEdge(self, edge): def addUndirectedEdge(self, edge):
""" """
Adds an undirected (or bi-directed) Edge. Adds an undirected (or bi-directed) Edge.
""" """
self.addIncomingEdge(edge) self.addIncomingEdge(edge)
self.addOutgoingEdge(edge) self.addOutgoingEdge(edge)
class Graph(object): class Graph(object):
""" """
Holds a Graph. Holds a Graph.
""" """
def __init__(self): def __init__(self):
# member variables: # member variables:
# redundant type keeping, "needed" for fast iterating over specific type # redundant type keeping, "needed" for fast iterating over specific type
self.vertices = {} # {type, set(v1, v2, ...)} self.vertices = {} # {type, set(v1, v2, ...)}
self.edges = {} # {type, set(e1, e2, ...)} self.edges = {} # {type, set(e1, e2, ...)}
def addCreateVertex(self, str_type): def addCreateVertex(self, str_type):
""" """
Creates a Vertex of str_type, stores it and returs it Creates a Vertex of str_type, stores it and returs it
(so that properties can be added to it). (so that properties can be added to it).
""" """
vertex = Vertex(str_type) vertex = Vertex(str_type)
self.addVertex(vertex) self.addVertex(vertex)
return vertex return vertex
def addVertex(self, vertex): def addVertex(self, vertex):
""" """
Stores a Vertex into the Graph. Stores a Vertex into the Graph.
""" """
if not isinstance(vertex, Vertex): if not isinstance(vertex, Vertex):
raise TypeError('addVertex expects a Vertex') raise TypeError('addVertex expects a Vertex')
# add vertex, but it first creates a new set for the vertex type # add vertex, but it first creates a new set for the vertex type
# if the type does not exist in the dictionary # if the type does not exist in the dictionary
self.vertices.setdefault(vertex.type, set()).add(vertex) self.vertices.setdefault(vertex.type, set()).add(vertex)
def getVerticesOfType(self, str_type): def getVerticesOfType(self, str_type):
""" """
Returns all vertices of a specific type, Returns all vertices of a specific type,
Return [] if there are no vertices with the given type Return [] if there are no vertices with the given type
""" """
return self.vertices.get(str_type, []) return self.vertices.get(str_type, [])
def getEdgesOfType(self, str_type): def getEdgesOfType(self, str_type):
""" """
Returns all edges of a specific type, Returns all edges of a specific type,
Return [] if there are no edges with the given type Return [] if there are no edges with the given type
""" """
return self.edges.get(str_type, []) return self.edges.get(str_type, [])
def addCreateEdge(self, src, tgt, str_type): def addCreateEdge(self, src, tgt, str_type):
""" """
Creates edge of str_type from src to tgt, and returns it, Creates edge of str_type from src to tgt, and returns it,
so that properties can be added to the edge. so that properties can be added to the edge.
""" """
if not isinstance(src, Vertex): if not isinstance(src, Vertex):
raise TypeError('addCreateEdge: src is not a Vertex') raise TypeError('addCreateEdge: src is not a Vertex')
if not isinstance(tgt, Vertex): if not isinstance(tgt, Vertex):
raise TypeError('addCreateEdge: tgt is not a Vertex') raise TypeError('addCreateEdge: tgt is not a Vertex')
edge = Edge(src, tgt, str_type) edge = Edge(src, tgt, str_type)
# link vertices connected to this edge # link vertices connected to this edge
edge.src.addOutgoingEdge(edge) edge.src.addOutgoingEdge(edge)
edge.tgt.addIncomingEdge(edge) edge.tgt.addIncomingEdge(edge)
self.addEdge(edge) self.addEdge(edge)
return edge return edge
def addEdge(self, edge): def addEdge(self, edge):
""" """
Stores an Edge into the Graph. Stores an Edge into the Graph.
""" """
if not isinstance(edge, Edge): if not isinstance(edge, Edge):
raise TypeError('addEdge expects an Edge') raise TypeError('addEdge expects an Edge')
# add edge, but it first creates a new set for the edge type # add edge, but it first creates a new set for the edge type
# if the type does not exist in the dictionary # if the type does not exist in the dictionary
self.edges.setdefault(edge.type, set()).add(edge) self.edges.setdefault(edge.type, set()).add(edge)

View file

@ -1,8 +1,8 @@
# coding: utf-8 # coding: utf-8
""" """
Author: Sten Vercamman Author: Sten Vercamman
Univeristy of Antwerp Univeristy of Antwerp
Example code for paper: Efficient model transformations for novices Example code for paper: Efficient model transformations for novices
url: http://msdl.cs.mcgill.ca/people/hv/teaching/MSBDesign/projects/Sten.Vercammen url: http://msdl.cs.mcgill.ca/people/hv/teaching/MSBDesign/projects/Sten.Vercammen
@ -21,24 +21,24 @@ at the workings behind various techniques for efficient pattern matching.
import graph as mg import graph as mg
def printGraph(fileName, graph, matched_v={}, matched_e={}): def printGraph(fileName, graph, matched_v={}, matched_e={}):
if not isinstance(graph, mg.Graph): if not isinstance(graph, mg.Graph):
raise TypeError('Can only print Graph Graphs') raise TypeError('Can only print Graph Graphs')
with open(fileName, 'w') as f: with open(fileName, 'w') as f:
f.write('digraph randomGraph {\n\n') f.write('digraph randomGraph {\n\n')
for str_type, plan_vertices in graph.vertices.items(): for str_type, plan_vertices in graph.vertices.items():
for plan_vertex in plan_vertices: for plan_vertex in plan_vertices:
vertex_str = str(id(plan_vertex)) + ' [label="'+str(str_type)+'"' vertex_str = str(id(plan_vertex)) + ' [label="'+str(str_type)+'"'
if plan_vertex in list(matched_v.values()): if plan_vertex in list(matched_v.values()):
vertex_str += ', style=dashed, style=filled]\n' vertex_str += ', style=dashed, style=filled]\n'
else: else:
vertex_str += ']\n' vertex_str += ']\n'
f.write(vertex_str) f.write(vertex_str)
for out_edge in plan_vertex.outgoing_edges: for out_edge in plan_vertex.outgoing_edges:
edge_str = str(id(plan_vertex)) + ' -> ' + str(id(out_edge.tgt)) + ' [label="'+str(out_edge.type)+'"' edge_str = str(id(plan_vertex)) + ' -> ' + str(id(out_edge.tgt)) + ' [label="'+str(out_edge.type)+'"'
if out_edge in list(matched_e.values()): if out_edge in list(matched_e.values()):
edge_str += ', style=dashed, penwidth = 4]\n' edge_str += ', style=dashed, penwidth = 4]\n'
else: else:
edge_str += ']\n' edge_str += ']\n'
f.write(edge_str) f.write(edge_str)
f.write('\n}') f.write('\n}')

View file

@ -1,8 +1,8 @@
# coding: utf-8 # coding: utf-8
""" """
Author: Sten Vercamman Author: Sten Vercamman
Univeristy of Antwerp Univeristy of Antwerp
Example code for paper: Efficient model transformations for novices Example code for paper: Efficient model transformations for novices
url: http://msdl.cs.mcgill.ca/people/hv/teaching/MSBDesign/projects/Sten.Vercammen url: http://msdl.cs.mcgill.ca/people/hv/teaching/MSBDesign/projects/Sten.Vercammen
@ -18,8 +18,8 @@ It is intended as a guideline, even for novices, and provides an in-depth look
at the workings behind various techniques for efficient pattern matching. at the workings behind various techniques for efficient pattern matching.
""" """
from generator import * from generator import *
from patternMatching import * from patternMatching import *
import graphToDot import graphToDot
@ -28,66 +28,66 @@ import random
debug = False debug = False
if __name__ == '__main__': if __name__ == '__main__':
""" """
The main function called when running from the command line. The main function called when running from the command line.
""" """
nr_of_vertices = 50 nr_of_vertices = 50
nr_of_diff_types_v = 2 nr_of_diff_types_v = 2
nr_of_edges = 150 nr_of_edges = 150
nr_of_diff_types_e = 2 nr_of_diff_types_e = 2
dv = [random.randint(0, nr_of_diff_types_v) for _ in range(nr_of_vertices)] dv = [random.randint(0, nr_of_diff_types_v) for _ in range(nr_of_vertices)]
de = [random.randint(0, nr_of_diff_types_e) for _ in range(nr_of_edges)] de = [random.randint(0, nr_of_diff_types_e) for _ in range(nr_of_edges)]
dc_inc = [random.randint(0, nr_of_vertices-1) for _ in range(nr_of_edges)] dc_inc = [random.randint(0, nr_of_vertices-1) for _ in range(nr_of_edges)]
dc_out = [random.randint(0, nr_of_vertices-1) for _ in range(nr_of_edges)] dc_out = [random.randint(0, nr_of_vertices-1) for _ in range(nr_of_edges)]
# override random graph by copy pasting output from terminal # override random graph by copy pasting output from terminal
# dv = [ 10,5,4,0,8,6,8,0,4,8,5,5,7,0,10,0,5,6,10,4,0,3,0,8,2,7,5,8,1,0,2,10,0,0,1,6,8,4,7,6,4,2,10,10,6,4,6,0,2,7 ] # dv = [ 10,5,4,0,8,6,8,0,4,8,5,5,7,0,10,0,5,6,10,4,0,3,0,8,2,7,5,8,1,0,2,10,0,0,1,6,8,4,7,6,4,2,10,10,6,4,6,0,2,7 ]
# de = [ 8,10,8,1,6,7,4,3,5,2,0,0,9,6,0,3,8,3,2,7,2,3,10,8,10,8,10,2,5,5,10,6,7,5,1,2,1,2,2,3,7,7,2,1,7,2,9,10,8,1,9,4,1,3,1,1,8,2,2,9,10,9,1,9,4,10,10,10,9,3,5,3,6,6,9,1,2,6,3,2,4,10,9,6,5,6,2,4,3,2,4,10,6,2,8,8,0,5,1,7,3,4,3,8,7,3,0,8,3,3,8,5,10,5,9,3,1,10,3,2,6,3,10,0,5,10,9,10,0,1,4,7,10,3,1,9,1,2,3,7,4,3,7,8,8,4,5,10,1,4 ] # de = [ 8,10,8,1,6,7,4,3,5,2,0,0,9,6,0,3,8,3,2,7,2,3,10,8,10,8,10,2,5,5,10,6,7,5,1,2,1,2,2,3,7,7,2,1,7,2,9,10,8,1,9,4,1,3,1,1,8,2,2,9,10,9,1,9,4,10,10,10,9,3,5,3,6,6,9,1,2,6,3,2,4,10,9,6,5,6,2,4,3,2,4,10,6,2,8,8,0,5,1,7,3,4,3,8,7,3,0,8,3,3,8,5,10,5,9,3,1,10,3,2,6,3,10,0,5,10,9,10,0,1,4,7,10,3,1,9,1,2,3,7,4,3,7,8,8,4,5,10,1,4 ]
# dc_inc = [ 0,25,18,47,22,25,16,45,38,25,5,45,15,44,17,46,6,17,35,8,16,29,48,47,25,34,4,20,24,1,47,44,8,25,32,3,16,6,33,21,6,13,41,10,17,25,21,33,31,30,5,4,45,26,16,42,12,25,29,3,32,30,14,26,11,13,7,13,3,43,43,22,48,37,20,28,15,40,19,33,43,16,49,36,11,25,9,42,3,22,16,40,42,44,27,30,1,18,10,35,19,6,9,43,37,38,45,19,41,14,37,45,0,31,29,31,24,20,44,46,8,45,43,3,38,38,35,12,19,45,7,34,20,28,12,17,45,17,35,49,20,21,49,1,35,38,38,36,33,30 ] # dc_inc = [ 0,25,18,47,22,25,16,45,38,25,5,45,15,44,17,46,6,17,35,8,16,29,48,47,25,34,4,20,24,1,47,44,8,25,32,3,16,6,33,21,6,13,41,10,17,25,21,33,31,30,5,4,45,26,16,42,12,25,29,3,32,30,14,26,11,13,7,13,3,43,43,22,48,37,20,28,15,40,19,33,43,16,49,36,11,25,9,42,3,22,16,40,42,44,27,30,1,18,10,35,19,6,9,43,37,38,45,19,41,14,37,45,0,31,29,31,24,20,44,46,8,45,43,3,38,38,35,12,19,45,7,34,20,28,12,17,45,17,35,49,20,21,49,1,35,38,38,36,33,30 ]
# dc_out = [ 9,2,49,49,37,33,16,21,5,46,4,15,9,6,14,22,16,33,23,21,15,31,37,23,47,3,30,26,35,9,29,21,39,32,22,43,5,9,41,30,31,30,37,33,31,34,23,22,34,26,44,36,38,33,48,5,9,34,13,7,48,41,43,26,26,7,12,6,12,28,22,8,29,22,24,27,16,4,31,41,32,15,19,20,38,0,26,18,43,46,40,17,29,14,34,14,32,17,32,47,16,45,7,4,35,22,42,11,38,2,0,29,4,38,17,44,9,23,5,10,31,17,1,11,16,5,37,27,35,32,45,16,18,1,14,4,42,24,43,31,21,38,6,34,39,46,20,1,38,47 ] # dc_out = [ 9,2,49,49,37,33,16,21,5,46,4,15,9,6,14,22,16,33,23,21,15,31,37,23,47,3,30,26,35,9,29,21,39,32,22,43,5,9,41,30,31,30,37,33,31,34,23,22,34,26,44,36,38,33,48,5,9,34,13,7,48,41,43,26,26,7,12,6,12,28,22,8,29,22,24,27,16,4,31,41,32,15,19,20,38,0,26,18,43,46,40,17,29,14,34,14,32,17,32,47,16,45,7,4,35,22,42,11,38,2,0,29,4,38,17,44,9,23,5,10,31,17,1,11,16,5,37,27,35,32,45,16,18,1,14,4,42,24,43,31,21,38,6,34,39,46,20,1,38,47 ]
dv = [0, 1, 0, 1, 0] dv = [0, 1, 0, 1, 0]
de = [0, 0, 0] de = [0, 0, 0]
dc_inc = [0, 2, 4] dc_inc = [0, 2, 4]
dc_out = [1, 3, 3] dc_out = [1, 3, 3]
gg = GraphGenerator(dv, de, dc_inc, dc_out, debug) gg = GraphGenerator(dv, de, dc_inc, dc_out, debug)
graph = gg.getRandomGraph() graph = gg.getRandomGraph()
print(graph.vertices) print(graph.vertices)
pattern = gg.getRandomPattern(3, 15, debug=debug) pattern = gg.getRandomPattern(3, 15, debug=debug)
print(pattern.vertices) print(pattern.vertices)
# override random pattern by copy pasting output from terminal to create # override random pattern by copy pasting output from terminal to create
# pattern, paste it in the createConstantPattern function in the generator.py # pattern, paste it in the createConstantPattern function in the generator.py
# pattern = gg.createConstantPattern() # pattern = gg.createConstantPattern()
# generate here to know pattern and graph before searching it # generate here to know pattern and graph before searching it
graphToDot.printGraph('randomPattern.dot', pattern) graphToDot.printGraph('randomPattern.dot', pattern)
graphToDot.printGraph('randomGraph.dot', graph) graphToDot.printGraph('randomGraph.dot', graph)
#PM = PatternMatching('naive') #PM = PatternMatching('naive')
#PM = PatternMatching('SP') #PM = PatternMatching('SP')
# PM = PatternMatching('Ullmann') # PM = PatternMatching('Ullmann')
PM = PatternMatching('VF2') PM = PatternMatching('VF2')
matches = [m for m in PM.matchVF2(pattern, graph)] matches = [m for m in PM.matchVF2(pattern, graph)]
print("found", len(matches), "matches:", matches) print("found", len(matches), "matches:", matches)
# regenerate graph, to show matched pattern # regenerate graph, to show matched pattern
for i, (v,e) in enumerate(matches): for i, (v,e) in enumerate(matches):
graphToDot.printGraph(f'randomGraph-{i}.dot', graph, v, e) graphToDot.printGraph(f'randomGraph-{i}.dot', graph, v, e)
if debug: if debug:
print(len(v)) print(len(v))
print('___') print('___')
print(v) print(v)
for key, value in v.items(): for key, value in v.items():
print(value.type) print(value.type)
print(len(e)) print(len(e))
print(e) print(e)
print('___') print('___')
for key, value in e.items(): for key, value in e.items():
print(value.type) print(value.type)

File diff suppressed because it is too large Load diff