Yentl Van Tendeloo 8 anos atrás
pai
commit
e94fe8e192

BIN
bootstrap/bootstrap.m.gz


+ 17 - 2
bootstrap/primitives.alc

@@ -195,7 +195,7 @@ Element function set_copy(a : Element):
 
 	return b!
 
-Element function set_to_string(s : Element):
+String function set_to_string(s : Element):
 	String result
 	Integer i
 
@@ -210,7 +210,22 @@ Element function set_to_string(s : Element):
 
 	return result!
 
-Element function dict_to_string(d : Element):
+String function list_to_string(s : Element):
+	String result
+	Integer i
+
+	result = "["
+	i = 0
+	while (i < read_nr_out(s)):
+		result = result + cast_v2s(dict_read(s, i))
+		result = result + ", "
+		i = i + 1
+	
+	result = result + "]"
+
+	return result!
+
+String function dict_to_string(d : Element):
 	String result
 	Element keys
 	Element key

+ 43 - 30
bootstrap/ramify.alc

@@ -32,20 +32,28 @@ Element function ramify(model : Element):
 	add_AL_to_MM(new_model)
 
 	// Add some default elements
-	//	Class LHS {
+	//	Class LHS_Root {
 	//		constraint : funcdef {
 	//			target_upper_cardinality = 1
 	//		}
 	//		upper_cardinality = 1
 	//		lower_cardinality = 1
 	//	}
-	instantiate_node(new_model, "Class", "LHS")
-	instantiate_attribute(new_model, "LHS", "lower_cardinality", 1)
-	instantiate_attribute(new_model, "LHS", "upper_cardinality", 1)
-	instantiate_link(new_model, "Association", "LHS_constraint", "LHS", "funcdef")
+	instantiate_node(new_model, "Class", "LHS_Root")
+	instantiate_attribute(new_model, "LHS_Root", "lower_cardinality", 1)
+	instantiate_attribute(new_model, "LHS_Root", "upper_cardinality", 1)
+	instantiate_link(new_model, "Association", "LHS_constraint", "LHS_Root", "funcdef")
 	instantiate_attribute(new_model, "LHS_constraint", "name", "constraint")
 	instantiate_attribute(new_model, "LHS_constraint", "target_upper_cardinality", 1)
 
+	//  Class LHS : LHS_Root {}
+	instantiate_node(new_model, "Class", "LHS")
+	instantiate_link(new_model, "Inheritance", "", "LHS", "LHS_Root")
+
+	//  Class NAC : LHS_Root {}
+	instantiate_node(new_model, "Class", "NAC")
+	instantiate_link(new_model, "Inheritance", "", "NAC", "LHS_Root")
+
 	//	Class Pre_Element {
 	//		label : String {
 	//			target_lower_cardinality = 1
@@ -64,8 +72,8 @@ Element function ramify(model : Element):
 	instantiate_attribute(new_model, "Pre_Element_constraint", "name", "constraint")
 	instantiate_attribute(new_model, "Pre_Element_constraint", "target_upper_cardinality", 1)
 
-	// Association LHS_contains (LHS, Pre_Element) {}
-	instantiate_link(new_model, "Association", "LHS_contains", "LHS", "Pre_Element")
+	// Association LHS_contains (LHS_Root, Pre_Element) {}
+	instantiate_link(new_model, "Association", "LHS_contains", "LHS_Root", "Pre_Element")
 	instantiate_attribute(new_model, "LHS_contains", "name", "contains")
 
 	//	Class RHS {
@@ -209,41 +217,46 @@ Element function ramify(model : Element):
 	instantiate_attribute(new_model, "OnFailure", "target_lower_cardinality", 1)
 	instantiate_attribute(new_model, "OnFailure", "target_upper_cardinality", 1)
 
-	// 	Class Query : Rule {}
-	instantiate_node(new_model, "Class", "Query")
-	instantiate_link(new_model, "Inheritance", "", "Query", "Rule")
+	// Class LHSRule : Rule {}
+	instantiate_node(new_model, "Class", "LHSRule")
+	instantiate_link(new_model, "Inheritance", "", "LHSRule", "Rule")
 
-	// 	Association QueryLHS (Query, LHS) {
+	// 	Association LHSLink (LHSRule, LHS) {
 	//		target_lower_cardinality = 1
 	//		target_upper_cardinality = 1
 	//	}
-	instantiate_link(new_model, "Association", "QueryLHS", "Query", "LHS")
-	instantiate_attribute(new_model, "QueryLHS", "target_lower_cardinality", 1)
-	instantiate_attribute(new_model, "QueryLHS", "target_upper_cardinality", 1)
+	instantiate_link(new_model, "Association", "LHSLink", "LHSRule", "LHS")
+	instantiate_attribute(new_model, "LHSLink", "target_lower_cardinality", 1)
+	instantiate_attribute(new_model, "LHSLink", "target_upper_cardinality", 1)
 
-	//	Class Atomic : Rule {}
-	instantiate_node(new_model, "Class", "Atomic")
-	instantiate_link(new_model, "Inheritance", "", "Atomic", "Rule")
+	// 	Association NACLink (LHSRule, NAC) {}
+	instantiate_link(new_model, "Association", "NACLink", "LHSRule", "NAC")
 
-	// 	Association AtomicLHS (Atomic, LHS) {
-	//		target_lower_cardinality = 1
-	//		target_upper_cardinality = 1
-	//	}
-	instantiate_link(new_model, "Association", "AtomicLHS", "Atomic", "LHS")
-	instantiate_attribute(new_model, "AtomicLHS", "target_lower_cardinality", 1)
-	instantiate_attribute(new_model, "AtomicLHS", "target_upper_cardinality", 1)
+	//  Class RHSRule : Rule {}
+	instantiate_node(new_model, "Class", "RHSRule")
+	instantiate_link(new_model, "Inheritance", "", "RHSRule", "Rule")
 
-	// 	Association AtomicRHS (Atomic, RHS) {
+	// 	Association RHSLink (RHSRule, RHS) {
 	//		target_lower_cardinality = 1
 	//		target_upper_cardinality = 1
 	//	}
-	instantiate_link(new_model, "Association", "AtomicRHS", "Atomic", "RHS")
-	instantiate_attribute(new_model, "AtomicRHS", "target_lower_cardinality", 1)
-	instantiate_attribute(new_model, "AtomicRHS", "target_upper_cardinality", 1)
+	instantiate_link(new_model, "Association", "RHSLink", "RHSRule", "RHS")
+	instantiate_attribute(new_model, "RHSLink", "target_lower_cardinality", 1)
+	instantiate_attribute(new_model, "RHSLink", "target_upper_cardinality", 1)
+
+	// 	Class Query : LHSRule {}
+	instantiate_node(new_model, "Class", "Query")
+	instantiate_link(new_model, "Inheritance", "", "Query", "LHSRule")
+
+	//	Class Atomic : LHSRule, RHSRule {}
+	instantiate_node(new_model, "Class", "Atomic")
+	instantiate_link(new_model, "Inheritance", "", "Atomic", "LHSRule")
+	instantiate_link(new_model, "Inheritance", "", "Atomic", "RHSRule")
 
-	// 	Class ForAll : Atomic {}
+	// 	Class ForAll : LHSRule, RHSRule {}
 	instantiate_node(new_model, "Class", "ForAll")
-	instantiate_link(new_model, "Inheritance", "", "ForAll", "Atomic")
+	instantiate_link(new_model, "Inheritance", "", "ForAll", "LHSRule")
+	instantiate_link(new_model, "Inheritance", "", "ForAll", "RHSRule")
 
 	//	Class Composite : Rule {}
 	instantiate_node(new_model, "Class", "Composite")

+ 50 - 16
bootstrap/transform.alc

@@ -5,7 +5,7 @@ include "random.alh"
 include "conformance_scd.alh"
 include "model_management.alh"
 
-Element function make_matching_schedule(schedule_model : Element, LHS : Element):
+Element function make_matching_schedule(schedule_model : Element, LHS : String, ignore : Element):
 	Element schedule
 	Element workset
 	Element all_elements
@@ -42,7 +42,9 @@ Element function make_matching_schedule(schedule_model : Element, LHS : Element)
 			// Check if element might not be already used somewhere
 			if (bool_not(set_in(schedule, next))):
 				if (set_in(full_all_elements, next)):
-					list_append(schedule, next)
+					if (bool_not(set_in(ignore, read_attribute(schedule_model, next, "label")))):
+						list_append(schedule, next)
+						required_size = required_size - 1
 
 					// If it is an edge, we should also add the target and source
 					if (is_edge(schedule_model["model"][next])):
@@ -149,12 +151,50 @@ Element function get_possible_bindings(host_model : Element, schedule_model : El
 
 	return filtered_options!
 
-Element function match(host_model : Element, schedule_model : Element, LHS : Element):
+Element function full_match(host_model : Element, schedule_model : Element, current : String):
+	Element NACs
+	String LHS
+	String NAC
+	Element mappings
+	Element mapping
+	Integer i
+	Element result
+	Element final_mappings
+	Boolean allowed
+
+	final_mappings = create_node()
+
+	// First match the LHS part itself to get initial mappings
+	LHS = set_pop(allAssociationDestinations(schedule_model, current, "LHSLink"))
+	mappings = match(host_model, schedule_model, LHS, create_node())
+
+	// Got a list of all possible mappings, now filter based on NACs
+	NACs = allAssociationDestinations(schedule_model, current, "NACLink")
+
+	// For each possible mapping, we check all NACs!
+	while (read_nr_out(mappings) > 0):
+		mapping = set_pop(mappings)
+		i = 0
+		allowed = True
+		while (bool_and(i < read_nr_out(NACs), allowed)):
+			NAC = read_edge_dst(read_out(NACs, i))
+			result = match(host_model, schedule_model, NAC, mapping)
+			if (read_nr_out(result) > 0):
+				// NAC could be matched, and therefore is not allowed
+				allowed = False
+			i = i + 1
+		
+		if (allowed):
+			set_add(final_mappings, mapping)
+
+	return final_mappings!
+
+Element function match(host_model : Element, schedule_model : Element, LHS : String, initial_mapping : Element):
 	// Match the schedule_model to the host_model, returning all possible mappings from schedule_model elements to host_model elements
 
 	// Make the schedule first
 	Element schedule
-	schedule = make_matching_schedule(schedule_model, LHS)
+	schedule = make_matching_schedule(schedule_model, LHS, dict_keys(initial_mapping))
 
 	// Now follow the schedule, incrementally building all mappings
 	Element mappings
@@ -166,7 +206,7 @@ Element function match(host_model : Element, schedule_model : Element, LHS : Ele
 	Element options
 
 	mappings = create_node()
-	set_add(mappings, create_node())
+	set_add(mappings, initial_mapping)
 	while (bool_and(read_nr_out(schedule) > 0, read_nr_out(mappings) > 0)):
 		current_element = list_pop(schedule, 0)
 		new_mappings = create_node()
@@ -358,16 +398,14 @@ Boolean function transform_composite(host_model : Element, schedule_model : Elem
 Boolean function transform_atomic(host_model : Element, schedule_model : Element, current : String):
 	// Execute the atomic transformation
 	Element mappings
-	String LHS
 	Element mapping
-	LHS = set_pop(allAssociationDestinations(schedule_model, current, "AtomicLHS"))
-	mappings = match(host_model, schedule_model, LHS)
+	mappings = full_match(host_model, schedule_model, current)
 
 	if (read_nr_out(mappings) > 0):
 		// Pick one!
 		mapping = random_choice(set_to_list(mappings))
 		String RHS
-		RHS = set_pop(allAssociationDestinations(schedule_model, current, "AtomicRHS"))
+		RHS = set_pop(allAssociationDestinations(schedule_model, current, "RHSLink"))
 		rewrite(host_model, schedule_model, RHS, mapping)
 		return True!
 	else:
@@ -376,13 +414,11 @@ Boolean function transform_atomic(host_model : Element, schedule_model : Element
 Boolean function transform_forall(host_model : Element, schedule_model : Element, current : String):
 	// Execute the atomic transformation
 	Element mappings
-	String LHS
 	String RHS
 	Element mapping
 	Boolean result
 
-	LHS = set_pop(allAssociationDestinations(schedule_model, current, "AtomicLHS"))
-	mappings = match(host_model, schedule_model, LHS)
+	mappings = full_match(host_model, schedule_model, current)
 
 	if (read_nr_out(mappings) > 0):
 		result = True
@@ -392,18 +428,16 @@ Boolean function transform_forall(host_model : Element, schedule_model : Element
 	while (read_nr_out(mappings) > 0):
 		mapping = set_pop(mappings)
 		// TODO check if there are actually no deletions happening in the meantime of other matched elements...
-		RHS = set_pop(allAssociationDestinations(schedule_model, current, "AtomicRHS"))
+		RHS = set_pop(allAssociationDestinations(schedule_model, current, "RHSLink"))
 		rewrite(host_model, schedule_model, RHS, mapping)
 
 	return result!
 
 Boolean function transform_query(host_model : Element, schedule_model : Element, current : String):
 	// Execute the transformation
-	String LHS
 	Element mappings
 	Element mapping
-	LHS = set_pop(allAssociationDestinations(schedule_model, current, "QueryLHS"))
-	mappings = match(host_model, schedule_model, LHS)
+	mappings = full_match(host_model, schedule_model, current)
 
 	if (read_nr_out(mappings) > 0):
 		return True!

+ 32 - 16
integration/test_pn_interface.py

@@ -25,6 +25,7 @@ transform = ["Which model do you want to transform?",
             ]
 
 transform_result_true = ["Transformation result: True"]
+transform_result_false = ["Transformation result: False"]
 
 split = ["Name of the model to split up?",
          "Name of new metamodel?",
@@ -629,25 +630,38 @@ Element function constraint(model : Element, name : String):
                     {Contains} Failure failure {}
                     {Contains} Success success {}
                     {Contains} Atomic mark {
+                        NAC {
+                            Pre_Transition mark_nac_t {
+                                label = "1"
+                            }
+                            Pre_Place mark_nac_p{
+                                label = "10"
+                            }
+                            Pre_P2T (mark_nac_p, mark_nac_t){
+                                label = "11"
+                            }
+
+                            constraint = $
+                                include "primitives.alh"
+                                include "modelling.alh"
+                                Boolean function constraint(host_model : Element, mapping : Element):
+                                    Integer tokens
+                                    Integer weight
+                                    tokens = read_attribute(host_model, mapping["10"], "tokens")
+                                    weight = read_attribute(host_model, mapping["11"], "weight")
+                                    log("NAC == tokens " + cast_v2s(tokens))
+                                    log("NAC == weight " + cast_v2s(weight))
+                                    if (tokens < weight):
+                                        log("TRUE")
+                                        return True!
+                                    else:
+                                        log("FALSE")
+                                        return False!
+                                $
+                        }
                         LHS {
                             Pre_Transition {
                                 label = "1"
-                                constraint = $
-                                    include "primitives.alh"
-                                    include "modelling.alh"
-                                    include "object_operations.alh"
-                                    Boolean function constraint(host_model : Element, name : String):
-                                        Element links
-                                        String link
-                                        String place
-                                        links = allIncomingAssociationInstances(host_model, name, "P2T")
-                                        while (read_nr_out(links) > 0):
-                                            link = set_pop(links)
-                                            place = readAssociationSource(host_model, link)
-                                            if (integer_lt(read_attribute(host_model, place, "tokens"), read_attribute(host_model, link, "weight"))):
-                                                return False!
-                                        return True!
-                                    $
                             }
                         }
                         RHS {
@@ -804,6 +818,7 @@ Element function constraint(model : Element, name : String):
                 "ramify", "PetriNets_Runtime_SCHEDULE", "PetriNets_Runtime",
                 ] + get_model_constructor(schedule_model) + [
                 "transform", "pn", "pn_simulate",
+                "transform", "pn", "pn_simulate",
                 "load", "pn",
                     "verify",
                     "read", "t1",
@@ -822,6 +837,7 @@ Element function constraint(model : Element, name : String):
             ramify + prompt + 
             prompt +
             transform + transform_result_true + prompt +
+            transform + transform_result_false + prompt +
             load + loaded +
             ["OK"] + prompt +
             read_node("t1", "Transition", [], [("executing", "Boolean", False)]) + prompt +

+ 1 - 0
interface/HUTN/includes/primitives.alh

@@ -98,6 +98,7 @@ Boolean function has_input()
 Element function list_pop(lst : Element, index : Integer)
 Element function set_copy(set : Element)
 String function set_to_string(set : Element)
+String function list_to_string(set : Element)
 String function dict_to_string(dict : Element)
 Element function set_overlap(sa : Element, sb : Element)
 Element function dict_copy(dict : Element)