aboutsummaryrefslogtreecommitdiffstats
path: root/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/PartialInterpretationGraph.xtend
blob: a2934eb9ee8df874db4066964c5e59a26e703a37 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph

import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric
import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDefinition
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialComplexTypeInterpretationImpl
import java.util.ArrayList
import java.util.List

class PartialInterpretationGraph extends Graph{
	val typeToExclude = "undefinedpart";
	val classSuffix = " class";
	
	/**
	 * Define a new PartialInterpretationGraph by parse every element from a PartialInterpretation
	 */
	new(PartialInterpretation partial, List<Metric> metrics, String name){		
		//the edge types are defined in terms of RelationDeclaration
		partial.problem.relations.filter(RelationDeclaration).forEach[
			//only need the name of the reference type (remove everything with and after "reference")
			var n = it.name.split(" ").get(0);
				this.statistic.addEdgeType(n);
		]
		// add all elements
		val typeInterpretations = getTypes(partial);
		for(type : typeInterpretations){
			//Only consider the most concrete class
			if(isConcreteType(type.interpretationOf)){
				var typeName = type.interpretationOf.name.replace(classSuffix, '');
				for(node : type.elements){
					if(!this.statistic.containsNode(node)){
						this.statistic.addNodeWithType(node, typeName);
					}else{
						// if the current type of the node is a super type of the type to check, 
						// substitute the current type with the new type
						var currentType = statistic.getTypesForNode(node).get(0);
						if(isSuperType(currentType, type.interpretationOf)){
							statistic.overwriteCurrentType(node, typeName);
						}
					}
				}
			}
		}
		
		for(relationInterpretation : partial.partialrelationinterpretation) {
			//only need the name of the reference type (remove everything with and after "reference")
			val type = relationInterpretation.interpretationOf.name.split(" ").get(0);
			for(edge : relationInterpretation.relationlinks.filter(BinaryElementRelationLink)){
				statistic.addEdge(edge.param1, edge.param2, type);
			}	
		}	
		
		this.name = name;
		this.metrics = metrics;	
	}
	
	/**
	 * recursively check if a type is the super type of another
	 */
	 def boolean isSuperType(String typeName, Type subtypeToCheck){
	 	var superTypes = subtypeToCheck.supertypes;
	 	if(superTypes.size == 0){
	 		return false;
	 	}else if(subtypeToCheck.supertypes.map[it.name.replace(classSuffix, '')].contains(typeName)){
	 		return true;
	 	}else{
	 		for(superType : superTypes){
	 			if(isSuperType(typeName, superType)){
	 				return true;
	 			}
	 		}
	 		return false;
	 	}
	 }
	 
	 /**
	  * Check if a Type object is the class that we want to consider
	  *	A type object is to be considered if it satisfy one of the following:
	  * 	1. if it is not abstract
	  * 	2. if it is abstract but has a subclass of type TypeDefinition (This means the generation is
	  * 	   started with nodes in this type) 
	  */
	def boolean isConcreteType(Type t){
		if(!t.isAbstract || t.subtypes.findFirst[it instanceof TypeDefinition] !== null){
			return true;
		}
		return false;
	}
	
	/**
	 * Set basic information for the output
	 */
	override setBasicInformation(ArrayList<ArrayList<String>> output){
		val metaInfo = new ArrayList<String>();
		metaInfo.add(META_MODEL_HEADER);
		metaInfo.add(this.metaModel);
		
		val edgeInfo = new ArrayList<String>();
		edgeInfo.add(NUM_EDGE_TYPE_HEADER);
		edgeInfo.add(this.statistic.allTypes.size()+"");
		
		val nodeInfo = new ArrayList<String>();
		nodeInfo.add(NUM_NODE_HEADER);
		nodeInfo.add(this.statistic.allNodes.size()+"");
		
		val stateInfo = new ArrayList<String>();
		stateInfo.add(STATE_ID_HEADER);
		stateInfo.add(this.name);
		
		output.add(metaInfo);
		output.add(edgeInfo);
		output.add(nodeInfo);
		output.add(stateInfo);
	}
	
	private def getTypes(PartialInterpretation partial){
		//only the complex type interpretations are the ones defined in meta model
		//do not care about undefined types as it will be included in the class type
		return partial.partialtypeinterpratation.filter(PartialComplexTypeInterpretationImpl)
												.filter[!it.interpretationOf.name.toLowerCase.contains(typeToExclude)];
	}
	
	override getStatistic() {
		throw new UnsupportedOperationException("TODO: auto-generated method stub")
	}
	
	override getName() {
		return name;
	}
	
}