Bladeren bron

showed that traditional approach for VF2 is slower or not at all scaleable

tpinna 10 jaren geleden
bovenliggende
commit
4a0c6b1213
1 gewijzigde bestanden met toevoegingen van 160 en 50 verwijderingen
  1. 160 50
      integration/code/pn_interface.alc

+ 160 - 50
integration/code/pn_interface.alc

@@ -124,6 +124,54 @@ Integer function are_connected(model: Element, el1:Element, el2:Element):
 			return 0 //edge is not connected
 	return 0 // if the function doesn't support it, assume disconnected
 
+Element function read_outgoing_assoc(model:Element, el1:Element, allowed:Element):
+	Element result
+	result = create_node()
+	if(is_edge(el1)):
+		set_add(result, read_edge_dst(el1))
+		return result
+	else:
+		Integer length
+		length = read_nr_out(el1)
+		log(cast_i2s(length))
+		Integer counter
+		counter = 0
+		Element edge
+		while (counter < length):
+			edge = read_out(el1, counter)
+			//check if edge is part of the model
+			if (set_in_node(allowed, edge)): 
+				//check if it is not attribute related
+				 if(bool_not(isAttributeRelated(model, edge))):
+					set_add(result, edge)
+			counter = counter + 1
+		return result
+	return create_node()
+
+Element function read_incoming_assoc(model:Element, el1:Element, allowed:Element):
+	Element result
+	result = create_node()
+	if(is_edge(el1)):
+		set_add(result, read_edge_src(el1))
+		return result
+	else:
+		//get possible types of associations		
+		Integer length
+		length = read_nr_in(model["typemapping"][el1])
+		Integer counter
+		counter = 0
+		
+		Element edge
+		while (counter < length):
+			edge = read_in(el1, counter)
+			//check if edge is part of the model
+			if (set_in_node(allowed, edge)): 
+				//check if it is not attribute related
+				 if(bool_not(isAttributeRelated(model, edge))):
+					set_add(result, edge)
+			counter = counter + 1
+		return result
+	return create_node()
 
 Element function new_SearchState(OldSearchState : Element, TransfModel : Element, NewTransfElem: Element, HostModel : Element, NewHostElem : Element):
 	//some variables
@@ -131,6 +179,12 @@ Element function new_SearchState(OldSearchState : Element, TransfModel : Element
 	nss = create_node()
 	Integer index // used for list looping
 	Element elem // reusable loop variable
+	Element ol //old list = old pattern out
+	Element nl //new list = new N pattern out
+	Element allowedP
+	allowedP = OldSearchState["V_pattern"]
+	Element allowedH
+	allowedH = OldSearchState["V_host"]
 	
 	//new MATCHES
 	dict_add(nss, "matches", OldSearchState["matches"]) //hopefully works as a reference
@@ -140,21 +194,31 @@ Element function new_SearchState(OldSearchState : Element, TransfModel : Element
 	OldCurMatchKeys = dict_keys(OldSearchState["curmatch"])
 	Element new_curmatch //the new curmatch
 	new_curmatch = create_node()
+	Element new_curmatch_pattern //keep a set of all matches pattern nodes
+	new_curmatch_pattern = create_node() 
+	Element new_curmatch_host //keep a set of all matched host nodes
+	new_curmatch_host = create_node()
 	while (integer_lt(0, list_len(OldCurMatchKeys))): //copying the old curmatch
 		index = set_pop(OldCurMatchKeys)
 		dict_add(new_curmatch, index, OldSearchState["curmatch"][index]) 
+		set_add(new_curmatch_pattern, OldSearchState["curmatch"][index]["pn"] )
+		set_add(new_curmatch_host, OldSearchState["curmatch"][index]["hn"] )
 	Element newPair // the new pair to be added
 	newPair = create_node()
 	dict_add(newPair, "pn", NewTransfElem) //PatternNode
+	set_add(new_curmatch_pattern, NewTransfElem)
 	dict_add(newPair, "hn", NewHostElem) // HostNode
+	set_add(new_curmatch_host, NewHostElem)
 	Integer plabel
 	plabel = read_attribute(TransfModel, getName(TransfModel, NewTransfElem), "plabel")
 	dict_add(new_curmatch, plabel, newPair) //add pair to new curmatch
 	dict_add(nss, "curmatch", new_curmatch) //add curmatch to state
 	
+	//new CURMATCH_pattern and host (constructed during the previous loop)
+	dict_add(nss, "curmatch_pattern", new_curmatch_pattern)
+	dict_add(nss, "curmatch_host", new_curmatch_pattern)
+	
 	//new N_PATTERN_OUT (copy everything but the new match elements)
-	Element ol //old list = old pattern out
-	Element nl //new list = new N pattern out
 	ol = OldSearchState["N_pattern_out"]
 	nl = create_node()
 	index = 0
@@ -162,7 +226,12 @@ Element function new_SearchState(OldSearchState : Element, TransfModel : Element
 		elem = list_read(ol, index)
 		index = index + 1
 		if(bool_not(element_eq(elem, NewTransfElem))): 
-			list_append(nl, elem)
+			set_add(nl, elem)
+	ol = read_outgoing_assoc(TransfModel, NewTransfElem, allowedP)
+	while (read_nr_out(ol)>0):
+		elem = set_pop(ol)
+		if (bool_not(set_in_node(new_curmatch_pattern, elem))):
+			list_append(nl,elem)
 	dict_add(nss, "N_pattern_out", nl)
 	
 	//new N_HOST_OUT (copy everything but the new match elements)
@@ -174,6 +243,11 @@ Element function new_SearchState(OldSearchState : Element, TransfModel : Element
 		index = index + 1
 		if(bool_not(element_eq(elem, NewHostElem))): 
 			list_append(nl, elem)
+	ol = read_outgoing_assoc(HostModel, NewHostElem, allowedH)
+	while (read_nr_out(ol)>0):
+		elem = set_pop(ol)
+		if (bool_not(set_in_node(new_curmatch_host, elem))):
+			list_append(nl,elem)
 	dict_add(nss, "N_host_out", nl)
 	
 	//new N_PATTERN_IN (copy everything but the new match elements)
@@ -185,6 +259,11 @@ Element function new_SearchState(OldSearchState : Element, TransfModel : Element
 		index = index + 1
 		if(bool_not(element_eq(elem, NewTransfElem))):
 			list_append(nl, elem)
+	ol = read_incoming_assoc(TransfModel, NewTransfElem, allowedP)
+	while (read_nr_out(ol)>0):
+		elem = set_pop(ol)
+		if (bool_not(set_in_node(new_curmatch_pattern, elem))):
+			list_append(nl,elem)
 	dict_add(nss, "N_pattern_in", nl)
 	
 	//new N_HOST_IN (copy everything but the new match elements
@@ -196,56 +275,48 @@ Element function new_SearchState(OldSearchState : Element, TransfModel : Element
 		index = index + 1
 		if(bool_not(element_eq(elem, NewHostElem))): 
 			list_append(nl, elem)
+	ol = read_incoming_assoc(HostModel, NewHostElem, allowedH)
+	while (read_nr_out(ol) > 0):
+		elem = set_pop(ol)
+		if (bool_not(set_in_node(new_curmatch_host, elem))):
+			list_append(nl,elem)
 	dict_add(nss, "N_host_in", nl)
 	
 	//new V_PATTERN
-	ol = OldSearchState["V_pattern"]
-	nl = create_node()
-	index = 0
-	Integer connectedness
-	while (index < list_len(ol)): //loop trough old list
-		elem = list_read(ol, index)
-		index = index + 1
-		if(bool_not(element_eq(elem, NewTransfElem))):
-			connectedness = are_connected(TransfModel, NewTransfElem, elem)
-			if (connectedness == 0): // if not connected, keep in V
-				list_append(nl, elem) 
-			elif (connectedness == 1): //if connected in outwards manner, don't keep in v and add to outlist
-				list_append(nss["N_pattern_out"], elem)
-			elif (connectedness == 2): //if connected in inwards manner, don't keep in v and add to inlist
-				list_append(nss["N_pattern_in"], elem)
-			else:
-				log("new_SearchState: unsupported connectedness value")
-				log(cast_i2s(connectedness))
-	dict_add(nss, "V_pattern", nl)
+	dict_add(nss, "V_pattern", allowedP)
 	
 	//new V_HOST
-	ol = OldSearchState["V_host"]
-	nl = create_node()
-	index = 0
-	while (index < list_len(ol)): //loop trough old list
-		elem = list_read(ol, index)
-		index = index + 1
-		if(bool_not(element_eq(elem, NewHostElem))):
-			connectedness = are_connected(HostModel, NewHostElem, elem)
-			if (connectedness == 0): // if not connected, keep in V
-				list_append(nl, elem) 
-			elif (connectedness == 1): //if connected in outwards manner, don't keep in v and add to outlist
-				list_append(nss["N_host_out"], elem)
-			elif (connectedness == 2): //if connected in inwards manner, don't keep in v and add to inlist
-				list_append(nss["N_host_in"], elem)
-			else:
-				log("new_SearchState: unsupported connectedness value")
-				log(cast_i2s(connectedness))
-	dict_add(nss, "V_host", nl)
+	dict_add(nss, "V_host", allowedH)
 	
 	// copy pattern_size
 	dict_add(nss, "pattern_size", OldSearchState["pattern_size"])
 	
 	return nss
 
-Element function transf_vf2(SearchState: Element, transf_m : Element, host_m : Element):
+Element function destruct(nss:Element):
+	log("destructing")
+	//destruct current_match
+	Element todelete
+	while (read_nr_out(nss["curmatch"])>0):
+		todelete = set_pop(nss["curmatch"])
+		delete_element(todelete)
+	
+	delete_element(nss["curmatch_pattern"])
+	delete_element(nss["curmatch_host"])
+	delete_element(nss["N_pattern_out"])
+	delete_element(nss["N_pattern_in"])
+	delete_element(nss["N_host_in"])
+	delete_element(nss["N_host_out"])
 	
+	
+	
+	delete_element(nss)
+	log("end destructing")
+	
+	return 0
+
+Element function transf_vf2(SearchState: Element, transf_m : Element, host_m : Element):
+	log("transf_vf2")
 	// get the current match from the search-state
 	Element current_match
 	current_match = dict_read(SearchState,"curmatch")
@@ -254,7 +325,20 @@ Element function transf_vf2(SearchState: Element, transf_m : Element, host_m : E
 	Integer pattern_size
 	pattern_size = SearchState["pattern_size"]
 	if pattern_size == list_len(current_match):
-		list_append(SearchState["matches"], SearchState["curmatch"])
+		Element OldCurMatchKeys // for looping trough old curmatch (for copying)
+		OldCurMatchKeys = dict_keys(SearchState["curmatch"])
+		Element new_curmatch //the new curmatch
+		new_curmatch = create_node()
+		Element deepcopy
+		Integer index
+		
+		while (integer_lt(0, list_len(OldCurMatchKeys))): //copying the old curmatch
+			index = set_pop(OldCurMatchKeys)
+			deepcopy = create_node()
+			dict_add(deepcopy, "pn", SearchState["curmatch"][index]["pn"])
+			dict_add(deepcopy, "hn", SearchState["curmatch"][index]["hn"])
+			dict_add(new_curmatch, index, deepcopy) 
+		list_append(SearchState["matches"], new_curmatch)
 		//log("MATCHED")
 		return SearchState
 
@@ -263,8 +347,6 @@ Element function transf_vf2(SearchState: Element, transf_m : Element, host_m : E
 		return SearchState
 	if (list_len(SearchState["N_pattern_in"]) > list_len(SearchState["N_host_in"])):
 		return SearchState
-	if (list_len(SearchState["V_pattern"]) > list_len(SearchState["V_host"])):
-		return SearchState
 
 	//initialise some variables
 	Integer index2 //an index used for looping trough host_list
@@ -287,6 +369,7 @@ Element function transf_vf2(SearchState: Element, transf_m : Element, host_m : E
 				nss = transf_vf2(nss, transf_m, host_m)
 				dict_delete(SearchState, "matches")
 				dict_add(SearchState, "matches", nss["matches"])
+				destruct(nss)
 	elif ( list_len(SearchState["N_pattern_in"]) > 0 ):
 		//check for candidates in (N_pattern_in, N_host_in)
 		host_list = SearchState["N_host_in"]
@@ -300,10 +383,12 @@ Element function transf_vf2(SearchState: Element, transf_m : Element, host_m : E
 				nss = transf_vf2(nss, transf_m, host_m)
 				dict_delete(SearchState, "matches")
 				dict_add(SearchState, "matches", nss["matches"])
+				destruct(nss)
 	elif ( list_len(SearchState["V_pattern"]) > 0 ):
 		//check for candidates in (V_pattern, V_host))
 		host_list = SearchState["V_host"]
-		pattern_node = list_read(SearchState["V_pattern"], 0)
+		pattern_node = set_pop(SearchState["V_pattern"])
+		//list_read(SearchState["V_pattern"], 0)
 		index2 = 0
 		while (index2 < list_len(host_list)):
 			host_node = list_read(host_list, index2)
@@ -313,8 +398,10 @@ Element function transf_vf2(SearchState: Element, transf_m : Element, host_m : E
 				nss = transf_vf2(nss, transf_m, host_m)
 				dict_delete(SearchState, "matches")
 				dict_add(SearchState, "matches", nss["matches"])
+				destruct(nss)
 	else:
 		log("no candidate found")
+	log(" end transf_vf2")
 	return SearchState
 
 
@@ -356,6 +443,8 @@ Element function tf_matchAll(tf_ma_transformation: Element, tf_ma_pattern : Elem
 	SearchState = create_node()
 	dict_add(SearchState, "matches", create_node())
 	dict_add(SearchState, "curmatch", create_node())
+	dict_add(SearchState, "curmatch_pattern", create_node())
+	dict_add(SearchState, "curmatch_host", create_node())
 	dict_add(SearchState, "N_pattern_out", create_node())
 	dict_add(SearchState, "N_host_out", create_node())
 	dict_add(SearchState, "N_pattern_in", create_node())
@@ -370,8 +459,14 @@ Element function tf_matchAll(tf_ma_transformation: Element, tf_ma_pattern : Elem
 	
 	//timing info
 	log(string_join("matching took ", cast_i2s( current_time() - starttime)))
-
-	return SearchState["matches"]
+	
+	delete_element(tf_ma_ramified_nodes)
+	delete_element(host_nodes)
+	
+	Element matches 
+	matches = SearchState["matches"]
+	destruct(SearchState)
+	return matches
 
 Element function mergeLHSNAC(tf_er_lhs : Element, tf_er_nac: Element):
 	
@@ -583,6 +678,21 @@ Element function tf_executeFRule(tf_er_transformation: Element,tf_er_rule: Eleme
 			dict_add(plabel_to_rhsnode,rhs_plabel, rhs_node)
 		
 		rhs_rewrite(final_matches ,plabel_to_rhsnode, tf_er_transformation, tf_er_model )
+	
+	//clean up matches
+	Element todelete
+	Element todelete2
+	while (read_nr_out(tf_er_nac) >0):
+		todelete2 = set_pop(tf_er_nac)
+		while (read_nr_out(todelete2)>0):
+			todelete = set_pop(todelete2)
+			delete_element(todelete)
+		
+	while (read_nr_out(tf_er_lhs) >0):
+		todelete2 = set_pop(tf_er_nac)
+		while (read_nr_out(todelete2)>0):
+			todelete = set_pop(todelete2)
+			delete_element(todelete)
 		
 	return True
 
@@ -1018,11 +1128,11 @@ Element function petrinet_transformation(root: Element):
 	instantiate_link(my_model, "getrule","", "frule3", "produce_tokens")
 	
 	//create circularity link
-	instantiate_link(my_model, "next_onSucces", "",  "frule3",  "arule1")
+	//instantiate_link(my_model, "next_onSucces", "",  "frule3",  "arule1")
 	//if you cannot consume, still try to produce (for source transitions)
-	instantiate_link(my_model, "next_onFailure", "",  "frule2",  "frule3")
+	//instantiate_link(my_model, "next_onFailure", "",  "frule2",  "frule3")
 	//if you cannot produce, still check for other transitions (it might have consumed already)
-	instantiate_link(my_model, "next_onFailure", "",  "frule3",  "arule1")
+	//instantiate_link(my_model, "next_onFailure", "",  "frule3",  "arule1")