Просмотр исходного кода

pattern matching: convert tabs to spaces

Joeri Exelmans 1 год назад
Родитель
Сommit
3ae35a87d0
5 измененных файлов с 969 добавлено и 955 удалено
  1. 177 177
      pattern_matching/generator.py
  2. 132 132
      pattern_matching/graph.py
  3. 22 22
      pattern_matching/graphToDot.py
  4. 67 67
      pattern_matching/main.py
  5. 571 557
      pattern_matching/patternMatching.py

+ 177 - 177
pattern_matching/generator.py

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

+ 132 - 132
pattern_matching/graph.py

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

+ 22 - 22
pattern_matching/graphToDot.py

@@ -1,8 +1,8 @@
 # coding: utf-8
 
 """
-Author:		Sten Vercamman
-			Univeristy of Antwerp
+Author:        Sten Vercamman
+            Univeristy of Antwerp
 
 Example code for paper: Efficient model transformations for novices
 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
 
 def printGraph(fileName, graph, matched_v={}, matched_e={}):
-	if not isinstance(graph, mg.Graph):
-		raise TypeError('Can only print Graph Graphs')
+    if not isinstance(graph, mg.Graph):
+        raise TypeError('Can only print Graph Graphs')
 
-	with open(fileName, 'w') as f:
-		f.write('digraph randomGraph {\n\n')
-		for str_type, plan_vertices in graph.vertices.items():
-			for plan_vertex in plan_vertices:
-				vertex_str	= str(id(plan_vertex)) + ' [label="'+str(str_type)+'"'
-				if plan_vertex in list(matched_v.values()):
-					vertex_str	+= ', style=dashed, style=filled]\n'
-				else:
-					vertex_str	+= ']\n'
-				f.write(vertex_str)
-				for out_edge in plan_vertex.outgoing_edges:
-					edge_str	= str(id(plan_vertex)) + ' -> ' + str(id(out_edge.tgt)) + ' [label="'+str(out_edge.type)+'"'
-					if out_edge in list(matched_e.values()):
-						edge_str	+= ', style=dashed, penwidth = 4]\n'
-					else:
-						edge_str	+= ']\n'
-					f.write(edge_str)
-		f.write('\n}')
+    with open(fileName, 'w') as f:
+        f.write('digraph randomGraph {\n\n')
+        for str_type, plan_vertices in graph.vertices.items():
+            for plan_vertex in plan_vertices:
+                vertex_str    = str(id(plan_vertex)) + ' [label="'+str(str_type)+'"'
+                if plan_vertex in list(matched_v.values()):
+                    vertex_str    += ', style=dashed, style=filled]\n'
+                else:
+                    vertex_str    += ']\n'
+                f.write(vertex_str)
+                for out_edge in plan_vertex.outgoing_edges:
+                    edge_str    = str(id(plan_vertex)) + ' -> ' + str(id(out_edge.tgt)) + ' [label="'+str(out_edge.type)+'"'
+                    if out_edge in list(matched_e.values()):
+                        edge_str    += ', style=dashed, penwidth = 4]\n'
+                    else:
+                        edge_str    += ']\n'
+                    f.write(edge_str)
+        f.write('\n}')

+ 67 - 67
pattern_matching/main.py

@@ -1,8 +1,8 @@
 # coding: utf-8
 
 """
-Author:		Sten Vercamman
-			Univeristy of Antwerp
+Author:        Sten Vercamman
+            Univeristy of Antwerp
 
 Example code for paper: Efficient model transformations for novices
 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.
 """
 
-from generator			import *
-from patternMatching	import *
+from generator            import *
+from patternMatching    import *
 
 import graphToDot
 
@@ -28,66 +28,66 @@ import random
 debug = False
 
 if __name__ == '__main__':
-	"""
-	The main function called when running from the command line.
-	"""
-	nr_of_vertices		= 50
-	nr_of_diff_types_v	= 2
-	nr_of_edges			= 150
-	nr_of_diff_types_e	= 2
-
-	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)]
-	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)]
-
-	# 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 ]
-	# 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_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]
-	de = [0, 0, 0]
-	dc_inc = [0, 2, 4]
-	dc_out = [1, 3, 3]
-	
-	gg	= GraphGenerator(dv, de, dc_inc, dc_out, debug)
-
-	graph	= gg.getRandomGraph()
-
-	print(graph.vertices)
-	pattern	= gg.getRandomPattern(3, 15, debug=debug)
-	print(pattern.vertices)
-
-	# override random pattern by copy pasting output from terminal to create
-	# pattern, paste it in the createConstantPattern function in the generator.py
-	# pattern	= gg.createConstantPattern()
-
-	# generate here to know pattern and graph before searching it
-	graphToDot.printGraph('randomPattern.dot', pattern)
-	graphToDot.printGraph('randomGraph.dot', graph)
-
-	
-	#PM	= PatternMatching('naive')
-	#PM	= PatternMatching('SP')
-	# PM	= PatternMatching('Ullmann')
-	PM	= PatternMatching('VF2')
-	matches = [m for m in PM.matchVF2(pattern, graph)]
-	print("found", len(matches), "matches:", matches)
-
-	# regenerate graph, to show matched pattern
-	for i, (v,e) in enumerate(matches):
-		graphToDot.printGraph(f'randomGraph-{i}.dot', graph, v, e)
-
-	if debug:
-		print(len(v))
-		print('___')
-		print(v)
-		for key, value in v.items():
-			print(value.type)
-		print(len(e))
-		print(e)
-		print('___')
-		for key, value in e.items():
-			print(value.type)
+    """
+    The main function called when running from the command line.
+    """
+    nr_of_vertices        = 50
+    nr_of_diff_types_v    = 2
+    nr_of_edges            = 150
+    nr_of_diff_types_e    = 2
+
+    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)]
+    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)]
+
+    # 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 ]
+    # 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_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]
+    de = [0, 0, 0]
+    dc_inc = [0, 2, 4]
+    dc_out = [1, 3, 3]
+    
+    gg    = GraphGenerator(dv, de, dc_inc, dc_out, debug)
+
+    graph    = gg.getRandomGraph()
+
+    print(graph.vertices)
+    pattern    = gg.getRandomPattern(3, 15, debug=debug)
+    print(pattern.vertices)
+
+    # override random pattern by copy pasting output from terminal to create
+    # pattern, paste it in the createConstantPattern function in the generator.py
+    # pattern    = gg.createConstantPattern()
+
+    # generate here to know pattern and graph before searching it
+    graphToDot.printGraph('randomPattern.dot', pattern)
+    graphToDot.printGraph('randomGraph.dot', graph)
+
+    
+    #PM    = PatternMatching('naive')
+    #PM    = PatternMatching('SP')
+    # PM    = PatternMatching('Ullmann')
+    PM    = PatternMatching('VF2')
+    matches = [m for m in PM.matchVF2(pattern, graph)]
+    print("found", len(matches), "matches:", matches)
+
+    # regenerate graph, to show matched pattern
+    for i, (v,e) in enumerate(matches):
+        graphToDot.printGraph(f'randomGraph-{i}.dot', graph, v, e)
+
+    if debug:
+        print(len(v))
+        print('___')
+        print(v)
+        for key, value in v.items():
+            print(value.type)
+        print(len(e))
+        print(e)
+        print('___')
+        for key, value in e.items():
+            print(value.type)

Разница между файлами не показана из-за своего большого размера
+ 571 - 557
pattern_matching/patternMatching.py