aboutsummaryrefslogtreecommitdiffstats
path: root/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic
diff options
context:
space:
mode:
authorLibravatar 20001LastOrder <boqi.chen@mail.mcgill.ca>2019-08-08 16:45:45 -0400
committerLibravatar 20001LastOrder <boqi.chen@mail.mcgill.ca>2019-08-08 16:45:45 -0400
commitc33f0b9c4e112ee573d1b26d205a253cc0e487f8 (patch)
tree1ec2c4ab56b5bc0d0d56fa111bab0520c05604b4 /Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic
parentFurther development of realistic solver, create generation config for ecore m... (diff)
downloadVIATRA-Generator-c33f0b9c4e112ee573d1b26d205a253cc0e487f8.tar.gz
VIATRA-Generator-c33f0b9c4e112ee573d1b26d205a253cc0e487f8.tar.zst
VIATRA-Generator-c33f0b9c4e112ee573d1b26d205a253cc0e487f8.zip
Configurations for generation and new domain for generation ecore model
Diffstat (limited to 'Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic')
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Domain.xtend4
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend71
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetricDistance.xtend10
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Test.java31
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/KSDistance.xtend23
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/EMFGraph.xtend38
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend79
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/PartialInterpretationGraph.xtend60
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend9
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend59
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MultiplexParticipationCoefficientMetric.xtend6
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/validation/ConstraintCollection.xtend80
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/validation/ViolationCheck.xtend69
13 files changed, 420 insertions, 119 deletions
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Domain.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Domain.xtend
index 8351e96b..c8fd435b 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Domain.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Domain.xtend
@@ -1,5 +1,7 @@
1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app 1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app
2 2
3enum Domain{ 3enum Domain{
4 Yakinduum 4 Yakindumm,
5 Ecore,
6 Github
5} \ No newline at end of file 7} \ No newline at end of file
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend
index 062d69fa..ab187b3a 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend
@@ -3,13 +3,25 @@ package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app
3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.EMFGraph 3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.EMFGraph
4import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.CsvFileWriter 4import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.CsvFileWriter
5import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.GraphReader 5import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.GraphReader
6import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.validation.ViolationCheck
6import hu.bme.mit.inf.dslreasoner.domains.yakindu.sgraph.yakindumm.impl.YakindummPackageImpl 7import hu.bme.mit.inf.dslreasoner.domains.yakindu.sgraph.yakindumm.impl.YakindummPackageImpl
8import java.io.File
7import java.util.ArrayList 9import java.util.ArrayList
10import org.eclipse.emf.ecore.EPackage
8import org.eclipse.emf.ecore.EcorePackage 11import org.eclipse.emf.ecore.EcorePackage
12import org.eclipse.viatra.query.runtime.rete.matcher.ReteEngine
13import org.eclipse.emf.ecore.impl.EcorePackageImpl
14import org.eclipse.emf.ecore.EReference
9 15
10//import yakindumm2.impl.Yakindumm2PackageImpl 16//import yakindumm2.impl.Yakindumm2PackageImpl
11 17
12class Main { 18class Main {
19 var static Domain d = Domain.Ecore;
20 val static String suffix = '.ecore'
21 val static String OUTPUT_FOLDER = "Inputs/human/";
22 val static String INPUT_FOLDER = "outputs/human/";
23 val static int NUM_RUNS = 1;
24
13 static class RWInformation{ 25 static class RWInformation{
14 public var String inputFolder; 26 public var String inputFolder;
15 public var String outputFolder; 27 public var String outputFolder;
@@ -24,36 +36,32 @@ class Main {
24 36
25 def static void main(String[] args){ 37 def static void main(String[] args){
26 //init model 38 //init model
27 YakindummPackageImpl.eINSTANCE.eClass; 39 var EPackage metamodel;
28 EcorePackage.eINSTANCE.eClass;
29// Yakindumm2PackageImpl.eINSTANCE.eClass;
30 //val infos = initData();
31
32 println("Start Reading Models...");
33 var reader = new GraphReader(EcorePackage.eINSTANCE, ".xmi");
34// for(info : infos){
35// calculateAllModels(info.inputFolder, info.outputFolder,info.numRuns, reader);
36// }
37 40
38 //human input has different package declaration 41 //init viatra engine for the violation checker
39// reader = new GraphReader(Yakindumm2PackageImpl.eINSTANCE); 42 ReteEngine.getClass();
40 val human = new RWInformation("Inputs/viatra75/", "outputs/", 50);
41 calculateAllModels(human.inputFolder, human.outputFolder,human.numRuns, reader);
42 43
44 if(d == Domain.Yakindumm){
45 YakindummPackageImpl.eINSTANCE.eClass;
46 metamodel = YakindummPackageImpl.eINSTANCE;
47 }else if (d == Domain.Ecore){
48 EcorePackage.eINSTANCE.eClass;
49 metamodel = EcorePackageImpl.eINSTANCE;
50 }else if (d == Domain.Github){
51 //TODO: Initialize Github Package
52 }
43 53
54
55 println("Start Reading Models...");
56 var reader = new GraphReader(metamodel, suffix);
57
58 val models = new RWInformation(OUTPUT_FOLDER, INPUT_FOLDER, NUM_RUNS);
59 calculateAllModels(models.inputFolder, models.outputFolder,models.numRuns, reader);
44 println("finished"); 60 println("finished");
45 } 61 }
46 62
47 static def initData(){
48 val infos = new ArrayList<RWInformation>();
49 infos.add(new RWInformation("inputs/alloyInput/models/", "../plot/statistics/alloyOutput/", 20));
50 infos.add(new RWInformation("inputs/randomInput/models/", "../plot/statistics/randomOutput/", 20));
51 infos.add(new RWInformation("inputs/viatraInput30/", "../plot/statistics/viatraOutput30/", 20));
52 infos.add(new RWInformation("inputs/viatraInput100/", "../plot/statistics/viatraOutput100/", 10));
53 return infos;
54 }
55
56 static def calculateAllModels(String inputFolder, String outputFolder, int numRuns, GraphReader reader){ 63 static def calculateAllModels(String inputFolder, String outputFolder, int numRuns, GraphReader reader){
64 (new File(outputFolder)).mkdir();
57 for(var i = 1; i <= numRuns; i++){ 65 for(var i = 1; i <= numRuns; i++){
58 val models = new ArrayList<EMFGraph>(); 66 val models = new ArrayList<EMFGraph>();
59 models.addAll(reader.readModels(inputFolder + "run" + i)); 67 models.addAll(reader.readModels(inputFolder + "run" + i));
@@ -67,8 +75,21 @@ class Main {
67 } 75 }
68 76
69 static def calculateAndOutputMetrics(EMFGraph model, String metaModel, String fileName){ 77 static def calculateAndOutputMetrics(EMFGraph model, String metaModel, String fileName){
70 //println("evaluating for " + model.name); 78 //println("evaluating for " + model.name);
71 model.metaModel = metaModel; 79 model.metaModel = metaModel;
72 CsvFileWriter.write(model.evaluateAllMetrics(), fileName); 80
81 //remove eGenericType for Ecore domain
82 if(d == Domain.Ecore){
83 var refsToRemove = EcorePackageImpl.eINSTANCE.eAllContents.filter(EReference).filter[
84 it.name.equals('eGenericType') || it.name.equals('eGenericSuperTypes') || it.name.equals('eFactoryInstance')||
85 it.name.equals('eGenericExceptions') || it.name.equals('references') || it.name.equals('contents');
86 ];
87 refsToRemove.forEach[model.removeReference(it)];
88 }
89
90 var outputs = model.evaluateAllMetrics();
91 var violationsOutput = newArrayList('violations', ViolationCheck.calculateViolationCounts(model.root, d)+'');
92 outputs.add(violationsOutput);
93 CsvFileWriter.write(outputs, fileName);
73 } 94 }
74} \ No newline at end of file 95} \ No newline at end of file
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetricDistance.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetricDistance.xtend
index 66dcdff6..b2288f52 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetricDistance.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetricDistance.xtend
@@ -20,6 +20,7 @@ import java.util.List
20import java.util.Map 20import java.util.Map
21import org.apache.commons.math3.stat.regression.OLSMultipleLinearRegression 21import org.apache.commons.math3.stat.regression.OLSMultipleLinearRegression
22import org.eclipse.xtend.lib.annotations.Accessors 22import org.eclipse.xtend.lib.annotations.Accessors
23import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.EdgeTypeMetric
23 24
24class PartialInterpretationMetricDistance { 25class PartialInterpretationMetricDistance {
25 26
@@ -34,8 +35,8 @@ class PartialInterpretationMetricDistance {
34 var LinearModel linearModel; 35 var LinearModel linearModel;
35 36
36 37
37 new(){ 38 new(Domain d){
38 var metrics = RepMetricsReader.read(Domain.Yakinduum); 39 var metrics = RepMetricsReader.read(d);
39 this.g = metrics; 40 this.g = metrics;
40 ks = new KSDistance(g); 41 ks = new KSDistance(g);
41 js = new JSDistance(g); 42 js = new JSDistance(g);
@@ -53,6 +54,7 @@ class PartialInterpretationMetricDistance {
53 metrics.add(new NodeActivityMetric()); 54 metrics.add(new NodeActivityMetric());
54 metrics.add(new MultiplexParticipationCoefficientMetric()); 55 metrics.add(new MultiplexParticipationCoefficientMetric());
55 metrics.add(new NodeTypeMetric()); 56 metrics.add(new NodeTypeMetric());
57 metrics.add(new EdgeTypeMetric());
56 val metricCalculator = new PartialInterpretationGraph(partial, metrics, null); 58 val metricCalculator = new PartialInterpretationGraph(partial, metrics, null);
57 var metricSamples = metricCalculator.evaluateAllMetricsToSamples(); 59 var metricSamples = metricCalculator.evaluateAllMetricsToSamples();
58 60
@@ -63,6 +65,7 @@ class PartialInterpretationMetricDistance {
63 //var typedOutDegree = ks.typedOutDegreeDistance(metricSamples.typedOutDegreeSamples); 65 //var typedOutDegree = ks.typedOutDegreeDistance(metricSamples.typedOutDegreeSamples);
64 var distance = new MetricDistanceGroup(mpc, na, outDegree, nodeType); 66 var distance = new MetricDistanceGroup(mpc, na, outDegree, nodeType);
65 distance.nodeTypeInfo = metricSamples.nodeTypeSamples; 67 distance.nodeTypeInfo = metricSamples.nodeTypeSamples;
68 distance.edgeTypeDistance = ks.edgeTypeDistance(metricSamples.edgeTypeSamples);
66 return distance; 69 return distance;
67 } 70 }
68 71
@@ -177,7 +180,8 @@ class MetricDistanceGroup{
177 var double outDegreeDistance; 180 var double outDegreeDistance;
178 var double nodeTypeDistance; 181 var double nodeTypeDistance;
179 protected var HashMap<String, Double> nodeTypeInfo; 182 protected var HashMap<String, Double> nodeTypeInfo;
180 183 public var double edgeTypeDistance;
184
181 new(double mpcDistance, double naDistance, double outDegreeDistance, double nodeTypeDistance){ 185 new(double mpcDistance, double naDistance, double outDegreeDistance, double nodeTypeDistance){
182 this.mpcDistance = mpcDistance; 186 this.mpcDistance = mpcDistance;
183 this.naDistance = naDistance; 187 this.naDistance = naDistance;
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Test.java b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Test.java
deleted file mode 100644
index f06b377f..00000000
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Test.java
+++ /dev/null
@@ -1,31 +0,0 @@
1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import weka.core.matrix.LinearRegression;
7import weka.core.matrix.Matrix;
8
9public class Test {
10 public static void main(String[] args) {
11 linearRegressionTest();
12 }
13
14 public static void linearRegressionTest() {
15 double[][] x = {{1,1,2,3}, {1,2,3,4}, {1,3,5,7}, {1,1,5,7}};
16 double[] y = {10, 13, 19, 17};
17 double[] valueToPredict = {1,1,1,1};
18 Matrix m = new Matrix(x);
19 Matrix n = new Matrix(y, y.length);
20
21 LinearRegression regression = new LinearRegression(m, n, 0);
22 double[] coef = regression.getCoefficients();
23
24 //predict
25 double a = 0;
26 for(int i = 0; i < coef.length; i++) {
27 a += coef[i] * valueToPredict[i];
28 }
29 System.out.println(a);
30 }
31}
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/KSDistance.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/KSDistance.xtend
index 08d8704a..c486a328 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/KSDistance.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/KSDistance.xtend
@@ -70,13 +70,30 @@ class KSDistance extends CostDistance {
70 instanceDist.add(samples.getOrDefault(key, 0.0)); 70 instanceDist.add(samples.getOrDefault(key, 0.0));
71 } 71 }
72 72
73 return ks_distance_two_dist(sourceDist, instanceDist);
74 }
75
76 def edgeTypeDistance(HashMap<String, Double> samples){
77 var typesDistMap = g.edgeTypeSamples;
78 var sourceDist = newArrayList();
79 var instanceDist = newArrayList();
80
81 for(key : typesDistMap.keySet()){
82 sourceDist.add(typesDistMap.get(key));
83 instanceDist.add(samples.getOrDefault(key, 0.0));
84 }
85
86 return ks_distance_two_dist(sourceDist, instanceDist);
87 }
88
89 def double ks_distance_two_dist(List<Double> dist1, List<Double> dist2){
73 // Since we already know the pdf, we compute the ks-test manully 90 // Since we already know the pdf, we compute the ks-test manully
74 var ksStatistics = 0.0; 91 var ksStatistics = 0.0;
75 var sum1 = 0.0; 92 var sum1 = 0.0;
76 var sum2 = 0.0; 93 var sum2 = 0.0;
77 for(var i = 0; i < sourceDist.size(); i++){ 94 for(var i = 0; i < dist1.size(); i++){
78 sum1 += sourceDist.get(i); 95 sum1 += dist1.get(i);
79 sum2 += instanceDist.get(i); 96 sum2 += dist2.get(i);
80 97
81 ksStatistics = Math.max(ksStatistics, Math.abs(sum1 - sum2)); 98 ksStatistics = Math.max(ksStatistics, Math.abs(sum1 - sum2));
82 } 99 }
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/EMFGraph.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/EMFGraph.xtend
index 959006f4..8fa29fe6 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/EMFGraph.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/EMFGraph.xtend
@@ -7,10 +7,15 @@ import java.util.List
7import org.eclipse.emf.common.util.EList 7import org.eclipse.emf.common.util.EList
8import org.eclipse.emf.ecore.EObject 8import org.eclipse.emf.ecore.EObject
9import org.eclipse.emf.ecore.EReference 9import org.eclipse.emf.ecore.EReference
10import org.eclipse.xtend.lib.annotations.Accessors
10 11
11class EMFGraph extends Graph{ 12class EMFGraph extends Graph{
13 @Accessors(PUBLIC_GETTER)
14 var EObject root;
15
12 def void init (EObject root, List<Metric> metrics, String name, List<EReference> referenceTypes){ 16 def void init (EObject root, List<Metric> metrics, String name, List<EReference> referenceTypes){
13 val otherContents = root.eAllContents.toList(); 17 val otherContents = root.eAllContents.toList();
18 this.root = root;
14 otherContents.add(root); 19 otherContents.add(root);
15 init(otherContents, metrics, name, referenceTypes); 20 init(otherContents, metrics, name, referenceTypes);
16 } 21 }
@@ -30,17 +35,11 @@ class EMFGraph extends Graph{
30 statistic.addNodeWithAllTypes(it, types); 35 statistic.addNodeWithAllTypes(it, types);
31 ] 36 ]
32 37
33 referenceTypes.forEach[it| 38 referenceTypes.forEach[it|
34 var typeToAdd = it; 39 // Only consider the edges that are not derived to preserve the statistical property
35 40 if(!it.derived){
36 // TODO: Here is to only consider one part of opposite edges 41 statistic.addEdgeType(it.name);
37// if(it.upperBound != -1 && it.EOpposite !== null && 42 }
38// (it.EOpposite.upperBound == -1 || it.EOpposite.upperBound > it.upperBound
39// )){
40// typeToAdd = it.EOpposite;
41// }
42//
43 statistic.addEdgeType(typeToAdd.name);
44 ]; 43 ];
45 44
46 objects.forEach[source| 45 objects.forEach[source|
@@ -62,6 +61,12 @@ class EMFGraph extends Graph{
62 this.name = name; 61 this.name = name;
63 } 62 }
64 63
64 def void removeReference(EReference r){
65 if (statistic.containsEdgeType(r.name)){
66 statistic.removeReference(r.name, r.containment);
67 }
68 }
69
65 /** 70 /**
66 * Set basic information for the output 71 * Set basic information for the output
67 */ 72 */
@@ -94,15 +99,8 @@ class EMFGraph extends Graph{
94 } 99 }
95 100
96 def addEdge(EObject source, EObject target, EReference r){ 101 def addEdge(EObject source, EObject target, EReference r){
97 // TODO: Here is to only consider one part of opposite edges 102 //Only add the edge if the reference is not derived to preserve the statistical property
98 //check for the opposite reference and do not add if its opposite will be added 103 if(target !== null && r !== null && !r.derived){
99// if(r.upperBound != -1 && r.EOpposite !== null &&
100// (r.EOpposite.upperBound == -1 || r.EOpposite.upperBound > r.upperBound
101// )){
102// return;
103// }
104
105 if(target !== null && r !== null){
106 statistic.addEdge(source, target, r.name); 104 statistic.addEdge(source, target, r.name);
107 } 105 }
108 } 106 }
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend
index 84071176..af05a1cd 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend
@@ -12,7 +12,7 @@ import org.eclipse.emf.ecore.EReference
12 12
13class GraphStatistic { 13class GraphStatistic {
14 val incomingEdges = new HashMap<String, Multimap<EObject, EObject>>; 14 val incomingEdges = new HashMap<String, Multimap<EObject, EObject>>;
15 val outcomingEdges = new HashMap<String, Multimap<EObject, EObject>>; 15 val outgoingEdges = new HashMap<String, Multimap<EObject, EObject>>;
16 16
17 val edgeTypes = new HashSet<String>(); 17 val edgeTypes = new HashSet<String>();
18 val nodeToType = new HashMap<EObject, Set<String>>(); 18 val nodeToType = new HashMap<EObject, Set<String>>();
@@ -22,15 +22,13 @@ class GraphStatistic {
22 * @param type: type to add 22 * @param type: type to add
23 */ 23 */
24 def void addEdgeType(String type){ 24 def void addEdgeType(String type){
25
26
27 if(edgeTypes.contains(type)){ 25 if(edgeTypes.contains(type)){
28 return; 26 return;
29 } 27 }
30 28
31 edgeTypes.add(type); 29 edgeTypes.add(type);
32 incomingEdges.put(type, ArrayListMultimap.create()); 30 incomingEdges.put(type, ArrayListMultimap.create());
33 outcomingEdges.put(type, ArrayListMultimap.create()); 31 outgoingEdges.put(type, ArrayListMultimap.create());
34 } 32 }
35 33
36 /** 34 /**
@@ -43,6 +41,23 @@ class GraphStatistic {
43 nodeToType.put(n, types); 41 nodeToType.put(n, types);
44 } 42 }
45 43
44 def boolean containsNode(EObject o){
45 return nodeToType.containsKey(o);
46 }
47
48 def Set<String> getTypesForNode(EObject o){
49 return nodeToType.getOrDefault(o, new HashSet<String>());
50 }
51
52 def void overwriteCurrentType(EObject o, String type){
53 var typeSet = nodeToType.getOrDefault(o, new HashSet<String>());
54
55 // clear current types
56 typeSet.clear();
57 typeSet.add(type);
58 nodeToType.put(o, typeSet);
59 }
60
46 /** 61 /**
47 * Add a node to the graph with all types in its type hierarchy 62 * Add a node to the graph with all types in its type hierarchy
48 */ 63 */
@@ -57,18 +72,66 @@ class GraphStatistic {
57 * @param type: type of the reference 72 * @param type: type of the reference
58 */ 73 */
59 def void addEdge(EObject source, EObject target, String type){ 74 def void addEdge(EObject source, EObject target, String type){
60 outcomingEdges.get(type).put(source, target); 75 outgoingEdges.get(type).put(source, target);
61 incomingEdges.get(type).put(target, source); 76 incomingEdges.get(type).put(target, source);
62 } 77 }
63 78
64 /** 79 /**
80 * check if this graph contains a specific edge type
81 */
82 def boolean containsEdgeType(String typeName){
83 if(outgoingEdges.containsKey(typeName) && incomingEdges.containsKey(typeName)){
84 return true;
85 }
86 return false;
87 }
88
89 /**
90 * remove references from the statistics, potentially remove the nodes associated with it
91 * @Param name: name of the reference
92 * @Param isContainment: if true then the corresponding nodes on the incoming side will also be removed
93 */
94 def removeReference(String name, boolean isContainment){
95 if(!edgeTypes.contains(name)){
96 return;
97 }
98
99 edgeTypes.remove(name);
100 var incomingSet = incomingEdges.remove(name);
101 outgoingEdges.remove(name);
102
103 // if the reference is not a containment, then removing the reference is enough
104 if(!isContainment){
105 return;
106 }
107
108 // else remove all corresponding nodes
109 val nodesToRemove = incomingSet.keySet();
110
111 //remove nodes from node sets
112 nodesToRemove.forEach[nodeToType.remove(it)];
113
114 val removeForMultimap = [Multimap<EObject, EObject> refMap|
115 nodesToRemove.forEach[refMap.removeAll(it)];
116 var values = refMap.values()
117 //remove the values from the list is equavalent to remove it in the multimap
118 values.removeAll(nodesToRemove);
119 return;
120 ];
121
122 //remove nodes from all other references on incomingEdges
123 incomingEdges.values.forEach(removeForMultimap);
124 outgoingEdges.values.forEach(removeForMultimap);
125 }
126
127 /**
65 * calculate the out degree for an object 128 * calculate the out degree for an object
66 */ 129 */
67 def int outDegree(EObject o){ 130 def int outDegree(EObject o){
68 var count = 0; 131 var count = 0;
69 132
70 for (String type : edgeTypes){ 133 for (String type : edgeTypes){
71 count += outcomingEdges.get(type).get(o).size(); 134 count += outgoingEdges.get(type).get(o).size();
72 } 135 }
73 return count; 136 return count;
74 } 137 }
@@ -89,7 +152,7 @@ class GraphStatistic {
89 * calculate the dimentional degree of a node 152 * calculate the dimentional degree of a node
90 */ 153 */
91 def int dimentionalDegree(EObject o, String type){ 154 def int dimentionalDegree(EObject o, String type){
92 return incomingEdges.get(type).get(o).size() + outcomingEdges.get(type).get(o).size(); 155 return incomingEdges.get(type).get(o).size() + outgoingEdges.get(type).get(o).size();
93 } 156 }
94 157
95 /** 158 /**
@@ -120,7 +183,7 @@ class GraphStatistic {
120 } 183 }
121 184
122 def HashMap<String, Multimap<EObject, EObject>> getOutgoingEdges(){ 185 def HashMap<String, Multimap<EObject, EObject>> getOutgoingEdges(){
123 return outcomingEdges; 186 return outgoingEdges;
124 } 187 }
125 188
126} 189}
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/PartialInterpretationGraph.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/PartialInterpretationGraph.xtend
index ef68f366..a2934eb9 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/PartialInterpretationGraph.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/PartialInterpretationGraph.xtend
@@ -2,6 +2,8 @@ package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph
2 2
3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric 3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration 4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDefinition
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink 7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialComplexTypeInterpretationImpl 9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialComplexTypeInterpretationImpl
@@ -20,19 +22,25 @@ class PartialInterpretationGraph extends Graph{
20 partial.problem.relations.filter(RelationDeclaration).forEach[ 22 partial.problem.relations.filter(RelationDeclaration).forEach[
21 //only need the name of the reference type (remove everything with and after "reference") 23 //only need the name of the reference type (remove everything with and after "reference")
22 var n = it.name.split(" ").get(0); 24 var n = it.name.split(" ").get(0);
23 // TODO: Here is to only consider one part of opposite edges
24 if(!n.equals('target') && !n.equals('source') /* && !n.equals('incomingTransitions')*/){
25 this.statistic.addEdgeType(n); 25 this.statistic.addEdgeType(n);
26 }
27 ] 26 ]
28 // add all elements 27 // add all elements
29 val typeInterpretations = getTypes(partial); 28 val typeInterpretations = getTypes(partial);
30 for(type : typeInterpretations){ 29 for(type : typeInterpretations){
31 //Only consider the most concrete class 30 //Only consider the most concrete class
32 if(type.interpretationOf.subtypes.size == 0){ 31 if(isConcreteType(type.interpretationOf)){
33 var typeName = type.interpretationOf.name.replace(classSuffix, ''); 32 var typeName = type.interpretationOf.name.replace(classSuffix, '');
34 for(node : type.elements){ 33 for(node : type.elements){
35 this.statistic.addNodeWithType(node, typeName); 34 if(!this.statistic.containsNode(node)){
35 this.statistic.addNodeWithType(node, typeName);
36 }else{
37 // if the current type of the node is a super type of the type to check,
38 // substitute the current type with the new type
39 var currentType = statistic.getTypesForNode(node).get(0);
40 if(isSuperType(currentType, type.interpretationOf)){
41 statistic.overwriteCurrentType(node, typeName);
42 }
43 }
36 } 44 }
37 } 45 }
38 } 46 }
@@ -40,12 +48,9 @@ class PartialInterpretationGraph extends Graph{
40 for(relationInterpretation : partial.partialrelationinterpretation) { 48 for(relationInterpretation : partial.partialrelationinterpretation) {
41 //only need the name of the reference type (remove everything with and after "reference") 49 //only need the name of the reference type (remove everything with and after "reference")
42 val type = relationInterpretation.interpretationOf.name.split(" ").get(0); 50 val type = relationInterpretation.interpretationOf.name.split(" ").get(0);
43 // TODO: Here is to only consider one part of opposite edges 51 for(edge : relationInterpretation.relationlinks.filter(BinaryElementRelationLink)){
44 if(!type.equals('target') && !type.equals('source') /*&& !type.equals('incomingTransitions')*/){ 52 statistic.addEdge(edge.param1, edge.param2, type);
45 for(edge : relationInterpretation.relationlinks.filter(BinaryElementRelationLink)){ 53 }
46 statistic.addEdge(edge.param1, edge.param2, type);
47 }
48 }
49 } 54 }
50 55
51 this.name = name; 56 this.name = name;
@@ -53,6 +58,39 @@ class PartialInterpretationGraph extends Graph{
53 } 58 }
54 59
55 /** 60 /**
61 * recursively check if a type is the super type of another
62 */
63 def boolean isSuperType(String typeName, Type subtypeToCheck){
64 var superTypes = subtypeToCheck.supertypes;
65 if(superTypes.size == 0){
66 return false;
67 }else if(subtypeToCheck.supertypes.map[it.name.replace(classSuffix, '')].contains(typeName)){
68 return true;
69 }else{
70 for(superType : superTypes){
71 if(isSuperType(typeName, superType)){
72 return true;
73 }
74 }
75 return false;
76 }
77 }
78
79 /**
80 * Check if a Type object is the class that we want to consider
81 * A type object is to be considered if it satisfy one of the following:
82 * 1. if it is not abstract
83 * 2. if it is abstract but has a subclass of type TypeDefinition (This means the generation is
84 * started with nodes in this type)
85 */
86 def boolean isConcreteType(Type t){
87 if(!t.isAbstract || t.subtypes.findFirst[it instanceof TypeDefinition] !== null){
88 return true;
89 }
90 return false;
91 }
92
93 /**
56 * Set basic information for the output 94 * Set basic information for the output
57 */ 95 */
58 override setBasicInformation(ArrayList<ArrayList<String>> output){ 96 override setBasicInformation(ArrayList<ArrayList<String>> output){
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend
index 491501b0..858113e9 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend
@@ -20,6 +20,8 @@ import org.eclipse.emf.ecore.resource.Resource
20import org.eclipse.emf.ecore.resource.ResourceSet 20import org.eclipse.emf.ecore.resource.ResourceSet
21import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl 21import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
22import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl 22import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl
23import org.eclipse.emf.ecore.EGenericType
24import org.eclipse.emf.ecore.EStructuralFeature
23 25
24class GraphReader{ 26class GraphReader{
25 val ResourceSet resSet = new ResourceSetImpl(); 27 val ResourceSet resSet = new ResourceSetImpl();
@@ -53,9 +55,11 @@ class GraphReader{
53 metrics.add(new TypedOutDegree()); 55 metrics.add(new TypedOutDegree());
54 metrics.add(new NodeTypeMetric()); 56 metrics.add(new NodeTypeMetric());
55 metrics.add(new EdgeTypeMetric()); 57 metrics.add(new EdgeTypeMetric());
56 58 var count = 1
57 //check all files in the directory with suffix 59 //check all files in the directory with suffix
58 for(String name : dir.list.filter[it| it.endsWith(suffix)]){ 60 for(String name : dir.list.filter[it| it.endsWith(suffix)]){
61 println(name)
62 println(count)
59 val file = new File(name); 63 val file = new File(name);
60 val roots = readModel(EObject, path, file.name); 64 val roots = readModel(EObject, path, file.name);
61 //add a list of metrics 65 //add a list of metrics
@@ -63,7 +67,8 @@ class GraphReader{
63 for(root : roots){ 67 for(root : roots){
64 g.init(root, metrics, name.replaceFirst(suffix, ""), referenceTypes); 68 g.init(root, metrics, name.replaceFirst(suffix, ""), referenceTypes);
65 } 69 }
66 70
71 count ++;
67 graphs.add(g); 72 graphs.add(g);
68 } 73 }
69 74
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend
index 6af0b6c7..06e88efc 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend
@@ -4,34 +4,62 @@ import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain
4import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup 4import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup
5import hu.bme.mit.inf.dslreasoner.domains.yakindu.sgraph.yakindumm.impl.YakindummPackageImpl 5import hu.bme.mit.inf.dslreasoner.domains.yakindu.sgraph.yakindumm.impl.YakindummPackageImpl
6import java.util.HashMap 6import java.util.HashMap
7import org.eclipse.emf.ecore.EReference
8import org.eclipse.emf.ecore.impl.EcorePackageImpl
7 9
8/** 10/**
9 * Read the sample of the distribution of a metric provided the csv file of the metric 11 * Read the sample of the distribution of a metric provided the csv file of the metric
10 */ 12 */
11class RepMetricsReader { 13class RepMetricsReader {
14 static var Domain domain;
12 static def read(Domain d){ 15 static def read(Domain d){
13 var reader = new GraphReader(YakindummPackageImpl.eINSTANCE, '.xmi'); 16 var GraphReader reader;
17 if(d == Domain.Yakindumm){
18 reader = new GraphReader(YakindummPackageImpl.eINSTANCE, '.xmi');
19 }else if (d == Domain.Ecore){
20 reader = new GraphReader(EcorePackageImpl.eINSTANCE, '.ecore');
21 }else if (d == Domain.Github){
22 // Initialize the reader with github package
23 }
14 24
25 domain = d;
15 26
16 var domainRepPath = DataName.REP_PATH + d.name + '/'; 27 var domainRepPath = DataName.REP_PATH + d.name + '/';
17 var rep = new MetricSampleGroup() 28 var rep = new MetricSampleGroup()
18 var out_d = readMetrics(reader, domainRepPath + DataName.OUT_D_REP); 29 var out_d = readMetrics(reader, domainRepPath + DataName.OUT_D_REP);
19 rep.mpcSamples = readMetrics(reader, domainRepPath + DataName.MPC_REP).mpcSamples; 30 var mpc = readMetrics(reader, domainRepPath + DataName.MPC_REP);
31 rep.mpcSamples = mpc.mpcSamples;
20 rep.outDegreeSamples = out_d.outDegreeSamples; 32 rep.outDegreeSamples = out_d.outDegreeSamples;
21 rep.naSamples = readMetrics(reader, domainRepPath + DataName.NA_REP).naSamples; 33 rep.naSamples = readMetrics(reader, domainRepPath + DataName.NA_REP).naSamples;
22 rep.typedOutDegreeSamples = out_d.typedOutDegreeSamples; 34 rep.typedOutDegreeSamples = out_d.typedOutDegreeSamples;
23 rep.edgeTypeSamples = out_d.edgeTypeSamples; 35 rep.edgeTypeSamples = mpc.edgeTypeSamples;
24 36
25 //TODO: Parameterize the prior node distribution 37 //TODO: Parameterize the prior node distribution
26 var nodeTypeSamples = new HashMap<String, Double>(); 38 var nodeTypeSamples = new HashMap<String, Double>();
27 nodeTypeSamples.put('Entry', 0.04257802080554814); 39 if(d == Domain.Yakindumm){
28 nodeTypeSamples.put('Choice', 0.1267671379034409); 40 nodeTypeSamples.put('Entry', 0.04257802080554814);
29 nodeTypeSamples.put('State', 0.1596092291277674); 41 nodeTypeSamples.put('Choice', 0.1267671379034409);
30 nodeTypeSamples.put('Transition', 0.6138636969858629); 42 nodeTypeSamples.put('State', 0.1596092291277674);
31 nodeTypeSamples.put('Statechart', 0.010136036276340358); 43 nodeTypeSamples.put('Transition', 0.6138636969858629);
32 nodeTypeSamples.put('Region', 0.04467858095492131); 44 nodeTypeSamples.put('Statechart', 0.010136036276340358);
33 nodeTypeSamples.put('Exit', 0.0018338223526273673); 45 nodeTypeSamples.put('Region', 0.04467858095492131);
34 nodeTypeSamples.put('FinalState', 0.0005334755934915977); 46 nodeTypeSamples.put('Exit', 0.0018338223526273673);
47 nodeTypeSamples.put('FinalState', 0.0005334755934915977);
48 }else if(d ==Domain.Ecore){
49 nodeTypeSamples.put('EAttribute', 0.23539778449144008);
50 nodeTypeSamples.put('EClass', 0.33081570996978854);
51 nodeTypeSamples.put('EReference', 0.30996978851963747);
52 nodeTypeSamples.put('EPackage', 0.012789526686807653);
53 nodeTypeSamples.put('EAnnotation', 0.002517623363544813);
54 nodeTypeSamples.put('EEnumLiteral', 0.07275931520644502);
55 nodeTypeSamples.put('EEnum', 0.013645518630412891);
56 nodeTypeSamples.put('EDataType', 0.004028197381671702);
57 nodeTypeSamples.put('EParameter', 0.005941591137965764);
58 nodeTypeSamples.put('EGenericType', 0.002014098690835851);
59 nodeTypeSamples.put('EOperation', 0.009415911379657605);
60 nodeTypeSamples.put('ETypeParameter', 0.0007049345417925478);
61 }
62
35 63
36 64
37 rep.nodeTypeSamples = nodeTypeSamples; 65 rep.nodeTypeSamples = nodeTypeSamples;
@@ -42,7 +70,14 @@ class RepMetricsReader {
42 * Read representative model 70 * Read representative model
43 */ 71 */
44 private static def readMetrics(GraphReader r, String path){ 72 private static def readMetrics(GraphReader r, String path){
45 var model = r.readModels(path).head; 73 val model = r.readModels(path).head;
74 if(domain == Domain.Ecore){
75 var refsToRemove = EcorePackageImpl.eINSTANCE.eAllContents.filter(EReference).filter[
76 it.name.equals('eGenericType') || it.name.equals('eGenericSuperTypes') || it.name.equals('eFactoryInstance') ||
77 it.name.equals('eGenericExceptions') || it.name.equals('references') || it.name.equals('contents');
78 ];
79 refsToRemove.forEach[model.removeReference(it)];
80 }
46 return model.evaluateAllMetricsToSamples(); 81 return model.evaluateAllMetricsToSamples();
47 } 82 }
48 83
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MultiplexParticipationCoefficientMetric.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MultiplexParticipationCoefficientMetric.xtend
index d9c88bb4..eafa49b2 100644
--- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MultiplexParticipationCoefficientMetric.xtend
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MultiplexParticipationCoefficientMetric.xtend
@@ -9,11 +9,11 @@ import org.eclipse.emf.ecore.EObject
9class MultiplexParticipationCoefficientMetric extends Metric { 9class MultiplexParticipationCoefficientMetric extends Metric {
10 public static val countName = "MPCCount"; 10 public static val countName = "MPCCount";
11 public static val valueName = "MPCValue"; 11 public static val valueName = "MPCValue";
12 12 val formatter = new DecimalFormat("#0.00000");
13 13
14 override evaluate(GraphStatistic g) { 14 override evaluate(GraphStatistic g) {
15 //because the precision issue of double, we translate double values into String to be the key 15 //because the precision issue of double, we translate double values into String to be the key
16 val formatter = new DecimalFormat("#0.00000"); 16
17 17
18 //get number of different types 18 //get number of different types
19 val typeCounts = g.allTypes.size; 19 val typeCounts = g.allTypes.size;
@@ -75,6 +75,6 @@ class MultiplexParticipationCoefficientMetric extends Metric {
75 coef = 0; 75 coef = 0;
76 } 76 }
77 77
78 return coef; 78 return Double.parseDouble(formatter.format(coef));
79 } 79 }
80} \ No newline at end of file 80} \ No newline at end of file
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/validation/ConstraintCollection.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/validation/ConstraintCollection.xtend
new file mode 100644
index 00000000..685c5836
--- /dev/null
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/validation/ConstraintCollection.xtend
@@ -0,0 +1,80 @@
1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.validation
2
3import java.util.ArrayList
4import java.util.HashMap
5import java.util.List
6import java.util.Map
7import org.eclipse.emf.common.notify.Notifier
8import org.eclipse.emf.common.util.URI
9import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
10import org.eclipse.viatra.addon.validation.core.api.IConstraintSpecification
11import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
12import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedPatternGroup
13import org.eclipse.viatra.query.runtime.emf.EMFScope
14
15class ConstraintCollection{
16 val constraints = new ArrayList<IConstraintSpecification>();
17 var BaseGeneratedPatternGroup patterns;
18 var List<Notifier> resources = new ArrayList<Notifier>();
19
20
21 new(List<IConstraintSpecification> constraints, List<String> uris, BaseGeneratedPatternGroup patterns){
22 this.constraints.addAll(constraints);
23 this.patterns = patterns;
24 setURIs(uris);
25 }
26
27 new(List<IConstraintSpecification> constraints, BaseGeneratedPatternGroup patterns){
28 this.constraints.addAll(constraints);
29 this.patterns = patterns;
30 }
31
32 def addModel(Notifier n ){
33 resources.add(n);
34 }
35
36 def setURIs(List<String> uris){
37 val resSet = new ResourceSetImpl();
38
39 for(uri : uris){
40 var resource = resSet.getResource(URI.createURI(uri), true);
41 resources.add(resource);
42 }
43
44 println('reading model finished')
45 }
46
47 def List<Integer> calculateViolations(){
48 var results = new ArrayList<Integer>();
49
50 for(resource : resources){
51 val engine = initEngine(resource);
52 var matches = constraints.stream.mapToInt([ele| ele.querySpecification.getMatcher(engine).countMatches]).sum();
53 results.add(matches);
54 }
55
56 return results;
57 }
58
59 def ArrayList<Map<String, Integer>> calculateViolationMaps(){
60 val result = new ArrayList<Map<String, Integer>>()
61
62 for(resource : resources){
63 val map = new HashMap<String, Integer>();
64 val engine = initEngine(resource);
65 constraints.forEach[
66 var count = it.querySpecification.getMatcher(engine).countMatches;
67 map.put(it.querySpecification.simpleName, count);
68 ];
69 result.add(map);
70 }
71 return result;
72 }
73
74 private def initEngine(Notifier r){
75 var engine = ViatraQueryEngine.on(new EMFScope(r));
76 //init patterns with the new engine
77 patterns.prepare(engine);
78 return engine;
79 }
80}
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/validation/ViolationCheck.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/validation/ViolationCheck.xtend
new file mode 100644
index 00000000..72239e22
--- /dev/null
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/validation/ViolationCheck.xtend
@@ -0,0 +1,69 @@
1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.validation
2
3import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain
4import com.google.common.reflect.ClassPath
5import hu.bme.mit.inf.dslreasoner.partialsnapshot_mavo.yakindu.Patterns
6import java.util.ArrayList
7import org.eclipse.emf.ecore.EObject
8import org.eclipse.viatra.addon.validation.core.api.IConstraintSpecification
9
10class ViolationCheck {
11 /**
12 * Return the total number of violations
13 */
14 def static int calculateViolationCounts(EObject root, Domain d){
15 var packageName = '';
16 if(d == Domain.Yakindumm){
17 packageName = 'constraints.yakindumm';
18 }else if (d == Domain.Ecore){
19 //TODO: put constraints package names for ecore and github models
20 return -1;
21 }else if (d == Domain.Github){
22 return -1;
23 }
24
25
26 var constriants = loadConstraints(packageName);
27 var collections = new ConstraintCollection(constriants, Patterns.instance);
28 collections.addModel(root);
29 var results = collections.calculateViolations();
30 if(results.size > 0){
31 return results.get(0);
32 }else{
33 throw new IllegalArgumentException("Calculate Violation Failed");
34 }
35 }
36
37 /**
38 * return a map contain the count for each type of violation
39 */
40 def static violationMaps(EObject root){
41 var constriants = loadConstraints('hu.bme.mit.inf.dslreasoner.partialsnapshot_mavo.yakindu');
42 var collections = new ConstraintCollection(constriants, Patterns.instance);
43 collections.addModel(root);
44 var results = collections.calculateViolationMaps();
45 if(results.size > 0){
46 return results.get(0);
47 }else{
48 throw new IllegalArgumentException("Calculate Violation Failed");
49 }
50 }
51
52 def static loadConstraints(String packageName){
53 val constraints = new ArrayList<IConstraintSpecification>();
54
55 val classPath = ClassPath.from(ClassLoader.systemClassLoader);
56 val classInfos = classPath.getTopLevelClasses(packageName);
57
58 for(info : classInfos){
59 if(info.load.interfaces.contains(IConstraintSpecification)){
60 //IConstraintSpecification only has one constructor with empty argument list
61 var constructor = info.load.constructors.get(0);
62 var instance = constructor.newInstance();
63 constraints.add(instance as IConstraintSpecification);
64 }
65 }
66
67 return constraints
68 }
69}