From 34404d03bc70647b55daf0d4378410629d548578 Mon Sep 17 00:00:00 2001 From: "S.John" Date: Thu, 1 Mar 2018 16:14:36 +0100 Subject: [PATCH 1/8] added schema location to output files --- .../src/uk/ac/kcl/ui/output/MDEOResultsOutput.xtend | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/uk.ac.kcl.mdeoptimise.ui/src/uk/ac/kcl/ui/output/MDEOResultsOutput.xtend b/src/plugins/uk.ac.kcl.mdeoptimise.ui/src/uk/ac/kcl/ui/output/MDEOResultsOutput.xtend index ada9e66af..36e6ea65c 100644 --- a/src/plugins/uk.ac.kcl.mdeoptimise.ui/src/uk/ac/kcl/ui/output/MDEOResultsOutput.xtend +++ b/src/plugins/uk.ac.kcl.mdeoptimise.ui/src/uk/ac/kcl/ui/output/MDEOResultsOutput.xtend @@ -18,6 +18,8 @@ import java.util.TimeZone import java.util.HashMap import com.google.common.io.Files import java.nio.charset.Charset +import org.eclipse.emf.ecore.xmi.XMIResource +import java.util.Map class MDEOResultsOutput { @@ -148,7 +150,12 @@ class MDEOResultsOutput { resource.contents.clear } resource.contents.add(model) - resource.save(Collections.EMPTY_MAP) + + // Keep schema location in output models + val Map options = new HashMap(); + options.put(XMIResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE); + + resource.save(options) } private def storeSolutionData(PrintWriter infoWriter, String modelPath, MoeaOptimisationSolution solution){ From 1cc6f34652c719114c10d9c9c66d4eb1a3790574 Mon Sep 17 00:00:00 2001 From: "S.John" Date: Wed, 14 Mar 2018 14:05:38 +0100 Subject: [PATCH 2/8] added copy of meta model to experiments folder; before result is saved, URI of referenced package is changed to point to copy of meta model --- .../ac/kcl/ui/output/MDEOResultsOutput.xtend | 56 ++++++++++++------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/src/plugins/uk.ac.kcl.mdeoptimise.ui/src/uk/ac/kcl/ui/output/MDEOResultsOutput.xtend b/src/plugins/uk.ac.kcl.mdeoptimise.ui/src/uk/ac/kcl/ui/output/MDEOResultsOutput.xtend index 36e6ea65c..595f1f948 100644 --- a/src/plugins/uk.ac.kcl.mdeoptimise.ui/src/uk/ac/kcl/ui/output/MDEOResultsOutput.xtend +++ b/src/plugins/uk.ac.kcl.mdeoptimise.ui/src/uk/ac/kcl/ui/output/MDEOResultsOutput.xtend @@ -1,25 +1,24 @@ package uk.ac.kcl.ui.output +import com.google.common.io.Files +import java.io.File +import java.io.PrintWriter +import java.nio.charset.Charset +import java.text.SimpleDateFormat import java.util.Date -import java.util.List +import java.util.HashMap import java.util.LinkedList +import java.util.List +import java.util.Map +import java.util.TimeZone +import org.eclipse.core.runtime.IPath +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.ecore.EObject import org.eclipse.emf.ecore.resource.ResourceSet -import uk.ac.kcl.mdeoptimise.Optimisation import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl -import org.eclipse.emf.ecore.EObject -import java.util.Collections -import java.text.SimpleDateFormat -import uk.ac.kcl.optimisation.moea.MoeaOptimisationSolution -import java.io.PrintWriter -import java.io.File -import org.eclipse.emf.common.util.URI -import org.eclipse.core.runtime.IPath -import java.util.TimeZone -import java.util.HashMap -import com.google.common.io.Files -import java.nio.charset.Charset import org.eclipse.emf.ecore.xmi.XMIResource -import java.util.Map +import uk.ac.kcl.mdeoptimise.Optimisation +import uk.ac.kcl.optimisation.moea.MoeaOptimisationSolution class MDEOResultsOutput { @@ -44,7 +43,7 @@ class MDEOResultsOutput { batches.add(batch); } - def String outputBatchSummary(MDEOBatch batch, IPath outcomePath) { + def String outputBatchSummary(MDEOBatch batch, IPath outcomePath, IPath metaModelOutputPath) { var batchOutputPath = outcomePath.append(String.format("batch-%s/", batch.id)) var batchInfoPath = batchOutputPath.append("outcome.txt") @@ -71,7 +70,7 @@ class MDEOResultsOutput { val solution = batch.solutions.get(i); val modelPath = batchOutputPath + String.format("%08X", solution.model.hashCode) + ".xmi" - solution.model.writeModel(modelPath) + solution.model.writeModel(modelPath, metaModelOutputPath.toPortableString) storeSolutionData(batchWriter, modelPath, solution) } @@ -132,25 +131,42 @@ class MDEOResultsOutput { } } + def IPath copyMetaModel(IPath outcomePath){ + val metaModelInputPath = projectRoot.append(moptConfiguration.basepath.location).append(moptConfiguration.metamodel.location) + val metaModelOutputPath = outcomePath.append(metaModelInputPath.lastSegment) + + if (!metaModelInputPath.empty) { + val outputFile = metaModelOutputPath.toFile + Files.createParentDirs(outputFile) + Files.copy(metaModelInputPath.toFile, outputFile) + } + return metaModelOutputPath + } + def void saveOutcome(){ val experimentDate = new SimpleDateFormat("yyMMdd-HHmmss").format(experimentStartTime); val outcomePath = projectRoot.append(String.format("mdeo-results/experiment-%s/", experimentDate)); + + val metaModelOutputPath = copyMetaModel(outcomePath) val batchesOutput = new StringBuilder(); - batches.forEach[ batch | batchesOutput.append(outputBatchSummary(batch, outcomePath))] + batches.forEach[ batch | batchesOutput.append(outputBatchSummary(batch, outcomePath, metaModelOutputPath))] outputExperimentSummary(batches, outcomePath, moptFile, batchesOutput) } - def writeModel(EObject model, String path) { - val resource = resourceSet.createResource(URI.createFileURI(path)) + def writeModel(EObject model, String path, String metaModelPath) { + val resource = resourceSet.createResource(URI.createFileURI(new File(path).absolutePath)) if (resource.loaded) { resource.contents.clear } resource.contents.add(model) + // Change URI of model package to reference the meta model copied to output location + model.eClass.EPackage.eResource.URI = URI.createFileURI(metaModelPath) + // Keep schema location in output models val Map options = new HashMap(); options.put(XMIResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE); From 14789967de105a7a26cf64eda6e43b171cff2944 Mon Sep 17 00:00:00 2001 From: "S.John" Date: Wed, 9 May 2018 09:45:32 +0200 Subject: [PATCH 3/8] moved MDEOResultsOutput init after null check --- .../src/uk/ac/kcl/ui/launch/RunOptimisation.xtend | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/plugins/uk.ac.kcl.mdeoptimise.ui/src/uk/ac/kcl/ui/launch/RunOptimisation.xtend b/src/plugins/uk.ac.kcl.mdeoptimise.ui/src/uk/ac/kcl/ui/launch/RunOptimisation.xtend index bac5989b0..2365d0814 100644 --- a/src/plugins/uk.ac.kcl.mdeoptimise.ui/src/uk/ac/kcl/ui/launch/RunOptimisation.xtend +++ b/src/plugins/uk.ac.kcl.mdeoptimise.ui/src/uk/ac/kcl/ui/launch/RunOptimisation.xtend @@ -56,11 +56,10 @@ class RunOptimisation { val resource = resourceSetProvider.get().getResource(URI.createFileURI(moptFile.getAbsolutePath()), true) val optimisationModel = resource.contents.head as Optimisation - val mdeoResultsOutput = new MDEOResultsOutput(new Date(), new Path(moptProjectPath), - new Path(configuredMoptFilePath), optimisationModel - ); - if(optimisationModel !== null){ + + val mdeoResultsOutput = new MDEOResultsOutput(new Date(), new Path(moptProjectPath), + new Path(configuredMoptFilePath), optimisationModel); var experimentId = 0; do { From f94bba0f5c9410d7e7ccad2cb6c5c6ec3aad51ee Mon Sep 17 00:00:00 2001 From: "S.John" Date: Wed, 9 May 2018 16:31:28 +0200 Subject: [PATCH 4/8] fixed offspring of crossover being returned even when they are not mutated --- .../kcl/optimisation/moea/MoeaProbabilisticVariation.xtend | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/moea/MoeaProbabilisticVariation.xtend b/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/moea/MoeaProbabilisticVariation.xtend index b47d10a3d..6c1fbc4a3 100644 --- a/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/moea/MoeaProbabilisticVariation.xtend +++ b/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/moea/MoeaProbabilisticVariation.xtend @@ -45,20 +45,18 @@ class MoeaProbabilisticVariation implements Variation { println("Not running crossover this run") } - var solutions = new LinkedList(); - for(var i = 0; i < result.length; i++){ var mutationProbability = random.nextDouble if(mutationProbability <= mutationRate){ println("Running mutation with probability: " + mutationProbability) - solutions.addAll(mutationOperator.evolve(#[result.get(i)])) + result.set(i, mutationOperator.evolve(#[result.get(i)]).get(0)) } else { println("Not running mutation this run") } } - return solutions; + return result; } From 56d32559a65603055159a18922102c1c8b0d685b Mon Sep 17 00:00:00 2001 From: "S.John" Date: Tue, 15 May 2018 17:16:14 +0200 Subject: [PATCH 5/8] changed crossover from inplace to outplace (implies arity of 2), added INOUT to respected parameters --- .../kcl/optimisation/SolutionGenerator.xtend | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend b/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend index 5964a1944..02bed03da 100644 --- a/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend +++ b/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend @@ -25,6 +25,8 @@ import org.eclipse.emf.henshin.interpreter.EGraph import java.util.Arrays import uk.ac.kcl.interpreter.evolvers.parameters.EvolverParametersFactory import org.eclipse.emf.henshin.model.ParameterKind +import com.google.common.collect.Iterables +import org.eclipse.emf.henshin.interpreter.impl.LoggingApplicationMonitor class SolutionGenerator { @@ -84,12 +86,16 @@ class SolutionGenerator { * @returns a list of results offspring */ def List crossover(List parents) { - - val crossoverParents = new ArrayList; - parents.forEach[parent | crossoverParents.add(EcoreUtil.copy(parent))] + val firstRunParents = new ArrayList; + val secondRunParents = new ArrayList; + + parents.forEach[parent | firstRunParents.add(EcoreUtil.copy(parent))] + parents.reverseView.forEach[parent | secondRunParents.add(EcoreUtil.copy(parent))] + + val firstRunGraph = new EGraphImpl(firstRunParents); + val secondRunGraph = new EGraphImpl(secondRunParents); - val graph = new EGraphImpl(crossoverParents) val triedOperators = new ArrayList() // Randomly pick one unit @@ -100,14 +106,19 @@ class SolutionGenerator { if(operator.eClass().getClassifierID() == HenshinPackage.RULE){ //Run the selected Henshin Rule - if(runRuleOperator(operator, graph, parents)){ + + if(runRuleOperator(operator, firstRunGraph, parents) + && runRuleOperator(operator, secondRunGraph, parents.reverseView) + ){ //println("Could run mutation" + matchToUse.name) - return graph.roots + return #[firstRunGraph.roots.get(1), secondRunGraph.roots.get(1)] } } else { - if(runUnitOperator(operator, graph, parents)){ + if(runUnitOperator(operator, firstRunGraph, parents) + && runUnitOperator(operator, secondRunGraph, parents.reverseView) + ){ //println("Could run mutation" + matchToUse.name) - return graph.roots + return #[firstRunGraph.roots.get(1), secondRunGraph.roots.get(1)] } } @@ -135,9 +146,9 @@ class SolutionGenerator { ruleRunner.unit = operator if(operator.parameters != null){ - //TODO Not sure about this filter. Check what kind of parameter we would expect people - //to pass in - var inParameters = operator.parameters.filter[parameter | parameter.kind.equals(ParameterKind.IN)] + var inParameters = operator.parameters.filter[parameter | parameter.kind.equals(ParameterKind.IN) + || parameter.kind.equals(ParameterKind.INOUT) + ] if(!inParameters.empty){ inParameters.forEach[ @@ -150,7 +161,7 @@ class SolutionGenerator { } //Run the selected Henshin Rule - return ruleRunner.execute(null) + return ruleRunner.execute(new LoggingApplicationMonitor) } @@ -171,7 +182,7 @@ class SolutionGenerator { } //Run the selected Henshin Unit - return unitRunner.execute(null) + return unitRunner.execute(new LoggingApplicationMonitor) } From e2a29d0f2f1f915e15ab3cc9a56797c15da3bab8 Mon Sep 17 00:00:00 2001 From: "S.John" Date: Tue, 15 May 2018 17:25:00 +0200 Subject: [PATCH 6/8] removed logging --- .../kcl/optimisation/SolutionGenerator.xtend | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend b/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend index 02bed03da..b4e7100a2 100644 --- a/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend +++ b/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend @@ -1,32 +1,29 @@ package uk.ac.kcl.optimisation import java.util.ArrayList +import java.util.Arrays import java.util.Iterator import java.util.List import java.util.Random import org.eclipse.emf.ecore.EObject import org.eclipse.emf.ecore.EPackage import org.eclipse.emf.ecore.util.EcoreUtil +import org.eclipse.emf.henshin.interpreter.EGraph import org.eclipse.emf.henshin.interpreter.Engine import org.eclipse.emf.henshin.interpreter.impl.ChangeImpl import org.eclipse.emf.henshin.interpreter.impl.EGraphImpl import org.eclipse.emf.henshin.interpreter.impl.EngineImpl import org.eclipse.emf.henshin.interpreter.impl.RuleApplicationImpl +import org.eclipse.emf.henshin.interpreter.impl.UnitApplicationImpl +import org.eclipse.emf.henshin.model.HenshinPackage +import org.eclipse.emf.henshin.model.ParameterKind import org.eclipse.emf.henshin.model.Unit import uk.ac.kcl.interpreter.IModelProvider +import uk.ac.kcl.interpreter.evolvers.parameters.EvolverParametersFactory +import uk.ac.kcl.interpreter.evolvers.parameters.IEvolverParametersFactory import uk.ac.kcl.mdeoptimise.Optimisation import static org.eclipse.emf.henshin.interpreter.impl.ChangeImpl.* -import org.eclipse.emf.henshin.model.Rule -import org.eclipse.emf.henshin.interpreter.impl.UnitApplicationImpl -import uk.ac.kcl.interpreter.evolvers.parameters.IEvolverParametersFactory -import org.eclipse.emf.henshin.model.HenshinPackage -import org.eclipse.emf.henshin.interpreter.EGraph -import java.util.Arrays -import uk.ac.kcl.interpreter.evolvers.parameters.EvolverParametersFactory -import org.eclipse.emf.henshin.model.ParameterKind -import com.google.common.collect.Iterables -import org.eclipse.emf.henshin.interpreter.impl.LoggingApplicationMonitor class SolutionGenerator { @@ -145,7 +142,7 @@ class SolutionGenerator { ruleRunner.EGraph = graph ruleRunner.unit = operator - if(operator.parameters != null){ + if(operator.parameters !== null){ var inParameters = operator.parameters.filter[parameter | parameter.kind.equals(ParameterKind.IN) || parameter.kind.equals(ParameterKind.INOUT) ] @@ -161,7 +158,7 @@ class SolutionGenerator { } //Run the selected Henshin Rule - return ruleRunner.execute(new LoggingApplicationMonitor) + return ruleRunner.execute(null) } @@ -182,7 +179,7 @@ class SolutionGenerator { } //Run the selected Henshin Unit - return unitRunner.execute(new LoggingApplicationMonitor) + return unitRunner.execute(null) } From 2b6c9083c7366ef8575747e40219b914f6279cc4 Mon Sep 17 00:00:00 2001 From: "S.John" Date: Wed, 16 May 2018 10:08:18 +0200 Subject: [PATCH 7/8] fixed missing inout parameter in runUnitOperator --- .../src/uk/ac/kcl/optimisation/SolutionGenerator.xtend | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend b/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend index b4e7100a2..e640d29a3 100644 --- a/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend +++ b/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend @@ -144,8 +144,7 @@ class SolutionGenerator { if(operator.parameters !== null){ var inParameters = operator.parameters.filter[parameter | parameter.kind.equals(ParameterKind.IN) - || parameter.kind.equals(ParameterKind.INOUT) - ] + || parameter.kind.equals(ParameterKind.INOUT)] if(!inParameters.empty){ inParameters.forEach[ @@ -167,8 +166,9 @@ class SolutionGenerator { unitRunner.EGraph = graph unitRunner.unit = operator - var inParameters = operator.parameters.filter[parameter | parameter.kind.equals(ParameterKind.IN)] - + var inParameters = operator.parameters.filter[parameter | parameter.kind.equals(ParameterKind.IN) + || parameter.kind.equals(ParameterKind.INOUT)] + if(!inParameters.empty){ inParameters.forEach[ parameter | unitRunner.setParameterValue( From cb7ec8d9ea926cea11887efbcea195e5ace0da54 Mon Sep 17 00:00:00 2001 From: "S.John" Date: Thu, 17 May 2018 11:10:53 +0200 Subject: [PATCH 8/8] fixed wrong object being used for parameter evaluation --- .../src/uk/ac/kcl/optimisation/SolutionGenerator.xtend | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend b/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend index e640d29a3..6a31ee37f 100644 --- a/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend +++ b/src/plugins/uk.ac.kcl.mdeoptimise/src/uk/ac/kcl/optimisation/SolutionGenerator.xtend @@ -104,15 +104,15 @@ class SolutionGenerator { if(operator.eClass().getClassifierID() == HenshinPackage.RULE){ //Run the selected Henshin Rule - if(runRuleOperator(operator, firstRunGraph, parents) - && runRuleOperator(operator, secondRunGraph, parents.reverseView) + if(runRuleOperator(operator, firstRunGraph, firstRunParents) + && runRuleOperator(operator, secondRunGraph, secondRunParents) ){ //println("Could run mutation" + matchToUse.name) return #[firstRunGraph.roots.get(1), secondRunGraph.roots.get(1)] } } else { - if(runUnitOperator(operator, firstRunGraph, parents) - && runUnitOperator(operator, secondRunGraph, parents.reverseView) + if(runUnitOperator(operator, firstRunGraph, firstRunParents) + && runUnitOperator(operator, secondRunGraph, secondRunParents) ){ //println("Could run mutation" + matchToUse.name) return #[firstRunGraph.roots.get(1), secondRunGraph.roots.get(1)]