aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner
diff options
context:
space:
mode:
authorLibravatar 20001LastOrder <boqi.chen@mail.mcgill.ca>2020-11-03 22:52:26 -0500
committerLibravatar 20001LastOrder <boqi.chen@mail.mcgill.ca>2020-11-03 22:52:26 -0500
commit945f487a08b643392a5d5918c631640b9a0e4605 (patch)
treeb537c456e395950ce98daaabb9468c7c17d5a72b /Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner
parentFix numeric-solver-at-end (diff)
downloadVIATRA-Generator-945f487a08b643392a5d5918c631640b9a0e4605.tar.gz
VIATRA-Generator-945f487a08b643392a5d5918c631640b9a0e4605.tar.zst
VIATRA-Generator-945f487a08b643392a5d5918c631640b9a0e4605.zip
add realistic solver
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner')
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend5
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend18
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java619
3 files changed, 641 insertions, 1 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend
index 0bd8c50e..af7b071a 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend
@@ -33,6 +33,8 @@ import org.eclipse.viatra.dse.solutionstore.SolutionStore
33import org.eclipse.viatra.dse.statecode.IStateCoderFactory 33import org.eclipse.viatra.dse.statecode.IStateCoderFactory
34import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.SolutionStoreWithDiversityDescriptor 34import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.SolutionStoreWithDiversityDescriptor
35import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityGranularity 35import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityGranularity
36import org.eclipse.emf.ecore.util.EcoreUtil
37import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.HillClimbingOnRealisticMetricStrategyForModelGeneration
36 38
37class ViatraReasoner extends LogicReasoner{ 39class ViatraReasoner extends LogicReasoner{
38 val PartialInterpretationInitialiser initialiser = new PartialInterpretationInitialiser() 40 val PartialInterpretationInitialiser initialiser = new PartialInterpretationInitialiser()
@@ -64,6 +66,7 @@ class ViatraReasoner extends LogicReasoner{
64 workspace.writeModel(emptySolution,"init.partialmodel") 66 workspace.writeModel(emptySolution,"init.partialmodel")
65 } 67 }
66 emptySolution.problemConainer = problem 68 emptySolution.problemConainer = problem
69 val emptySolutionCopy = EcoreUtil.copy(emptySolution)
67 70
68 val ScopePropagator scopePropagator = new ScopePropagator(emptySolution) 71 val ScopePropagator scopePropagator = new ScopePropagator(emptySolution)
69 scopePropagator.propagateAllScopeConstraints 72 scopePropagator.propagateAllScopeConstraints
@@ -113,7 +116,7 @@ class ViatraReasoner extends LogicReasoner{
113 dse.addTransformationRule(rule) 116 dse.addTransformationRule(rule)
114 } 117 }
115 118
116 val strategy = new BestFirstStrategyForModelGeneration(workspace,viatraConfig,method) 119 val strategy = new HillClimbingOnRealisticMetricStrategyForModelGeneration(workspace,viatraConfig,method)
117 viatraConfig.progressMonitor.workedForwardTransformation 120 viatraConfig.progressMonitor.workedForwardTransformation
118 val transformationFinished = System.nanoTime 121 val transformationFinished = System.nanoTime
119 val transformationTime = transformationFinished - transformationStartTime 122 val transformationTime = transformationFinished - transformationStartTime
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend
index 6e3c5235..96bf014d 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend
@@ -55,6 +55,14 @@ class ViatraReasonerConfiguration extends LogicSolverConfiguration{
55 public var unfinishedWFWeight = 1 55 public var unfinishedWFWeight = 1
56 56
57 public var calculateObjectCreationCosts = false 57 public var calculateObjectCreationCosts = false
58
59 public var RealisticGuidance realisticGuidance = RealisticGuidance.Composite;
60
61 public var isWFOptional = false;
62
63 public var allowMustViolations = false;
64
65 public var String domain = '';
58} 66}
59 67
60public class DiversityDescriptor { 68public class DiversityDescriptor {
@@ -83,4 +91,14 @@ public class SearchSpaceConstraint {
83 public static val UNLIMITED_MAXDEPTH = Integer.MAX_VALUE 91 public static val UNLIMITED_MAXDEPTH = Integer.MAX_VALUE
84 public var int maxDepth = UNLIMITED_MAXDEPTH 92 public var int maxDepth = UNLIMITED_MAXDEPTH
85 public var List<Function1<ModelGenerationMethod, ModelGenerationMethodBasedGlobalConstraint>> additionalGlobalConstraints = new LinkedList 93 public var List<Function1<ModelGenerationMethod, ModelGenerationMethodBasedGlobalConstraint>> additionalGlobalConstraints = new LinkedList
94}
95
96public enum RealisticGuidance{
97 MPC,
98 NodeActivity,
99 OutDegree,
100 NodeType,
101 Composite,
102 Composite_Without_Violations,
103 Violations
86} \ No newline at end of file 104} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java
new file mode 100644
index 00000000..f1bf96b6
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java
@@ -0,0 +1,619 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse;
2
3import java.util.ArrayList;
4import java.util.Arrays;
5import java.util.Collection;
6import java.util.Collections;
7import java.util.Comparator;
8import java.util.HashMap;
9import java.util.HashSet;
10import java.util.Iterator;
11import java.util.LinkedList;
12import java.util.List;
13import java.util.Map;
14import java.util.PriorityQueue;
15import java.util.Random;
16import java.util.Set;
17
18import org.apache.log4j.Logger;
19import org.eclipse.emf.ecore.util.EcoreUtil;
20import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
21import org.eclipse.viatra.dse.base.ThreadContext;
22import org.eclipse.viatra.dse.objectives.Fitness;
23import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
24import org.eclipse.viatra.dse.solutionstore.SolutionStore;
25import org.eclipse.viatra.query.runtime.api.IPatternMatch;
26import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
27import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher;
28
29import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain;
30import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.MetricDistanceGroup;
31import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.PartialInterpretationMetricDistance;
32import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel;
33import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner;
34import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem;
35import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult;
36import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult;
37import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult;
38import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod;
39import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic;
40import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation;
41import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedPartialInterpretationStateCoder;
42import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation;
43import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser;
44import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.RealisticGuidance;
45import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration;
46import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace;
47
48public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements IStrategy {
49 // Services and Configuration
50 private ThreadContext context;
51 private ReasonerWorkspace workspace;
52 private ViatraReasonerConfiguration configuration;
53 private ModelGenerationMethod method;
54 private PartialInterpretation2Logic partialInterpretation2Logic = new PartialInterpretation2Logic();
55 private Comparator<TrajectoryWithFitness> comparator;
56 private Logger logger = Logger.getLogger(IStrategy.class);
57 public NumericSolver numericSolver = null;
58
59 // Running
60 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore;
61 private SolutionStore solutionStore;
62 private SolutionStoreWithCopy solutionStoreWithCopy;
63 private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor;
64 private volatile boolean isInterrupted = false;
65 private ModelResult modelResultByInternalSolver = null;
66 private Random random = new Random();
67
68 // matchers for detecting the number of violations
69 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mustMatchers;
70 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mayMatchers;
71
72 // Encode the used activations of a particular state
73 private Map<Object, List<Object>> stateAndActivations;
74 private boolean allowMustViolation;
75 private Domain domain;
76 int targetSize;
77 public ActivationSelector activationSelector = new EvenActivationSelector(random);
78 // Statistics
79 private int numberOfStatecoderFail = 0;
80 private int numberOfPrintedModel = 0;
81 private int numberOfSolverCalls = 0;
82 private PartialInterpretationMetricDistance metricDistance;
83 private double currentStateValue = Double.MAX_VALUE;
84 private double currentNodeTypeDistance = 1;
85 private int numNodesToGenerate = 0;
86 public long explorationStarted = 0;
87
88 public HillClimbingOnRealisticMetricStrategyForModelGeneration(
89 ReasonerWorkspace workspace,
90 ViatraReasonerConfiguration configuration,
91 ModelGenerationMethod method)
92 {
93 this.workspace = workspace;
94 this.configuration = configuration;
95 this.method = method;
96 }
97
98 public SolutionStoreWithCopy getSolutionStoreWithCopy() {
99 return solutionStoreWithCopy;
100 }
101 public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() {
102 return solutionStoreWithDiversityDescriptor;
103 }
104 public int getNumberOfStatecoderFail() {
105 return numberOfStatecoderFail;
106 }
107
108 @Override
109 public void initStrategy(ThreadContext context) {
110 this.context = context;
111 this.solutionStore = context.getGlobalContext().getSolutionStore();
112 domain = Domain.valueOf(configuration.domain);
113
114 ViatraQueryEngine engine = context.getQueryEngine();
115// // TODO: visualisation
116 mustMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
117 mayMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
118
119 // manully restict the number of super types of one class
120 this.method.getInvalidWF().forEach(a ->{
121 ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine);
122 mustMatchers.add(matcher);
123 });
124
125 this.method.getUnfinishedWF().forEach(a ->{
126 ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine);
127 mayMatchers.add(matcher);
128 });
129
130
131 //set up comparator
132 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
133 this.comparator = new Comparator<TrajectoryWithFitness>() {
134 @Override
135 public int compare(TrajectoryWithFitness o1, TrajectoryWithFitness o2) {
136 return objectiveComparatorHelper.compare(o2.fitness, o1.fitness);
137 }
138 };
139
140 this.solutionStoreWithCopy = new SolutionStoreWithCopy();
141 this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement);
142
143 trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11, comparator);
144 stateAndActivations = new HashMap<Object, List<Object>>();
145 metricDistance = new PartialInterpretationMetricDistance(domain);
146
147 //set whether allows must violations during the realistic generation
148 allowMustViolation = configuration.allowMustViolations;
149 targetSize = configuration.typeScopes.maxNewElements + 2;
150 this.numericSolver = new NumericSolver(context, method, this.configuration.runIntermediateNumericalConsistencyChecks, false);
151 }
152
153 @Override
154 public void explore() {
155 this.explorationStarted=System.nanoTime();
156 if (!context.checkGlobalConstraints()) {
157 logger.info("Global contraint is not satisifed in the first state. Terminate.");
158 return;
159 }
160 if (configuration.searchSpaceConstraints.maxDepth == 0) {
161 logger.info("Maximal depth is reached in the initial solution. Terminate.");
162 return;
163 }
164
165 final Fitness firstFittness = context.calculateFitness();
166
167 //final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
168 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]);
169 TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness);
170 trajectoiresToExplore.add(currentTrajectoryWithFittness);
171 Object lastState = null;
172
173 //if(configuration)
174 visualiseCurrentState();
175 // the two is the True and False node generated at the beginning of the generation
176 int count = 0;
177 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) {
178
179 if (currentTrajectoryWithFittness == null) {
180 if (trajectoiresToExplore.isEmpty()) {
181 logger.debug("State space is fully traversed.");
182 return;
183 } else {
184 currentTrajectoryWithFittness = selectState();
185 if (logger.isDebugEnabled()) {
186 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray()));
187 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness);
188 }
189 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory);
190
191 // reset the regression for this trajectory
192 metricDistance.getLinearModel().resetRegression(context.getCurrentStateId());
193 }
194 }
195
196 List<Object> activationIds = selectActivation();
197 PartialInterpretation model = (PartialInterpretation) context.getModel();
198 System.out.println(model.getNewElements().size());
199 System.out.println("# violations: " + getNumberOfViolations(mayMatchers));
200
201 Map<Object, Double> valueMap = new HashMap<Object,Double>();
202
203 //init epsilon and draw
204 MetricDistanceGroup heuristics = metricDistance.calculateMetricDistanceKS(model);
205
206 if(!stateAndActivations.containsKey(context.getCurrentStateId())) {
207 stateAndActivations.put(context.getCurrentStateId(), new ArrayList<Object>());
208 }
209
210 // calculate values for epsilon greedy
211 double epsilon = 1.0/count;
212 double draw = Math.random();
213 count++;
214 this.currentNodeTypeDistance = heuristics.getNodeTypeDistance();
215 numNodesToGenerate = model.getMaxNewElements();
216 System.out.println("NA distance: " + heuristics.getNADistance());
217 System.out.println("MPC distance: " + heuristics.getMPCDistance());
218 System.out.println("Out degree distance:" + heuristics.getOutDegreeDistance());
219 System.out.println("NodeType :" + currentNodeTypeDistance);
220
221
222 //TODO: the number of activations to be checked should be configurasble
223 if(activationIds.size() > 50) {
224 activationIds = activationIds.subList(0, 50);
225 }
226
227 valueMap = sortWithWeight(activationIds);
228 lastState = context.getCurrentStateId();
229 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && activationIds.size() > 0) {
230 final Object nextActivation = drawWithEpsilonProbabilty(activationIds, valueMap, epsilon, draw);
231
232 stateAndActivations.get(context.getCurrentStateId()).add(nextActivation);
233 logger.debug("Executing new activation: " + nextActivation);
234 context.executeAcitvationId(nextActivation);
235 visualiseCurrentState();
236 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness);
237 if(consistencyCheckResult == true) { continue mainLoop; }
238
239 int currentSize = model.getNewElements().size();
240 int targetDiff = targetSize - currentSize;
241 boolean shouldFinish = currentSize >= targetSize;
242
243 // does not allow must violations
244 if((getNumberOfViolations(mustMatchers) > 0|| getNumberOfViolations(mayMatchers) > targetDiff) && !allowMustViolation && !shouldFinish) {
245 context.backtrack();
246 }else {
247 final Fitness nextFitness = context.calculateFitness();
248
249 // the only hard objectives are configured in the config file
250 checkForSolution(nextFitness);
251
252 if (context.getDepth() > configuration.searchSpaceConstraints.maxDepth) {
253 logger.debug("Reached max depth.");
254 context.backtrack();
255 continue;
256 }
257
258 //Record value for current trajectory
259 TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness(
260 context.getTrajectory().toArray(), nextFitness);
261 int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size();
262 int violation = getNumberOfViolations(mayMatchers);
263 double currentValue = calculateCurrentStateValue(nodeSize, violation);
264 metricDistance.getLinearModel().feedData(context.getCurrentStateId(), metricDistance.calculateFeature(nodeSize, violation), currentValue, lastState);
265 trajectoiresToExplore.add(nextTrajectoryWithFittness);
266 currentStateValue = currentValue;
267 //Currently, just go to the next state without considering the value of trajectory
268 currentTrajectoryWithFittness = nextTrajectoryWithFittness;
269 continue mainLoop;
270
271 }
272 }
273 logger.debug("State is fully traversed.");
274 trajectoiresToExplore.remove(currentTrajectoryWithFittness);
275 currentTrajectoryWithFittness = null;
276 context.backtrack();
277 }
278 logger.info("Interrupted.");
279 }
280
281 /**
282 *
283 * @param activationIds
284 * @return: activation to value map
285 */
286 private Map<Object, Double> sortWithWeight(List<Object> activationIds){
287 Map<Object, Double> valueMap = new HashMap<Object, Double>();
288 Object currentId = context.getCurrentStateId();
289 // check for next states
290 for(Object id : activationIds) {
291 context.executeAcitvationId(id);
292 int violation = getNumberOfViolations(mayMatchers);
293
294 if(!allowMustViolation && getNumberOfViolations(mustMatchers) > 0) {
295 valueMap.put(id, Double.MAX_VALUE);
296 stateAndActivations.get(currentId).add(id);
297 }else {
298 valueMap.put(id, calculateFutureStateValue(violation));
299 }
300
301
302
303 context.backtrack();
304 }
305
306 //remove all the elements having large distance
307 Collections.sort(activationIds, Comparator.comparing(li -> valueMap.get(li)));
308 return valueMap;
309 }
310
311 private double calculateFutureStateValue(int violation) {
312 long start = System.nanoTime();
313 int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size();
314 double currentValue = calculateCurrentStateValue(nodeSize,violation);
315 double[] toPredict = metricDistance.calculateFeature(100, violation);
316 if(Math.abs(currentValue - currentStateValue) < 0.001) {
317 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start);
318 return Double.MAX_VALUE;
319 }
320 try {
321 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start);
322 return metricDistance.getLinearModel().getPredictionForNextDataSample(metricDistance.calculateFeature(nodeSize, violation), currentValue, toPredict);
323 }catch(IllegalArgumentException e) {
324 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start);
325 return currentValue;
326 }
327
328 }
329 private double calculateCurrentStateValue(int factor, int violation) {
330 PartialInterpretation model = (PartialInterpretation) context.getModel();
331 MetricDistanceGroup g = metricDistance.calculateMetricDistanceKS(model);
332 if(configuration.realisticGuidance == RealisticGuidance.MPC) {
333 return g.getMPCDistance();
334 }else if(configuration.realisticGuidance == RealisticGuidance.NodeActivity) {
335 return g.getNADistance();
336 }else if(configuration.realisticGuidance == RealisticGuidance.OutDegree) {
337 return g.getOutDegreeDistance();
338 }else if(configuration.realisticGuidance == RealisticGuidance.NodeType) {
339 return g.getNodeTypeDistance();
340 }else if(configuration.realisticGuidance == RealisticGuidance.Composite) {
341 double consistenceWeights = 5 * factor / (configuration.typeScopes.maxNewElements + 2) * (1- 1.0/(1+violation));
342 if(domain == Domain.Yakindumm) {
343 double unfinishFactor = 50 * (1 - (double)factor / targetSize);
344 double nodeTypeFactor = g.getNodeTypeDistance();
345 double normalFactor = 5;
346 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
347 nodeTypeFactor = 0;
348 normalFactor = 100;
349 unfinishFactor = 0;
350 }
351
352 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
353 }else if (domain == Domain.Ecore) {
354 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
355 double nodeTypeFactor = g.getNodeTypeDistance();
356 double normalFactor = 5;
357 if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) {
358 nodeTypeFactor = 0;
359 normalFactor = 100;
360 unfinishFactor *= 0.5;
361 }
362
363 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
364 }else {
365 double unfinishFactor = context.calculateFitness().get("CompositeUnfinishednessObjective");
366 double nodeTypeFactor = g.getNodeTypeDistance();
367 double normalFactor = 5;
368 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
369 nodeTypeFactor = 0;
370 normalFactor = 100;
371 //unfinishFactor *= 0.5;
372 }
373
374 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + 2*g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
375 }
376
377 }else if(configuration.realisticGuidance == RealisticGuidance.Composite_Without_Violations) {
378 if(domain == Domain.Yakindumm) {
379 double unfinishFactor = 50 * (1 - (double)factor / targetSize);
380 double nodeTypeFactor = g.getNodeTypeDistance();
381 double normalFactor = 5;
382 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
383 nodeTypeFactor = 0;
384 normalFactor = 100;
385 unfinishFactor = 0;
386 }
387
388 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
389 }else if (domain == Domain.Github) {
390 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
391 double nodeTypeFactor = g.getNodeTypeDistance();
392 double normalFactor = 5;
393 if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) {
394 nodeTypeFactor = 0;
395 normalFactor = 100;
396 unfinishFactor *= 0.5;
397 }
398
399 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
400 } else {
401 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
402 double nodeTypeFactor = g.getNodeTypeDistance();
403 double normalFactor = 5;
404 if(currentNodeTypeDistance <= 0.20 || numNodesToGenerate == 1) {
405 nodeTypeFactor = 0;
406 normalFactor = 100;
407 unfinishFactor *= 0.5;
408 }
409
410 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
411 }
412 }else {
413 return violation;
414 }
415 }
416
417 private int getNumberOfViolations(Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers) {
418 int violations = matchers.stream().mapToInt(m -> m.countMatches()).sum();
419
420 return violations;
421 }
422
423 // Modified epsilon greedy choose for action based on value function
424 // with probability epsilon, choose the state with probability based on the weight
425 // with probability 1 - epsilon, choose the best state
426 // epsilon should decay w.r.t. time
427 private Object drawWithEpsilonProbabilty(List<Object> activationIds, Map<Object, Double> valueMap, double epsilon, double currentDraw) {
428 if(activationIds.size() <= 0) {
429 return null;
430 }
431
432 // if epsilon is smaller than current draw, return greedy choice
433 if(epsilon < currentDraw) {
434 return activationIds.remove(0);
435 }else {
436 //else return draw with probability of the weights
437 //find the sum of all 1-weights: the smaller the better
438 double sum = valueMap.values().stream().mapToDouble(d->1).sum();
439 double rand = Math.random() * sum;
440 double iterator = 0.0;
441 Object idToReturn = null;
442
443 // draw an item with probability
444 for(Object o : valueMap.keySet()) {
445 iterator += (1);
446 if(rand < iterator) {
447 idToReturn = o;
448 break;
449 }
450 }
451
452 //delete the item from the list
453 activationIds.remove(idToReturn);
454 valueMap.remove(idToReturn);
455 return idToReturn;
456 }
457 }
458
459 private List<Object> selectActivation() {
460 List<Object> activationIds;
461 try {
462 activationIds = this.activationSelector.randomizeActivationIDs(context.getUntraversedActivationIds());
463 } catch (NullPointerException e) {
464 numberOfStatecoderFail++;
465 activationIds = Collections.emptyList();
466 }
467 return activationIds;
468 }
469
470 private void checkForSolution(final Fitness fittness) {
471 if (fittness.isSatisifiesHardObjectives()) {
472 logger.debug("Solution Found!!");
473 logger.debug("# violations: " + (getNumberOfViolations(mustMatchers)));
474 if (solutionStoreWithDiversityDescriptor.isDifferent(context)) {
475 solutionStoreWithCopy.newSolution(context);
476 solutionStoreWithDiversityDescriptor.newSolution(context);
477 solutionStore.newSolution(context);
478 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolution);
479
480 logger.debug("Found a solution.");
481 }
482 }
483 }
484
485 public List<String> times = new LinkedList<String>();
486 private void saveTimes() {
487 long statecoderTime = ((NeighbourhoodBasedPartialInterpretationStateCoder)this.context.getStateCoder()).getStatecoderRuntime()/1000000;
488 long solutionCopy = solutionStoreWithCopy.getSumRuntime()/1000000;
489 long activationSelection = this.activationSelector.getRuntime()/1000000;
490 long numericalSolverSumTime = this.numericSolver.getRuntime()/1000000;
491 long numericalSolverProblemForming = this.numericSolver.getSolverSolvingProblem()/1000000;
492 long numericalSolverSolving = this.numericSolver.getSolverSolvingProblem()/1000000;
493 long numericalSolverInterpreting = this.numericSolver.getSolverSolution()/1000000;
494 long metricCalculationTime = this.method.getStatistics().metricCalculationTime / 1000000;
495 this.times.add(
496 "(TransformationExecutionTime"+method.getStatistics().transformationExecutionTime/1000000+
497 "|StateCoderTime:"+statecoderTime+
498 "|SolutionCopyTime:"+solutionCopy+
499 "|ActivationSelectionTime:"+activationSelection+
500 "|NumericalSolverSumTime:"+numericalSolverSumTime+
501 "|NumericalSolverProblemFormingTime:"+numericalSolverProblemForming+
502 "|NumericalSolverSolvingTime:"+numericalSolverSolving+
503 "|NumericalSolverInterpretingSolution:"+numericalSolverInterpreting+
504 "|MetricCalculationTime:"+metricCalculationTime + ")"
505 );
506
507 }
508
509 @Override
510 public void interruptStrategy() {
511 isInterrupted = true;
512 }
513
514
515 private TrajectoryWithFitness selectState() {
516 int randomNumber = random.nextInt(configuration.randomBacktrackChance);
517 if (randomNumber == 0) {
518 int elements = trajectoiresToExplore.size();
519 int randomElementIndex = random.nextInt(elements);
520 logger.debug("Randomly backtract to the " + randomElementIndex + " best solution...");
521 Iterator<TrajectoryWithFitness> iterator = trajectoiresToExplore.iterator();
522 while (randomElementIndex != 0) {
523 iterator.next();
524 randomElementIndex--;
525 }
526 TrajectoryWithFitness res = iterator.next();
527 if (res == null) {
528 return trajectoiresToExplore.element();
529 } else {
530 return res;
531 }
532 } else {
533 return trajectoiresToExplore.element();
534 }
535 }
536
537// private void logCurrentStateMetric() {
538// if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) {
539// return;
540// }
541//
542// PartialInterpretation interpretation = (PartialInterpretation)context.getModel(); //pattern.get("interpretation");
543// PartialInterpretationMetric.calculateMetric(interpretation, "debug/metric/" + context.getModel().hashCode(), context.getCurrentStateId().toString());
544// }
545
546 public void visualiseCurrentState() {
547 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugCongiguration.partialInterpretatioVisualiser;
548 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) {
549 PartialInterpretation p = (PartialInterpretation) (context.getModel());
550 int id = ++numberOfPrintedModel;
551 if (id % configuration.debugCongiguration.partalInterpretationVisualisationFrequency == 0) {
552 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p);
553 visualisation.writeToFile(workspace, String.format("state%09d.png", id));
554 }
555 }
556 }
557
558 protected boolean checkConsistency(TrajectoryWithFitness t) {
559 LogicReasoner internalIncosnsitencyDetector = configuration.internalConsistencyCheckerConfiguration.internalIncosnsitencyDetector;
560 if (internalIncosnsitencyDetector!= null) {
561 int id = ++numberOfSolverCalls;
562 if (id % configuration.internalConsistencyCheckerConfiguration.incternalConsistencyCheckingFrequency == 0) {
563 try {
564 PartialInterpretation interpretation = (PartialInterpretation) (context.getModel());
565 PartialInterpretation copied = EcoreUtil.copy(interpretation);
566 this.partialInterpretation2Logic.transformPartialIntepretation2Logic(copied.getProblem(), copied);
567 LogicProblem newProblem = copied.getProblem();
568
569 this.configuration.typeScopes.maxNewElements = interpretation.getMaxNewElements();
570 this.configuration.typeScopes.minNewElements = interpretation.getMinNewElements();
571 LogicResult result = internalIncosnsitencyDetector.solve(newProblem, configuration, workspace);
572 if (result instanceof InconsistencyResult) {
573 logger.debug("Solver found an Inconsistency!");
574 removeSubtreeFromQueue(t);
575 return true;
576 } else if (result instanceof ModelResult) {
577 logger.debug("Solver found a model!");
578 solutionStore.newSolution(context);
579
580 this.modelResultByInternalSolver = (ModelResult) result;
581 return true;
582 } else {
583 logger.debug("Failed consistency check.");
584 return false;
585 }
586 } catch (Exception e) {
587 logger.debug("Problem with internal consistency checking: "+e.getMessage());
588 e.printStackTrace();
589 return false;
590 }
591 }
592
593 }
594 return false;
595 }
596
597 protected void removeSubtreeFromQueue(TrajectoryWithFitness t) {
598 PriorityQueue<TrajectoryWithFitness> previous = this.trajectoiresToExplore;
599 this.trajectoiresToExplore = new PriorityQueue<>(this.comparator);
600 for (TrajectoryWithFitness trajectoryWithFitness : previous) {
601 if (!containsAsSubstring(trajectoryWithFitness.trajectory, t.trajectory)) {
602 this.trajectoiresToExplore.add(trajectoryWithFitness);
603 } else {
604 logger.debug("State has been excluded due to inherent inconsistency");
605 }
606 }
607 }
608
609 private boolean containsAsSubstring(Object[] full, Object[] substring) {
610 if (substring.length > full.length) {
611 return false;
612 } else if (substring.length == full.length) {
613 return Arrays.equals(full, substring);
614 } else {
615 Object[] part = Arrays.copyOfRange(full, 0, substring.length);
616 return Arrays.equals(part, substring);
617 }
618 }
619}