include "primitives.alh"
include "object_operations.alh"
include "modelling.alh"
include "library.alh"

Boolean function main(model : Element):
	// Contains three types of models: model, metamodel, and type_mapping.
	// Each with the obvious meanings.

	// Note that this is only a placeholder that serves as a proof of concept.
	// Thus only the check for multiple inheritance is being done, which checks for attributes.
	// A full example is given in the Modelverse's internal conformance relation.

	// Find all instances of classes
	// First, find the class types
	Element classes
	classes = allInstances(model, "metamodel/Class")

	Element type_mapping
	Element instances
	String instance
	type_mapping = model["model"][set_pop(allInstances(model, "type_mapping/Root"))]

	Element new_type_mapping
	Element keys
	String key
	new_type_mapping = dict_create()
	keys = dict_keys(type_mapping)
	while (set_len(keys) > 0):
		key = set_pop(keys)
		dict_add(new_type_mapping, "model/" + key, "metamodel/" + cast_string(type_mapping[key]))

	type_mapping = new_type_mapping
	
	// Check if each attribute is there, and satisfies the constraints
	instances = dict_keys(type_mapping)
	while (set_len(instances) > 0):
		instance = set_pop(instances)
		if (read_type(model, type_mapping[instance]) == "metamodel/Class"):
			// Got an instance of a Class
			String type
			Element inherits_from
			type = cast_string(type_mapping[instance])

			Element outgoing_links
			String outgoing_link
			Element attrs

			outgoing_links = allOutgoingAssociationInstances(model, instance, "")
			attrs = dict_create()
			while (set_len(outgoing_links) > 0):
				outgoing_link = set_pop(outgoing_links)
				String name
				if (dict_in(type_mapping, outgoing_link)):
					name = read_attribute(model, type_mapping[outgoing_link], "name")
					dict_add(attrs, name, model["model"][readAssociationDestination(model, outgoing_link)])

			// Fetch a list of attributes that should be defined
			// TODO
			inherits_from = allAssociationDestinations(model, type, "metamodel/Inheritance")

			String superclass
			Element defining_attributes
			Element last_found

			last_found = dict_create()
			while (set_len(inherits_from) > 0):
				superclass = set_pop(inherits_from)
				defining_attributes = getInstantiatableAttributes(model, superclass, "metamodel/AttributeLink")
				dict_update(last_found, defining_attributes)

			Element keys
			String attr
			Element constraint
			String result
			keys = dict_keys(attrs)
			while (set_len(keys) > 0):
				attr = set_pop(keys)
				constraint = get_func_AL_model(import_node(read_attribute(model, last_found[attr], "constraint")))
				result = constraint(attrs[attr])

				if (result != "OK"):
					log("Conformance not OK: " + result)
					return False!

	log("Conformance OK")
	return True!
