diff options
author | 20001LastOrder <boqi.chen@mail.mcgill.ca> | 2019-08-08 16:45:45 -0400 |
---|---|---|
committer | 20001LastOrder <boqi.chen@mail.mcgill.ca> | 2019-08-08 16:45:45 -0400 |
commit | c33f0b9c4e112ee573d1b26d205a253cc0e487f8 (patch) | |
tree | 1ec2c4ab56b5bc0d0d56fa111bab0520c05604b4 /Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic | |
parent | Further development of realistic solver, create generation config for ecore m... (diff) | |
download | VIATRA-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')
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 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app | 1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app |
2 | 2 | ||
3 | enum Domain{ | 3 | enum 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 | |||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.EMFGraph | 3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.EMFGraph |
4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.CsvFileWriter | 4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.CsvFileWriter |
5 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.GraphReader | 5 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.GraphReader |
6 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.validation.ViolationCheck | ||
6 | import hu.bme.mit.inf.dslreasoner.domains.yakindu.sgraph.yakindumm.impl.YakindummPackageImpl | 7 | import hu.bme.mit.inf.dslreasoner.domains.yakindu.sgraph.yakindumm.impl.YakindummPackageImpl |
8 | import java.io.File | ||
7 | import java.util.ArrayList | 9 | import java.util.ArrayList |
10 | import org.eclipse.emf.ecore.EPackage | ||
8 | import org.eclipse.emf.ecore.EcorePackage | 11 | import org.eclipse.emf.ecore.EcorePackage |
12 | import org.eclipse.viatra.query.runtime.rete.matcher.ReteEngine | ||
13 | import org.eclipse.emf.ecore.impl.EcorePackageImpl | ||
14 | import org.eclipse.emf.ecore.EReference | ||
9 | 15 | ||
10 | //import yakindumm2.impl.Yakindumm2PackageImpl | 16 | //import yakindumm2.impl.Yakindumm2PackageImpl |
11 | 17 | ||
12 | class Main { | 18 | class 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 | |||
20 | import java.util.Map | 20 | import java.util.Map |
21 | import org.apache.commons.math3.stat.regression.OLSMultipleLinearRegression | 21 | import org.apache.commons.math3.stat.regression.OLSMultipleLinearRegression |
22 | import org.eclipse.xtend.lib.annotations.Accessors | 22 | import org.eclipse.xtend.lib.annotations.Accessors |
23 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.EdgeTypeMetric | ||
23 | 24 | ||
24 | class PartialInterpretationMetricDistance { | 25 | class 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 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app; | ||
2 | |||
3 | import java.util.ArrayList; | ||
4 | import java.util.List; | ||
5 | |||
6 | import weka.core.matrix.LinearRegression; | ||
7 | import weka.core.matrix.Matrix; | ||
8 | |||
9 | public 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 | |||
7 | import org.eclipse.emf.common.util.EList | 7 | import org.eclipse.emf.common.util.EList |
8 | import org.eclipse.emf.ecore.EObject | 8 | import org.eclipse.emf.ecore.EObject |
9 | import org.eclipse.emf.ecore.EReference | 9 | import org.eclipse.emf.ecore.EReference |
10 | import org.eclipse.xtend.lib.annotations.Accessors | ||
10 | 11 | ||
11 | class EMFGraph extends Graph{ | 12 | class 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 | ||
13 | class GraphStatistic { | 13 | class 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 | ||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric | 3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric |
4 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration | 4 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration |
5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type | ||
6 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDefinition | ||
5 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink | 7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink |
6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | 8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation |
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialComplexTypeInterpretationImpl | 9 | import 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 | |||
20 | import org.eclipse.emf.ecore.resource.ResourceSet | 20 | import org.eclipse.emf.ecore.resource.ResourceSet |
21 | import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl | 21 | import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl |
22 | import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl | 22 | import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl |
23 | import org.eclipse.emf.ecore.EGenericType | ||
24 | import org.eclipse.emf.ecore.EStructuralFeature | ||
23 | 25 | ||
24 | class GraphReader{ | 26 | class 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 | |||
4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup | 4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup |
5 | import hu.bme.mit.inf.dslreasoner.domains.yakindu.sgraph.yakindumm.impl.YakindummPackageImpl | 5 | import hu.bme.mit.inf.dslreasoner.domains.yakindu.sgraph.yakindumm.impl.YakindummPackageImpl |
6 | import java.util.HashMap | 6 | import java.util.HashMap |
7 | import org.eclipse.emf.ecore.EReference | ||
8 | import 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 | */ |
11 | class RepMetricsReader { | 13 | class 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 | |||
9 | class MultiplexParticipationCoefficientMetric extends Metric { | 9 | class 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 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.validation | ||
2 | |||
3 | import java.util.ArrayList | ||
4 | import java.util.HashMap | ||
5 | import java.util.List | ||
6 | import java.util.Map | ||
7 | import org.eclipse.emf.common.notify.Notifier | ||
8 | import org.eclipse.emf.common.util.URI | ||
9 | import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl | ||
10 | import org.eclipse.viatra.addon.validation.core.api.IConstraintSpecification | ||
11 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine | ||
12 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedPatternGroup | ||
13 | import org.eclipse.viatra.query.runtime.emf.EMFScope | ||
14 | |||
15 | class 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 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.validation | ||
2 | |||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain | ||
4 | import com.google.common.reflect.ClassPath | ||
5 | import hu.bme.mit.inf.dslreasoner.partialsnapshot_mavo.yakindu.Patterns | ||
6 | import java.util.ArrayList | ||
7 | import org.eclipse.emf.ecore.EObject | ||
8 | import org.eclipse.viatra.addon.validation.core.api.IConstraintSpecification | ||
9 | |||
10 | class 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 | } | ||