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

import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.JSDistance
import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.KSDistance
import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.PartialInterpretationGraph
import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.CsvFileWriter
import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric
import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric
import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric
import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
import java.io.File
import java.io.FileNotFoundException
import java.io.PrintWriter
import java.util.ArrayList
import java.util.List
import org.eclipse.emf.ecore.util.EcoreUtil
import org.eclipse.viatra.dse.api.Solution

class PartialInterpretationMetric {
	var static KSDistance ks;
	var static JSDistance js;
	
	def static void initPaths(){
		new File("debug/metric/").mkdir();
		new File("debug/metric/trajectories/").mkdir();
		ks = new KSDistance(Domain.Yakinduum);
		js = new JSDistance(Domain.Yakinduum);
	}
	
	def static MetricDistanceGroup calculateMetricDistance(PartialInterpretation partial){
		val metrics = new ArrayList<Metric>();
		metrics.add(new OutDegreeMetric());
		metrics.add(new NodeActivityMetric());
		metrics.add(new MultiplexParticipationCoefficientMetric());
		
		val metricCalculator = new PartialInterpretationGraph(partial, metrics, null);		
		var metricSamples = metricCalculator.evaluateAllMetricsToSamples();
		
		var mpc = js.mpcDistance(metricSamples.mpcSamples);
		var na = js.naDistance(metricSamples.naSamples);
		var outDegree = js.outDegreeDistance(metricSamples.outDegreeSamples);
		
		return new MetricDistanceGroup(mpc, na, outDegree);
	}
	
	def static MetricDistanceGroup calculateMetricDistanceKS(PartialInterpretation partial){
		val metrics = new ArrayList<Metric>();
		metrics.add(new OutDegreeMetric());
		metrics.add(new NodeActivityMetric());
		metrics.add(new MultiplexParticipationCoefficientMetric());
		
		val metricCalculator = new PartialInterpretationGraph(partial, metrics, null);		
		var metricSamples = metricCalculator.evaluateAllMetricsToSamples();
		
		var mpc = ks.mpcDistance(metricSamples.mpcSamples);
		var na = ks.naDistance(metricSamples.naSamples);
		var outDegree = ks.outDegreeDistance(metricSamples.outDegreeSamples);
		
		return new MetricDistanceGroup(mpc, na, outDegree);
	}
	
	// calculate the metrics for a state
	def static void calculateMetric(PartialInterpretation partial, String path, String currentStateId, Integer counter){
		val metrics = new ArrayList<Metric>();
		metrics.add(new OutDegreeMetric());
		metrics.add(new NodeActivityMetric());
		metrics.add(new MultiplexParticipationCoefficientMetric());
		
		//make dir since the folder can be none existing
		new File(path).mkdir();
		val filename = path + "/state_"+currentStateId+"-"+counter+".csv";
		val metricCalculator = new PartialInterpretationGraph(partial, metrics, currentStateId);
		
		CsvFileWriter.write(metricCalculator.evaluateAllMetrics(), filename);
	}
	
	def static void outputTrajectories(PartialInterpretation empty, List<Solution>  solutions){	
		for(solution : solutions){
			
			//need to copy the empty solution because the transition directly worked on the graph
			val emptySolutionCopy = EcoreUtil.copy(empty)
			val trajectory = solution.shortestTrajectory;
			trajectory.model = emptySolutionCopy
			
			// state codes that will record the trajectory
			val stateCodes = newArrayList()
			var counter = 0

			//transform and record the state codes for each state
			while(trajectory.doNextTransformation){
				//println(trajectory.stateCoder.createStateCode)
				val stateId = trajectory.stateCoder.createStateCode.toString
				val interpretation = trajectory.getModel();
				println(stateId)
				//calculate metrics of current state
				calculateMetric(interpretation as PartialInterpretation, "debug/metric/output", stateId, counter)
				stateCodes.add(stateId)
				counter++
			}
			
			
			//output the trajectory
			try{
				new File("debug/metric/trajectories/").mkdir();
				val path = "debug/metric/trajectories/trajectory"+trajectory.stateCoder.createStateCode.toString+".csv"
				val PrintWriter writer = new PrintWriter(new File(path))
				val output = new StringBuilder
				for(stateCode : stateCodes){
					output.append(stateCode+'\n')
				}
				writer.write(output.toString())
				writer.close()
			}catch(FileNotFoundException e) {
				e.printStackTrace()
			}
		}			
	}
}

class MetricDistanceGroup{
	var double mpcDistance;
	var double naDistance;
	var double outDegreeDistance;
	
	new(double mpcDistance, double naDistance, double outDegreeDistance){
		this.mpcDistance = mpcDistance;
		this.naDistance = naDistance;
		this.outDegreeDistance = outDegreeDistance;
	}
	
	def double getMPCDistance(){
		return this.mpcDistance
	}
	
	def double getNADistance(){
		return this.naDistance
	}
	
	def double getOutDegreeDistance(){
		return this.outDegreeDistance
	}
}