aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <marussy@mit.bme.hu>2020-06-30 18:03:48 +0200
committerLibravatar Kristóf Marussy <marussy@mit.bme.hu>2020-06-30 18:03:48 +0200
commite11bce7ad3e803e80883499fec0ad6e4540ffe43 (patch)
treeca3ad9d5b9137e9455485e43350a4a353f487f22
parentDisable unrepairable match scoping for now (diff)
downloadVIATRA-Generator-e11bce7ad3e803e80883499fec0ad6e4540ffe43.tar.gz
VIATRA-Generator-e11bce7ad3e803e80883499fec0ad6e4540ffe43.tar.zst
VIATRA-Generator-e11bce7ad3e803e80883499fec0ad6e4540ffe43.zip
Add modified VIATRA-DSE version
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.classpath7
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.project28
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.settings/org.eclipse.jdt.core.prefs8
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/MANIFEST.MF387
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.properties3
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.xml14
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/about.html21
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/build.properties4
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSEException.java47
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSETransformationRule.java51
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DesignSpaceExplorer.java622
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Objectives.java153
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Solution.java60
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/SolutionTrajectory.java338
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Strategies.java123
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BestFirstStrategy.java228
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BreadthFirstStrategy.java220
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/DepthFirstStrategy.java188
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/FixedPriorityStrategy.java208
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/HillClimbingStrategy.java142
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/RandomSearchStrategy.java163
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategy.java44
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategyFactory.java13
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ActivationCodesConflictSet.java213
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DesignSpaceManager.java563
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictResolver.java35
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictSet.java83
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseEvmRuleBase.java21
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseIdPoolHelper.java68
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ExplorerThread.java88
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/GlobalContext.java374
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/IDseStrategyContext.java117
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/SingletonSetConflictResolver.java53
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ThreadContext.java542
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/DesignSpace.java106
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IBacktrackListener.java7
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IDesignSpace.java27
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/TrajectoryInfo.java154
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/multithreading/DSEThreadPool.java58
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ActivationFitnessProcessor.java15
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Comparators.java31
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Fitness.java29
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IGlobalConstraint.java58
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IObjective.java110
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/LeveledObjectivesHelper.java114
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ObjectiveComparatorHelper.java217
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/TrajectoryFitness.java84
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/AlwaysSatisfiedDummyHardObjective.java52
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/BaseObjective.java150
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/CompositeObjective.java137
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ConstraintsObjective.java316
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/DepthHardObjective.java89
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueriesGlobalConstraint.java116
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueryType.java14
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NeverSatisfiedDummyHardObjective.java52
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NoRuleActivationsHardObjective.java59
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/TrajectoryCostSoftObjective.java148
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionFoundHandler.java40
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionNameProvider.java18
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/IdBasedSolutionNameProvider.java37
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/LogSolutionHandler.java28
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ModelSaverSolutionFoundHandler.java55
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/SolutionStore.java311
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoder.java82
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoderFactory.java29
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProvider.java45
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProviderFactory.java25
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProvider.java60
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProviderFactory.java18
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependency.java33
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyGraph.java44
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyType.java15
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNode.java100
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNodeType.java17
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoder.java215
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoderFactory.java40
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder.java250
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoderFactory.java38
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/EMFHelper.java424
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/Hasher.java86
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/ValueComparableEObjectStringMap.java63
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/DesignSpaceVisualizerOptions.java56
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IDesignSpaceVisualizer.java39
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IExploreEventHandler.java40
84 files changed, 9580 insertions, 0 deletions
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.classpath b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.classpath
new file mode 100644
index 00000000..ed0eb24c
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.classpath
@@ -0,0 +1,7 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<classpath>
3 <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
4 <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
5 <classpathentry kind="src" path="src/"/>
6 <classpathentry kind="output" path="bin"/>
7</classpath>
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.project b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.project
new file mode 100644
index 00000000..aa414f43
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.project
@@ -0,0 +1,28 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<projectDescription>
3 <name>org.eclipse.viatra.dse</name>
4 <comment></comment>
5 <projects>
6 </projects>
7 <buildSpec>
8 <buildCommand>
9 <name>org.eclipse.jdt.core.javabuilder</name>
10 <arguments>
11 </arguments>
12 </buildCommand>
13 <buildCommand>
14 <name>org.eclipse.pde.ManifestBuilder</name>
15 <arguments>
16 </arguments>
17 </buildCommand>
18 <buildCommand>
19 <name>org.eclipse.pde.SchemaBuilder</name>
20 <arguments>
21 </arguments>
22 </buildCommand>
23 </buildSpec>
24 <natures>
25 <nature>org.eclipse.pde.PluginNature</nature>
26 <nature>org.eclipse.jdt.core.javanature</nature>
27 </natures>
28</projectDescription>
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.settings/org.eclipse.jdt.core.prefs b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..9f6ece88
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
1eclipse.preferences.version=1
2org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
4org.eclipse.jdt.core.compiler.compliance=1.8
5org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
6org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
7org.eclipse.jdt.core.compiler.release=disabled
8org.eclipse.jdt.core.compiler.source=1.8
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/MANIFEST.MF b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..fabef844
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/MANIFEST.MF
@@ -0,0 +1,387 @@
1Manifest-Version: 1.0
2Automatic-Module-Name: org.eclipse.viatra.dse
3Bundle-SymbolicName: org.eclipse.viatra.dse;singleton:=true
4Require-Bundle: org.eclipse.viatra.query.runtime;bundle-version="[2.4.
5 0,2.5.0)";visibility:=reexport,org.eclipse.viatra.transformation.evm;
6 bundle-version="[2.4.0,2.5.0)";visibility:=reexport,org.eclipse.emf.e
7 core,org.eclipse.emf.ecore.xmi;bundle-version="2.7.0",org.eclipse.emf
8 .edit,org.eclipse.viatra.transformation.runtime.emf;bundle-version="[
9 2.4.0,2.5.0)";visibility:=reexport
10Bundle-ManifestVersion: 2
11Bundle-RequiredExecutionEnvironment: JavaSE-1.8
12Bundle-ActivationPolicy: lazy
13Eclipse-SourceReferences: scm:git:git://git.eclipse.org/gitroot/viatra
14 /org.eclipse.viatra.git;path="dse/plugins/org.eclipse.viatra.dse";com
15 mitId=2a7314b6b21df594743fa017d18ae62da85c73fa
16Bundle-Vendor: Eclipse VIATRA Project
17Import-Package: com.google.common.base;version="27.1.0",com.google.com
18 mon.collect;version="27.1.0",com.google.common.util.concurrent;versio
19 n="27.1.0",org.apache.log4j;version="1.2.15"
20Export-Package: org.eclipse.viatra.dse.api,org.eclipse.viatra.dse.api.
21 strategy.impl,org.eclipse.viatra.dse.api.strategy.interfaces,org.ecli
22 pse.viatra.dse.base,org.eclipse.viatra.dse.designspace.api,org.eclips
23 e.viatra.dse.multithreading,org.eclipse.viatra.dse.objectives,org.ecl
24 ipse.viatra.dse.objectives.impl,org.eclipse.viatra.dse.solutionstore,
25 org.eclipse.viatra.dse.statecode,org.eclipse.viatra.dse.statecoding,o
26 rg.eclipse.viatra.dse.statecoding.simple,org.eclipse.viatra.dse.util,
27 org.eclipse.viatra.dse.visualizer
28SCM-Revision: 2a7314b6b21df594743fa017d18ae62da85c73fa
29Bundle-Name: VIATRA-DSE framework Base (Incubation)
30Bundle-Version: 0.24.0.202005060951
31Build-Jdk-Spec: 1.8
32Created-By: Maven Archiver 3.5.0
33
34Name: org/eclipse/viatra/dse/objectives/impl/NoRuleActivationsHardObje
35 ctive.class
36SHA-256-Digest: nEIutogP27RZKAUo9eH/DshkhyOF8voUnj4BC/pkhYU=
37
38Name: org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder$1.cla
39 ss
40SHA-256-Digest: t7KG11FngBrFGTPHJuEaP5BvpPqRYMDq8qKuQyccRWQ=
41
42Name: org/eclipse/viatra/dse/base/ThreadContext.class
43SHA-256-Digest: 0Z+RpFCBKvn1+SVJSLpRbEpoMATPujvvfqGsBr99mBI=
44
45Name: org/eclipse/viatra/dse/objectives/impl/ModelQueriesGlobalConstra
46 int.class
47SHA-256-Digest: 3qw4e1RY7TqpTKHRngBjCRWfJmMmu+DiUnKHO0yXVA4=
48
49Name: org/eclipse/viatra/dse/objectives/IObjective.class
50SHA-256-Digest: io0MQDhFysUXcHYcPUZENsy/xLn98SE65b2RbJ7QttM=
51
52Name: org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder.class
53SHA-256-Digest: yOvisOPQT9D/tuLV5fLonIoDpqi8bSRbPVjtLtv4UKo=
54
55Name: org/eclipse/viatra/dse/base/ExplorerThread.class
56SHA-256-Digest: N4tY8yMnFoKGoMyS0RdRtqpGIh6ucbvvAxnf/YPr/xk=
57
58Name: org/eclipse/viatra/dse/solutionstore/SolutionStore$BestSolutionS
59 aver.class
60SHA-256-Digest: yZkg5ntRMOsrKEgo7kkAaK5J8h11Ng8tzH4QXsLRhsM=
61
62Name: org/eclipse/viatra/dse/api/strategy/impl/RandomSearchStrategy$Sh
63 aredData.class
64SHA-256-Digest: 2jBwT4lfAUh7LDDmpi3JuzyjcWhVeb+53PPB5ZKlGx4=
65
66Name: org/eclipse/viatra/dse/base/DseIdPoolHelper$IGetRuleExecutions.c
67 lass
68SHA-256-Digest: s7Pr9OPNF5baYmoZlOTWl6keA+b1TVxV8zxBXMGewrM=
69
70Name: org/eclipse/viatra/dse/api/strategy/impl/RandomSearchStrategy.cl
71 ass
72SHA-256-Digest: 0R8ENAT9UA3BCsveA38VjvR4k+Um3i1fFlQB85inLZY=
73
74Name: org/eclipse/viatra/dse/api/DesignSpaceExplorer.class
75SHA-256-Digest: JCDN006fVS56ROn6cV7Ssdl4CN+xtbdiWjVfDkkgRDM=
76
77Name: org/eclipse/viatra/dse/util/EMFHelper$ENamedElementComparator.cl
78 ass
79SHA-256-Digest: J8o5TEdYpuU/6q1qTw3lUIHaE4pEH/EpDUvuTNWusVA=
80
81Name: org/eclipse/viatra/dse/util/ValueComparableEObjectStringMap$EObj
82 ectComparator.class
83SHA-256-Digest: iwLJSS2Ip9WvN2lC8gfg+ys5Cp+P7ZSpGP6QF5lKYKQ=
84
85Name: org/eclipse/viatra/dse/api/DesignSpaceExplorer$DseLoggingLevel.c
86 lass
87SHA-256-Digest: z3h4wzaSMGzPvV4KL6ilStnLdT/mVCNNp7C/AwfQhqk=
88
89Name: org/eclipse/viatra/dse/multithreading/DSEThreadPool.class
90SHA-256-Digest: XoKcmDnafPfiyQ0LemN0ni31T+aY+lXp/Q8p157kj/g=
91
92Name: org/eclipse/viatra/dse/api/strategy/impl/DepthFirstStrategy.clas
93 s
94SHA-256-Digest: SGlKz9PbynZwkmaJ1rpE0kVUOHl7vl7GOscNFoNEHLg=
95
96Name: org/eclipse/viatra/dse/base/GlobalContext.class
97SHA-256-Digest: dLn/Iu9JVDaaKK21VeFAMDXGaJWROEJCWJjULwMzNik=
98
99Name: org/eclipse/viatra/dse/statecoding/IncrementalObjectProvider.cla
100 ss
101SHA-256-Digest: L0yK9bhku/F8MX/NyKoBuydeMbMgZir8N0BRcFzHnKs=
102
103Name: org/eclipse/viatra/dse/statecode/IStateCoderFactory.class
104SHA-256-Digest: 1GsfU5aBQs1ieo3dblcXFZ07oq9QzWr1NZLppgSdCOM=
105
106Name: org/eclipse/viatra/dse/base/DesignSpaceManager$1.class
107SHA-256-Digest: /suIApW5KeZ7OifoR8SRPc3gU+2B8/ZnWInhdpAOTd8=
108
109Name: org/eclipse/viatra/dse/objectives/ActivationFitnessProcessor.cla
110 ss
111SHA-256-Digest: vML6AN6aCbn/cKeccmvzRAai47jZJk0CpYhwFQdhwvI=
112
113Name: org/eclipse/viatra/dse/solutionstore/IdBasedSolutionNameProvider
114 .class
115SHA-256-Digest: QFWpXui2nID6PKhTHs/1e0gj9u8NiniES6/G0C/oSzM=
116
117Name: org/eclipse/viatra/dse/api/strategy/impl/BreadthFirstStrategy$Bf
118 sSharedObject.class
119SHA-256-Digest: wVno1chuJ8pYpfv5cpB0fjsGbO2s+2OWcaVQgoQb5+k=
120
121Name: org/eclipse/viatra/dse/objectives/TrajectoryFitness.class
122SHA-256-Digest: DIEgS7SFg5pWuxvFhRn3f7hBt8+qk1+40w9WpOkoyrc=
123
124Name: org/eclipse/viatra/dse/solutionstore/SolutionStore$1.class
125SHA-256-Digest: V5AAqo4/81KOegdl1Wl8jIBrH57y4TdYrj+wOzV2vdM=
126
127Name: org/eclipse/viatra/dse/api/Solution.class
128SHA-256-Digest: U71jRd/R8tarIiHM+dETwXiwwPcmXO5m82bDUp/Mduo=
129
130Name: org/eclipse/viatra/dse/util/EMFHelper$EmfHelperException.class
131SHA-256-Digest: +OCT0+wqq9XGCze/qDE8hh3zprFMBAnkR7H1J7k/Htk=
132
133Name: org/eclipse/viatra/dse/base/DseEvmRuleBase.class
134SHA-256-Digest: iRILqfjFCMPd020YX8dMyRaNlUGfEUTd4N3gnqQRtDo=
135
136Name: org/eclipse/viatra/dse/objectives/impl/TrajectoryCostSoftObjecti
137 ve.class
138SHA-256-Digest: wXSfFPucpZyh72nGKuKn83N63Orl75XUM9SkzKfFBi4=
139
140Name: org/eclipse/viatra/dse/api/DSETransformationRule.class
141SHA-256-Digest: 01Ngrz/qbLR6j/4z9NxvtD2jHQAHMl698POXw8BSpPY=
142
143Name: org/eclipse/viatra/dse/objectives/impl/ModelQueryType.class
144SHA-256-Digest: SS0yM7NbAU0U4KoA4Tzy4gXKZ2IZaszyaqbtSN4GE74=
145
146Name: org/eclipse/viatra/dse/base/DseConflictResolver.class
147SHA-256-Digest: kLquKehufJSc2fJoUgztO62ucr1UUqfLQpyiFrY8BJc=
148
149Name: org/eclipse/viatra/dse/statecoding/TheStateCoderFactory.class
150SHA-256-Digest: 7tog5/ud60nPTYwPT6HHpHBDeutpFl2KLKXt8GnM3U8=
151
152Name: org/eclipse/viatra/dse/solutionstore/LogSolutionHandler.class
153SHA-256-Digest: cbpeCy8w558CbnhljT2TKalNqWBpKlIsMppr6hWDRpw=
154
155Name: org/eclipse/viatra/dse/designspace/api/TrajectoryInfo.class
156SHA-256-Digest: mXYUokn/RePXJXnfL7O3AZjvwqFkwiLZ0IipQGgdp0A=
157
158Name: org/eclipse/viatra/dse/statecoding/StatecodingDependencyType.cla
159 ss
160SHA-256-Digest: ef+0X9EnYYjpPiRNmjXrElCCaPekh+Wh6yimRTpp15E=
161
162Name: org/eclipse/viatra/dse/objectives/impl/CompositeObjective.class
163SHA-256-Digest: SJiO5Oina3I760xBUDGc4qYp1WrcSG6Yh0+8hQKf69U=
164
165Name: org/eclipse/viatra/dse/objectives/ObjectiveComparatorHelper.clas
166 s
167SHA-256-Digest: +uKjMIfQvBlKY9djJoP5Wd/EBKMkbrdk7shGdZ0rS2M=
168
169Name: org/eclipse/viatra/dse/api/Objectives.class
170SHA-256-Digest: pNQDcSeUV3oOM7aCgscjJwdyysQrMSZCyLhrSWLMUrI=
171
172Name: org/eclipse/viatra/dse/visualizer/DesignSpaceVisualizerOptions.c
173 lass
174SHA-256-Digest: nf/uvPeNaC8Nu9SPhk+sgvSheB/kh+GqsXXHbm7qer0=
175
176Name: org/eclipse/viatra/dse/api/DSEException.class
177SHA-256-Digest: MCUPB2tBDK01enENQDJ+qONxtl+WQyZaJf87iU+NFyU=
178
179Name: org/eclipse/viatra/dse/base/SingletonSetConflictResolver.class
180SHA-256-Digest: bd4gh7UG91EkNSE0JrpAKbHDxv6HYhL7YEq7PZZkRjo=
181
182Name: org/eclipse/viatra/dse/statecoding/IObjectsProvider.class
183SHA-256-Digest: SIcYuklHbTwYjV+gvS1B77Z0CR/2bannTSL77/qm/Gs=
184
185Name: org/eclipse/viatra/dse/statecoding/IncrementalObjectProviderFact
186 ory.class
187SHA-256-Digest: F12xo+nr94L4B1m1w2xmtA7t1TzGin5pFSEqkBmYxC0=
188
189Name: org/eclipse/viatra/dse/api/SolutionTrajectory.class
190SHA-256-Digest: uFjxXsF4khsOwgCsmRPMZbSayZ4qTDtwPGxDBH2lG74=
191
192Name: org/eclipse/viatra/dse/solutionstore/SolutionStore$SimpleSolutio
193 nSaver.class
194SHA-256-Digest: 12aDZULU6fhdXx8a/BvCQwXW7RZfEmIPFueU7GOpBB0=
195
196Name: org/eclipse/viatra/dse/util/Hasher.class
197SHA-256-Digest: 0nFBMPZ6/YudYlnE/l8XiECkWIHBRvkdyi9WUCIaN4c=
198
199Name: org/eclipse/viatra/dse/solutionstore/ISolutionNameProvider.class
200SHA-256-Digest: Ig8utojCZoNY8V37gbZVVJFOX8NZiu2tPsnAIkS1BaU=
201
202Name: org/eclipse/viatra/dse/objectives/IGlobalConstraint.class
203SHA-256-Digest: UvJwqLRVvv444GgELIu/tUGs4eV8cf/Anqh6horECP8=
204
205Name: org/eclipse/viatra/dse/solutionstore/SolutionStore.class
206SHA-256-Digest: V9OJ/9GqLq9cBToiBzapjyCs3mDuk4PkeduT5YpiTwE=
207
208Name: org/eclipse/viatra/dse/objectives/impl/DepthHardObjective.class
209SHA-256-Digest: Ra8i2f1YiRldwF06QotRoHkhKJLyGMYJnS6Lco1ldTM=
210
211Name: org/eclipse/viatra/dse/objectives/impl/BaseObjective.class
212SHA-256-Digest: DH8BIQo1OvBt5oEtS4sqsjtGOhlD1Nwz2yv7gdW3/hA=
213
214Name: org/eclipse/viatra/dse/api/DesignSpaceExplorer$1.class
215SHA-256-Digest: 1AccsshxVCMI2GPkioO7lQtS9JwPx17YrPTSjTZfqBQ=
216
217Name: org/eclipse/viatra/dse/objectives/impl/ConstraintsObjective.clas
218 s
219SHA-256-Digest: +eesnPuyvrf4xQOslHAFlNIyd4K9scCn8f6qprCxKzs=
220
221Name: org/eclipse/viatra/dse/api/strategy/impl/FixedPriorityStrategy.c
222 lass
223SHA-256-Digest: /+Dkno94lswrX5YEr60iH8szAKDL9hfAe2ZZ/amSe20=
224
225Name: org/eclipse/viatra/dse/base/IDseStrategyContext.class
226SHA-256-Digest: ACDjZwH6zo71KF8hXuAvC7NWmGPDv9lJ06U/iAptwEw=
227
228Name: org/eclipse/viatra/dse/statecode/IStateCoder.class
229SHA-256-Digest: L+foclr4t9XV4ltc7aDor4Ngf135J+UvTpTxCcegz9M=
230
231Name: org/eclipse/viatra/dse/objectives/impl/NeverSatisfiedDummyHardOb
232 jective.class
233SHA-256-Digest: KB8QybGLqya7vrKCMnwRdCOaJ/URoTIeR1NVYDNiOB4=
234
235Name: org/eclipse/viatra/dse/objectives/impl/AlwaysSatisfiedDummyHardO
236 bjective.class
237SHA-256-Digest: TzG4kskc7rM96sfpJc6YsSNF7PyE48NJLkUpkkwqsiI=
238
239Name: org/eclipse/viatra/dse/base/DesignSpaceManager.class
240SHA-256-Digest: WlF2FWYiBFQNAW2PsPpPorz64wQBWssTC/73maFotD8=
241
242Name: org/eclipse/viatra/dse/visualizer/IExploreEventHandler.class
243SHA-256-Digest: ZJwhUYNU+L1B88hsbfdIejJVUwhnvBjJSDHugw+RFh0=
244
245Name: META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.pro
246 perties
247SHA-256-Digest: 0JWWPFaIUkYh4BehmajscXzAloPgjeIs0iZSPFC/g1g=
248
249Name: org/eclipse/viatra/dse/statecoding/StatecodingDependency.class
250SHA-256-Digest: AeHJlVqUAUsjBlYumYq/e/WEBNbtlvCk00SG9rHPO88=
251
252Name: org/eclipse/viatra/dse/api/strategy/interfaces/IStrategy.class
253SHA-256-Digest: K5feGvnijYpwPJCOvR4m7ChtC7wX7LhLaau5/SBnFek=
254
255Name: org/eclipse/viatra/dse/visualizer/IDesignSpaceVisualizer.class
256SHA-256-Digest: gF2AAXk6xxQIDqdn56Aeifqmj71pBicLO7VJJoB64bY=
257
258Name: org/eclipse/viatra/dse/solutionstore/SolutionStore$ANumberOfEnou
259 ghSolutions.class
260SHA-256-Digest: qAOxgehQKfKkDSF2W2Gk/cXkDIBsQuN4yJ8Q3eRCnps=
261
262Name: META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.xml
263SHA-256-Digest: /LSOqjjd6+fmn3MHbXK9bGr7k+1GKE3kgzaDoJkgCQQ=
264
265Name: org/eclipse/viatra/dse/base/DseIdPoolHelper$IdProvider.class
266SHA-256-Digest: VRQcpABZNkp3Lgivy9PUraJf04riM1MOZvY64suvo3M=
267
268Name: org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder$2.cla
269 ss
270SHA-256-Digest: NqiG7/1poRDLI2BbRvr2hfHZqH73hfFxBic+4YKHcCM=
271
272Name: org/eclipse/viatra/dse/base/ThreadContext$GetRuleExecutionsImpl.
273 class
274SHA-256-Digest: HGFHcAmOg3O3se9FT4oE4pWZ8EFdyRkkHkBVJZi+hmM=
275
276Name: org/eclipse/viatra/dse/api/strategy/impl/BestFirstStrategy.class
277SHA-256-Digest: qJyc4dMUiLGVoJPrMWQtCI2o2HW5p6Ki5J8Ra6wb/gE=
278
279Name: org/eclipse/viatra/dse/designspace/api/IDesignSpace.class
280SHA-256-Digest: IS5IjYyUCvaHWBvUsPFeGFv65W+YTG7u+iRXp/eDIuM=
281
282Name: org/eclipse/viatra/dse/api/strategy/impl/HillClimbingStrategy.cl
283 ass
284SHA-256-Digest: UfrnKlXVqN8LWbUPSoA5PDiJOT7cnCA46kIXicC5mg0=
285
286Name: org/eclipse/viatra/dse/api/strategy/impl/BestFirstStrategy$Traje
287 ctoryWithFitness.class
288SHA-256-Digest: n3K90JLwOOVAXsrkROhn0ZNogaAKVdcUpXBj8RUMI3c=
289
290Name: org/eclipse/viatra/dse/util/EMFHelper$MetaModelElements.class
291SHA-256-Digest: FjS8V9JksWMjbV9a1dn04gWFH3fctq9HdWSfbMsV5Ck=
292
293Name: org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoderFactor
294 y.class
295SHA-256-Digest: jcBdVzrTpamZrT0pQZHyJJnooB+DKF6ADVS4RRhZGl4=
296
297Name: org/eclipse/viatra/dse/objectives/Fitness.class
298SHA-256-Digest: CJPJnXYS0WMnW4JVW2YO5/vvwKhRkRE7qROa87Ailpg=
299
300Name: org/eclipse/viatra/dse/api/strategy/impl/BreadthFirstStrategy.cl
301 ass
302SHA-256-Digest: 4odjR0x9jzt7Ed/hw6Q+ydZUrQQggqL8y216Lq60azM=
303
304Name: org/eclipse/viatra/dse/api/Strategies.class
305SHA-256-Digest: tURHC++pafgodWMnk4CperJDpZ9m4Do6xHAV37bHUoc=
306
307Name: org/eclipse/viatra/dse/statecoding/StatecodingNode.class
308SHA-256-Digest: 2xM/ShgCBqpV9tgQZPBxzTSPgbT7lcp7auQE14dEEqc=
309
310Name: org/eclipse/viatra/dse/solutionstore/SolutionStore$ISolutionSave
311 r.class
312SHA-256-Digest: nuYmJKeNKfM0a9sAbRpA6Knzqu51hlK011aoAQpTH3Q=
313
314Name: org/eclipse/viatra/dse/statecoding/StatecodingDependencyGraph.cl
315 ass
316SHA-256-Digest: 9ZxUtKP6+hvWqY9l0b+opdginEK1BoksdLqZ+DYViqI=
317
318Name: org/eclipse/viatra/dse/util/EMFHelper.class
319SHA-256-Digest: hpOu0HMuLuiLYUbg0rhdfVG4/ZrlVftoKLmTsRAHW/E=
320
321Name: org/eclipse/viatra/dse/base/DesignSpaceManager$2.class
322SHA-256-Digest: x8i8lLzE/UkaQJya1kGbTlJnB/JFNy5607FLESkMQXA=
323
324Name: org/eclipse/viatra/dse/base/ActivationCodesConflictSet.class
325SHA-256-Digest: 0G/W2cxiS4R9GEpBWovAIEA4brmQ2sTjqi1F7vgS0/c=
326
327Name: org/eclipse/viatra/dse/api/SolutionTrajectory$1.class
328SHA-256-Digest: 7epxs7VJgi7Jmo2pKb22m2OLhOOIu3OHTJrWC8HjEzQ=
329
330Name: org/eclipse/viatra/dse/solutionstore/SolutionStore$IEnoughSoluti
331 ons.class
332SHA-256-Digest: /5Ux9DFOI3UHcG8om2rGzX2k0Yj1lIoeG/tR82P3zpQ=
333
334Name: org/eclipse/viatra/dse/objectives/impl/ConstraintsObjective$Quer
335 yConstraint.class
336SHA-256-Digest: 79pmTnUZbgOHEdGzyj5PIb2eGrd554q3c17LNdbTQxM=
337
338Name: org/eclipse/viatra/dse/objectives/Comparators.class
339SHA-256-Digest: V5MzedIHj3KBEBbR4UNAhqmbqB3sHuk183zxMlKhGD4=
340
341Name: org/eclipse/viatra/dse/statecoding/IObjectsProviderFactory.class
342SHA-256-Digest: VlWdfwyWo39xhvgIF9PedWC+Yv1Q0hYaDBSF7Z+ClSA=
343
344Name: org/eclipse/viatra/dse/base/GlobalContext$ExplorationProcessStat
345 e.class
346SHA-256-Digest: rNnsUlZX7z1yPBoNSfWvoXwKhSAjGUhpBo9CZVJwadw=
347
348Name: org/eclipse/viatra/dse/base/DseIdPoolHelper.class
349SHA-256-Digest: 8wUkapQg0xNS3Vy/Mtv18N9dEB9ev/QiH1tYPzFtBN8=
350
351Name: about.html
352SHA-256-Digest: Qx53vUKBh4ByLG9I8uUS7GH8BTecG5s70WKYlnHc04k=
353
354Name: org/eclipse/viatra/dse/solutionstore/ISolutionFoundHandler.class
355SHA-256-Digest: bjBZdHvq37DxouRprrTxR0l8CWUCY+aw5JtccbEeAJg=
356
357Name: org/eclipse/viatra/dse/designspace/api/DesignSpace.class
358SHA-256-Digest: D51XZw1Z2bCk+PxzX7i8WpE64L9s64FoedEMxM0fSYA=
359
360Name: org/eclipse/viatra/dse/util/ValueComparableEObjectStringMap.clas
361 s
362SHA-256-Digest: VYf9HcY2IbUo2d1K+c2rKIFkxNIRFeEi9zr9s1Inc7o=
363
364Name: org/eclipse/viatra/dse/statecoding/StatecodingNodeType.class
365SHA-256-Digest: VUsDepoiER2/0o3aIE8uX08eOdXzvKBkfXPpPaow5yU=
366
367Name: org/eclipse/viatra/dse/api/strategy/interfaces/IStrategyFactory.
368 class
369SHA-256-Digest: K51RjSOSyMrj86BO/zgmo4kO83HgxKvrEGeOTo5WoVs=
370
371Name: org/eclipse/viatra/dse/base/ActivationCodesConflictSet$Activatio
372 nCodesMultiBiMap.class
373SHA-256-Digest: DEtZHFLUnrSZG5x15o2lTasPd5+ufqWCCQXg+YXGxQA=
374
375Name: org/eclipse/viatra/dse/statecoding/TheStateCoder.class
376SHA-256-Digest: 7iWoLYIXKNGjRgpIHZDuW3i8wBpV5OqO978Fg9WxEK8=
377
378Name: org/eclipse/viatra/dse/objectives/LeveledObjectivesHelper.class
379SHA-256-Digest: HYJ6Z75XEjy3UGBB00bv/GfxdOey+9MpGM5aJuFm5fM=
380
381Name: org/eclipse/viatra/dse/solutionstore/ModelSaverSolutionFoundHand
382 ler.class
383SHA-256-Digest: CmINEWESAe5ynUDWoc8YQQdsmBx1bRLNabbzmoxxsUg=
384
385Name: org/eclipse/viatra/dse/base/DseConflictSet.class
386SHA-256-Digest: boreOAKc8L3ZEts53PUwZiZ4l+8Em3aLeXDQBJZihbY=
387
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.properties b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.properties
new file mode 100644
index 00000000..33746c20
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.properties
@@ -0,0 +1,3 @@
1artifactId=org.eclipse.viatra.dse
2groupId=org.eclipse.viatra
3version=0.24.0-SNAPSHOT
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.xml b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.xml
new file mode 100644
index 00000000..4d50659f
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.xml
@@ -0,0 +1,14 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<project
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
4 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
5 <modelVersion>4.0.0</modelVersion>
6 <parent>
7 <artifactId>org.eclipse.viatra.parent.dse</artifactId>
8 <groupId>org.eclipse.viatra</groupId>
9 <version>0.24.0-SNAPSHOT</version>
10 <relativePath>../../../releng/org.eclipse.viatra.parent.dse/pom.xml</relativePath>
11 </parent>
12 <artifactId>org.eclipse.viatra.dse</artifactId>
13 <packaging>eclipse-plugin</packaging>
14</project> \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/about.html b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/about.html
new file mode 100644
index 00000000..4c69fcc0
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/about.html
@@ -0,0 +1,21 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
2<html>
3<head>
4<title>About</title>
5<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
6</head>
7<body lang="EN-US">
8<h2>About This Content</h2>
9
10<p>March 18, 2019</p>
11<h3>License</h3>
12
13<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
14Eclipse Public License Version 2.0 (&quot;EPL&quot;). A copy of the EPL is available at <a href="http://www.eclipse.org/org/documents/epl-v20.php">http://www.eclipse.org/legal/epl-v20.html</a>.
15For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
16
17<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
18apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
19indicated below, the terms and conditions of the EPL still apply to any source code in the Content and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
20</body>
21</html> \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/build.properties b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/build.properties
new file mode 100644
index 00000000..08373bf1
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/build.properties
@@ -0,0 +1,4 @@
1source.. = src/
2bin.includes = META-INF/,\
3 .,\
4 about.html
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSEException.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSEException.java
new file mode 100644
index 00000000..f0da19ed
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSEException.java
@@ -0,0 +1,47 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api;
10
11/**
12 * Represents a general runtime exception that happened during the execution of the design space exploration process.
13 * Problems that cause this exception are not recoverable within the scope of the design space exploration process.
14 */
15public class DSEException extends RuntimeException {
16
17 private static final long serialVersionUID = -8312212010574763824L;
18
19 /**
20 * @see RuntimeException#RuntimeException()
21 */
22 public DSEException() {
23 super();
24 }
25
26 /**
27 * @see RuntimeException#RuntimeException(String)
28 */
29 public DSEException(String message) {
30 super(message);
31 }
32
33 /**
34 * @see RuntimeException#RuntimeException(String, Throwable)
35 */
36 public DSEException(String message, Throwable cause) {
37 super(message, cause);
38 }
39
40 /**
41 * @see RuntimeException#RuntimeException(Throwable)
42 */
43 public DSEException(Throwable cause) {
44 super(cause);
45 }
46
47}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSETransformationRule.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSETransformationRule.java
new file mode 100644
index 00000000..8c3511ae
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSETransformationRule.java
@@ -0,0 +1,51 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api;
10
11import java.util.Objects;
12import java.util.function.Consumer;
13
14import org.eclipse.viatra.query.runtime.api.IPatternMatch;
15import org.eclipse.viatra.query.runtime.api.IQuerySpecification;
16import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher;
17import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
18
19/**
20 * An instance of this class is a specification of a graph transformation rule on a given metamodel. Such a rule
21 * consists of a left hand side (LHS), which is specified by an {@link IQuerySpecification} and a right hand side (RHS),
22 * which is specified by an {@link Consumer}.
23 *
24 * @author Andras Szabolcs Nagy
25 *
26 * @param <Match>
27 * A VIATRA Query pattern match - left hand side of the rule
28 * @param <Matcher>
29 * A VIATRA Query pattern matcher - left hand side of the rule
30 * @deprecated
31 */
32@Deprecated
33public class DSETransformationRule<Match extends IPatternMatch, Matcher extends ViatraQueryMatcher<Match>> extends
34 BatchTransformationRule<Match, Matcher> {
35
36 public DSETransformationRule(String name, IQuerySpecification<Matcher> querySpec,
37 Consumer<Match> action) {
38 super(name, querySpec, BatchTransformationRule.STATELESS_RULE_LIFECYCLE, action);
39
40 Objects.requireNonNull(name);
41 Objects.requireNonNull(querySpec);
42 Objects.requireNonNull(action);
43
44 }
45
46 public DSETransformationRule(IQuerySpecification<Matcher> querySpec,
47 Consumer<Match> action) {
48 this(querySpec.getFullyQualifiedName(), querySpec, action);
49 }
50
51}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DesignSpaceExplorer.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DesignSpaceExplorer.java
new file mode 100644
index 00000000..9cd6e68a
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DesignSpaceExplorer.java
@@ -0,0 +1,622 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api;
10
11import java.util.Collection;
12import java.util.HashSet;
13import java.util.Set;
14import java.util.Timer;
15import java.util.TimerTask;
16import java.util.concurrent.atomic.AtomicBoolean;
17
18import org.apache.log4j.BasicConfigurator;
19import org.apache.log4j.Level;
20import org.apache.log4j.Logger;
21import org.eclipse.emf.common.notify.Notifier;
22import org.eclipse.emf.ecore.EObject;
23import org.eclipse.emf.ecore.EPackage;
24import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
25import org.eclipse.viatra.dse.base.DesignSpaceManager;
26import org.eclipse.viatra.dse.base.GlobalContext;
27import org.eclipse.viatra.dse.designspace.api.DesignSpace;
28import org.eclipse.viatra.dse.designspace.api.IDesignSpace;
29import org.eclipse.viatra.dse.objectives.IGlobalConstraint;
30import org.eclipse.viatra.dse.objectives.IObjective;
31import org.eclipse.viatra.dse.solutionstore.ISolutionNameProvider;
32import org.eclipse.viatra.dse.solutionstore.IdBasedSolutionNameProvider;
33import org.eclipse.viatra.dse.solutionstore.SolutionStore;
34import org.eclipse.viatra.dse.statecode.IStateCoder;
35import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
36import org.eclipse.viatra.dse.statecoding.simple.SimpleStateCoderFactory;
37import org.eclipse.viatra.dse.visualizer.IDesignSpaceVisualizer;
38import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
39import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver;
40import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
41
42/**
43 * <p>
44 * The {@link DesignSpaceExplorer} is the main API of the <b>Design Space Exploration</b> engine.
45 * </p>
46 *
47 * <p>
48 * To parameterize the algorithm one must use the following methods after instantiating:
49 * <ul>
50 * <li>{@link #setInitialModel(EObject)} or it's overloads to set the starting model.</li>
51 * <li>{@link #addTransformationRule(BatchTransformationRule)} to define the transformations.</li> <li
52 * {@link #addObjective(IObjective)} to define the objective functions. Use the {@link Objectives} helper class for
53 * instantiating built-in, configurable objectives.</li>
54 * <li>{@link #startExploration(IStrategy)} or it's overloads to start an exploration with the given exploration
55 * strategy. Use the {@link Strategies} helper class for instantiating built-in, configurable exploration strategies.
56 * </li>
57 * </ul>
58 * </p>
59 *
60 * <p>
61 * <b>Designs Space Exploration</b> is the process of finding a sequence (or sequences) of predefined transformation
62 * rules ("transitions") that, if applied in order on the starting model, results in a new model state that fulfills the
63 * hard (or goal) constraints and is near optimal with respect to the objectives.
64 * </p>
65 *
66 * <p>
67 * An extension to this paradigm is the introduction of global constraints, which guarantees, that no sequence will be
68 * returned, which if executed, results in an intermediate model state that violates the specified global constraints,
69 * including the final state. You can add constraints by invoking {@link #addGlobalConstraint(IGlobalConstraint)}.
70 * </p>
71 *
72 * @author Andras Szabolcs Nagy & Miklos Foldenyi
73 *
74 */
75public class DesignSpaceExplorer {
76
77 private Notifier model;
78
79 private GlobalContext globalContext = new GlobalContext();
80
81 private final Logger logger = Logger.getLogger(this.getClass());
82
83 private Set<EPackage> metaModelPackages = new HashSet<EPackage>();
84
85 private static final String MODEL_NOT_YET_GIVEN = "The starting model is not given yet. Please call the setInitialModel method first.";
86
87 private boolean deepCopyModel;
88
89 /**
90 * <p>
91 * Creates a {@link DesignSpaceExplorer} object that is able to execute a design space exploration process.
92 * </p>
93 *
94 * <p>
95 * By default the state coder used is the generic (not meta-model specific) {@link GraphHash}. You can provide your
96 * custom state coder by implementing the {@link IStateCoderFactory} and {@link IStateCoder} interfaces, and passing
97 * the former to the {@link #setStateCoderFactory(IStateCoderFactory)} method.
98 *
99 */
100 public DesignSpaceExplorer() {
101 setDesignspace(new DesignSpace());
102 }
103
104 /**
105 * Adds a metamodel in the form of {@link EPackage}, which is needed for certain guidance.
106 *
107 * @param metaModelPackage
108 */
109 public void addMetaModelPackage(EPackage metaModelPackage) {
110 metaModelPackages.add(metaModelPackage);
111 }
112
113 /**
114 * Defines the initial model of the exploration, and whether it is supposed to be used to execute the DSE process or
115 * it should be cloned. Please note, that in multithreaded mode any subsequent threads will be working on cloned
116 * models.
117 *
118 * @param model
119 * The root object of the EMF model.
120 * @param deepCopyModel
121 * If it is set to true, the exploration will run on a cloned model.
122 */
123 public void setInitialModel(Notifier model, boolean deepCopyModel) {
124 this.model = model;
125 this.deepCopyModel = deepCopyModel;
126 }
127
128 /**
129 * Defines the initial model of the exploration. The model will be cloned, which is desired in most cases as the
130 * given model won't be changed.
131 *
132 * @param model
133 * The root object of the EMF model.
134 */
135 public void setInitialModel(Notifier model) {
136 setInitialModel(model, true);
137 }
138
139 /**
140 * Defines the initial model of the exploration. The given model won't be cloned, thus the exploration will modify
141 * it.
142 *
143 * @param model
144 * The root object of the EMF model. It won't be cloned.
145 */
146 public void setInitialModelUncloned(Notifier model) {
147 setInitialModel(model, false);
148 }
149
150 /**
151 * Adds a {@link BatchTransformationRule}.
152 *
153 * @param rule
154 * The transformationRule.
155 */
156 public void addTransformationRule(BatchTransformationRule<?, ?> rule) {
157 Preconditions.checkArgument(rule != null);
158 for (BatchTransformationRule<?, ?> rule2 : globalContext.getTransformations()) {
159 if (rule.getPrecondition().equals(rule2.getPrecondition())) {
160 throw new DSEException(
161 "Two transformation rule ("
162 + rule.getName()
163 + "; "
164 + rule2.getName()
165 + ") uses the same LHS VIATRA Query pattern ("
166 + rule.getPrecondition().getFullyQualifiedName()
167 + "), which may lead to hash collision."
168 + " Please wrap the pattern with an other pattern with the 'find' keyword (or duplicate the code), and use that for one of the rules LHS.");
169 }
170 }
171
172 globalContext.getTransformations().add(rule);
173 }
174
175 /**
176 * Adds a global constraint to the exploration process. Please see the {@link IGlobalConstraint} interface and its
177 * implementations for details.
178 *
179 * @param constraint
180 * The global constraint.
181 * @see IGlobalConstraint
182 */
183 public void addGlobalConstraint(IGlobalConstraint constraint) {
184 globalContext.getGlobalConstraints().add(constraint);
185 }
186
187 /**
188 * Adds an objective the the exploration process. Please see the {@link IObjective} interface and its
189 * implementations for details.
190 *
191 * @param objective
192 * The objective.
193 * @see IObjective
194 */
195 public void addObjective(IObjective objective) {
196 for (IObjective o : globalContext.getObjectives()) {
197 if (o.getName().equals(objective.getName())) {
198 throw new DSEException("Two objectives with the same name cannot be registered:" + o.getName());
199 }
200 }
201 globalContext.getObjectives().add(objective);
202 }
203
204 /**
205 * Sets a {@link IStateCoderFactory} for which will be used for creating {@link IStateCoder}s. The default
206 * implementation is the {@link SimpleStateCoderFactory}, which works well in most of the cases.
207 *
208 * @param stateCoderFactory
209 * The factory.
210 */
211 public final void setStateCoderFactory(IStateCoderFactory stateCoderFactory) {
212 globalContext.setStateCoderFactory(stateCoderFactory);
213 }
214
215 /**
216 * Defines the maximum processing threads that the design space exploration can use. Note, that this is only
217 * limiting the threads doing the actual calculation. By default this value will be set to the number of logical
218 * processors (including HyperThreading) in the computer, reported by {@link Runtime#availableProcessors()}.
219 *
220 * @param maxNumberOfThreads
221 * The number of maximum processing threads available to the design space exploration process.
222 */
223 public void setMaxNumberOfThreads(int maxNumberOfThreads) {
224 globalContext.getThreadPool().setMaximumPoolSize(maxNumberOfThreads);
225 }
226
227 /**
228 * Sets the {@link IDesignSpace} implementation that is to be used during the design space exploration process. By
229 * default, the {@link DesignSpace} implementation is used.
230 *
231 * @param designspace
232 * The {@link IDesignSpace} implementation.
233 */
234 public final void setDesignspace(IDesignSpace designspace) {
235 globalContext.setDesignSpace(designspace);
236 }
237
238 /**
239 * Sets the solution store for strategies. Please see the {@link SolutionStore} for how to configure it.
240 *
241 * @param solutionStore
242 * The parameterized {@link SolutionStore} implementation.
243 */
244 public void setSolutionStore(SolutionStore solutionStore) {
245 globalContext.setSolutionStore(solutionStore);
246 }
247
248 /**
249 * Starts the design space exploration. It returns only when the strategy decides to stop the execution.
250 *
251 * @param strategy
252 * The strategy of the exploration.
253 */
254 public void startExploration(IStrategy strategy) {
255 startExploration(strategy, true, -1);
256 }
257
258 /**
259 * Starts the design space exploration asynchronously. Completion of the process can be verified by calling
260 * {@link DesignSpaceExplorer#isDone()}.
261 *
262 * @param strategy
263 * The strategy of the exploration.
264 */
265 public void startExplorationAsync(IStrategy strategy) {
266 startExploration(strategy, false, -1);
267 }
268
269 /**
270 * Starts the design space exploration with a timeout. It returns only when the strategy decides to stop the
271 * execution or the given timeout is elapsed.
272 *
273 * @param strategy
274 * The strategy of the exploration.
275 * @param timeout
276 * The number of milliseconds before the exploration is forced to stop.
277 * @return Returns true if the exploration stopped by the timeout.
278 */
279 public boolean startExplorationWithTimeout(IStrategy strategy, long timeout) {
280 return startExploration(strategy, true, timeout);
281 }
282
283 /**
284 * Starts the design space exploration asynchronously with a timeout. Completion of the process can be verified by
285 * calling {@link DesignSpaceExplorer#isDone()}.
286 *
287 * @param strategy
288 * The strategy of the exploration.
289 * @param timeout
290 * The number of milliseconds before the exploration is forced to stop.
291 * @return Returns true if the exploration stopped by the timeout.
292 */
293 public boolean startExplorationAsyncWithTimeout(IStrategy strategy, long timeout) {
294 return startExploration(strategy, false, timeout);
295 }
296
297 /**
298 * Starts the design space exploration. If {@code waitForTermination} is true, then it returns only when the
299 * strategy decides to stop the execution or there was a timeout, otherwise when the exploration process is started
300 * it returns immediately. In this case, process completion can be verified by calling
301 * {@link DesignSpaceExplorer#isDone()}.
302 *
303 * @param strategy
304 * The strategy of the exploration.
305 * @param waitForTermination
306 * True if the method must wait for the engine to stop, i.e. whether to start synchronously.
307 * @param timeout
308 * The number of milliseconds before the exploration is forced to stop.
309 * @return Returns true if the exploration stopped by the timeout.
310 */
311 public boolean startExploration(IStrategy strategy, boolean waitForTermination, final long timeout) {
312 initExploration(strategy);
313
314 Timer timer = new Timer();
315 final AtomicBoolean wasTimeout = new AtomicBoolean(false);
316
317 if (timeout > 0) {
318 TimerTask timerTask = new TimerTask() {
319 @Override
320 public void run() {
321 logger.info("Timeout, stopping threads...");
322 globalContext.stopAllThreads();
323 wasTimeout.set(true);
324 }
325 };
326 timer.schedule(timerTask, timeout);
327 }
328
329 if (waitForTermination) {
330 waitForTerminaition();
331 timer.cancel();
332 } else {
333 logger.info("Design space exploration started asynchronously.");
334 }
335
336 return wasTimeout.get();
337
338 }
339
340 private void initExploration(IStrategy strategy) {
341 Preconditions.checkArgument(model != null, MODEL_NOT_YET_GIVEN);
342 Preconditions.checkArgument(strategy != null, "A strategy must be given. Use the Strategies helper class.");
343 Preconditions.checkState(!globalContext.getTransformations().isEmpty(),
344 "At least one transformation rule must be added to start the exploration.");
345
346 if (globalContext.getStateCoderFactory() == null) {
347 if (getMetaModelPackages() == null || getMetaModelPackages().isEmpty()) {
348 throw new DSEException("Cannot initialize state coder."
349 + " Please specifiy the EPackages your model uses with addMetaModelPackage(EPackage)");
350 }
351 globalContext.setStateCoderFactory(new SimpleStateCoderFactory(getMetaModelPackages()));
352 }
353
354 logger.info("DesignSpaceExplorer started exploration.");
355
356 if (deepCopyModel) {
357 globalContext.startFirstThread(strategy, model);
358 } else {
359 globalContext.startFirstThreadWithoutModelClone(strategy, model);
360 }
361 }
362
363 /**
364 * Returns all of the found {@link Solution}s, trajectories. Call it after
365 * {@link DesignSpaceExplorer#startExploration()}. Calling this while the process is running returns the solutions
366 * that have been found <b>so far</b>. The returned {@link Solution} objects may change internal state after they
367 * have been returned, if a shorter trajectory has been found to the referred state.
368 *
369 * @return The found solutions.
370 */
371 public Collection<Solution> getSolutions() {
372 return globalContext.getSolutionStore().getSolutions();
373 }
374
375 /**
376 * Returns an arbitrary solution trajectory or null if the exploration failed to find any.
377 *
378 * @return An arbitrary solution trajectory.
379 */
380 public SolutionTrajectory getArbitrarySolution() {
381 Collection<Solution> solutions = getSolutions();
382 if (solutions.isEmpty()) {
383 return null;
384 }
385 return solutions.iterator().next().getArbitraryTrajectory();
386 }
387
388 /**
389 * Returns the number of distinct states the exploration process has visited so far.
390 *
391 * @return the number of distinct states.
392 */
393 public long getNumberOfStates() {
394 return globalContext.getDesignSpace().getNumberOfStates();
395 }
396
397 /**
398 * Returns the number of distinct transitions the exploration process has discovered (but not necessarily traversed)
399 * so far.
400 *
401 * @return the number of distinct transitions.
402 */
403 public long getNumberOfTransitions() {
404 return globalContext.getDesignSpace().getNumberOfTransitions();
405 }
406
407 /**
408 * Returns the {@link EPackage}s, which were registered with the
409 * {@link DesignSpaceExplorer#addMetaModelPackage(EPackage)} method.
410 *
411 * @return The set of meta model packages.
412 */
413 public Set<EPackage> getMetaModelPackages() {
414 return metaModelPackages;
415 }
416
417 /**
418 * Returns true if the {@link IExplorerThread strategy} decided to stop, and all the threads finished their work.
419 *
420 * @return true if the process has finished, false otherwise.
421 */
422 public boolean isDone() {
423 return globalContext.isDone();
424 }
425
426 /**
427 * Returns the {@link GlobalContext} which holds the configurations such as rule, objectives, etc.
428 *
429 * @return The global context.
430 */
431 public GlobalContext getGlobalContext() {
432 return globalContext;
433 }
434
435 /**
436 * Registers a design space visualizer. Please see the corresponding interface {@link IDesignSpaceVisualizer}.
437 *
438 * @see IDesignSpaceVisualizer
439 *
440 * @param visualizer
441 */
442 public void addDesignSpaceVisulaizer(IDesignSpaceVisualizer visualizer) {
443 globalContext.registerDesignSpaceVisualizer(visualizer);
444 }
445
446 /**
447 * Creates a string containing the state codes of all the found solutions and the found trajectories to these
448 * solutions with fitness values.
449 *
450 * @return A pretty string with the solutions.
451 */
452 public String toStringSolutions() {
453 StringBuilder sb = new StringBuilder();
454 Collection<Solution> solutions = getSolutions();
455 sb.append("Number of solutions: ");
456 sb.append(solutions.size());
457 sb.append("\n");
458 for (Solution solution : solutions) {
459 sb.append("Solution: ");
460 sb.append(solution.getStateCode());
461 sb.append("\n");
462 for (SolutionTrajectory trajectory : solution.getTrajectories()) {
463 sb.append(" ");
464 sb.append(trajectory.toPrettyString());
465 sb.append("\n");
466 }
467 }
468 return sb.toString();
469 }
470
471 /**
472 * A conflict resolver can filter rule activations the DSE engine will see. The primary use of this is symmetry
473 * reduction. This function is subject to change for better API.
474 *
475 * @param conflictResolver
476 */
477 public void setConflictResolver(ConflictResolver conflictResolver) {
478 globalContext.setConflictResolver(conflictResolver);
479 }
480
481 /**
482 * Enumeration for different use cases of logging, including:
483 * <ul>
484 * <li>OFF - no error messages.</li>
485 * <li>WARN - only error and warn messages.</li>
486 * <li>BASIC - logs basic information on how the exploration is going.</li>
487 * <li>VERBOSE_STRATEGY - logs everything the exploration strategy is prepared for.</li>
488 * <li>VERBOSE_FULL - logs every transformation.</li>
489 * </ul>
490 *
491 * @author Andras Szabolcs Nagy
492 *
493 */
494 public enum DseLoggingLevel {
495 OFF, WARN, BASIC, VERBOSE_STRATEGY, VERBOSE_FULL
496 }
497
498 /**
499 * Changes the level of logging. See {@link DseLoggingLevel} for details.
500 *
501 * @param dseLoggingLevel
502 */
503 public static void turnOnLogging(DseLoggingLevel dseLoggingLevel) {
504 switch (dseLoggingLevel) {
505 case OFF:
506 Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.OFF);
507 Logger.getLogger(IStrategy.class).setLevel(Level.OFF);
508 Logger.getLogger(DesignSpaceManager.class).setLevel(Level.OFF);
509 break;
510 case WARN:
511 Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.WARN);
512 Logger.getLogger(IStrategy.class).setLevel(Level.WARN);
513 Logger.getLogger(DesignSpaceManager.class).setLevel(Level.WARN);
514 break;
515 case BASIC:
516 Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.INFO);
517 Logger.getLogger(IStrategy.class).setLevel(Level.INFO);
518 Logger.getLogger(DesignSpaceManager.class).setLevel(Level.WARN);
519 break;
520 case VERBOSE_STRATEGY:
521 Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.DEBUG);
522 Logger.getLogger(IStrategy.class).setLevel(Level.DEBUG);
523 Logger.getLogger(DesignSpaceManager.class).setLevel(Level.WARN);
524 break;
525 case VERBOSE_FULL:
526 Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.DEBUG);
527 Logger.getLogger(IStrategy.class).setLevel(Level.DEBUG);
528 Logger.getLogger(DesignSpaceManager.class).setLevel(Level.DEBUG);
529 break;
530 default:
531 throw new DSEException("Not supported logging level.");
532 }
533 }
534
535 /**
536 * Changes the level of logging. See {@link DseLoggingLevel} for details.
537 *
538 * Also configures a basic console appender for log4j.
539 *
540 * @param dseLoggingLevel
541 */
542 public static void turnOnLoggingWithBasicConfig(DseLoggingLevel dseLoggingLevel) {
543 BasicConfigurator.configure();
544 Logger.getRootLogger().setLevel(Level.WARN);
545 turnOnLogging(dseLoggingLevel);
546 }
547
548 /**
549 * Stops the exploration and waits for termination. It has no effect if the exploration is already terminated or not
550 * even started.
551 */
552 public void stopExploration() {
553 if (globalContext.isDone()) {
554 logger.info("Cannot stop exploration - design space exploration has already finished.");
555 } else if (globalContext.isNotStarted()) {
556 logger.info("Cannot stop exploration - design space exploration has not been started.");
557 } else {
558 globalContext.stopAllThreads();
559 waitForTerminaition();
560 }
561 }
562
563 /**
564 * Stops the exploration asynchronously. It has no effect if the exploration is already terminated or not even
565 * started.
566 */
567 public void stopExplorationAsync() {
568 if (globalContext.isDone()) {
569 logger.info("Cannot stop exploration - design space exploration has already finished.");
570 } else if (globalContext.isNotStarted()) {
571 logger.info("Cannot stop exploration - design space exploration has not been started.");
572 } else {
573 globalContext.stopAllThreads();
574 }
575 }
576
577 /**
578 * Waits for termination.
579 */
580 public void waitForTerminaition() {
581 globalContext.waitForTermination();
582 }
583
584 /**
585 * Serializes all the found solutions by transforming the given initial model.
586 * </p>Files will be named <code>solution[id].xmi</code>.
587 * @param model The initial model.
588 */
589 public void saveModels(Notifier model) {
590 this.saveModels(model, "solution", "xmi");
591 }
592
593 /**
594 * Serializes all the found solutions by transforming the given initial model.
595 * </p>Files will be named <code>solution[id].[extension]</code>.
596 * @param model The initial model.
597 * @param extension The extension of the omitted file.
598 */
599 public void saveModels(Notifier model, String extension) {
600 this.saveModels(model, "solution", extension);
601 }
602
603 /**
604 * Serializes all the found solutions by transforming the given initial model.
605 * </p>Files will be named <code>[fileNamePrefix][id].[extension]</code>.
606 * @param model The initial model.
607 * @param fileNamePrefix The prefix (optionally including a file path) of the omitted file.
608 * @param extension The extension of the omitted file.
609 */
610 public void saveModels(Notifier model, String fileNamePrefix, String extension) {
611 globalContext.getSolutionStore().saveModels(model, new IdBasedSolutionNameProvider(fileNamePrefix, extension));
612 }
613
614 /**
615 * Serializes all the found solutions by transforming the given initial model.
616 * </p>Files will be named using the {@link ISolutionNameProvider}.
617 * @param model The initial model.
618 */
619 public void saveModels(Notifier model, ISolutionNameProvider solutionNameProvider) {
620 globalContext.getSolutionStore().saveModels(model, solutionNameProvider);
621 }
622}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Objectives.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Objectives.java
new file mode 100644
index 00000000..3b375fac
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Objectives.java
@@ -0,0 +1,153 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api;
10
11import org.eclipse.viatra.dse.objectives.impl.CompositeObjective;
12import org.eclipse.viatra.dse.objectives.impl.ConstraintsObjective;
13import org.eclipse.viatra.dse.objectives.impl.AlwaysSatisfiedDummyHardObjective;
14import org.eclipse.viatra.dse.objectives.impl.DepthHardObjective;
15import org.eclipse.viatra.dse.objectives.impl.NeverSatisfiedDummyHardObjective;
16import org.eclipse.viatra.dse.objectives.impl.NoRuleActivationsHardObjective;
17import org.eclipse.viatra.dse.objectives.impl.TrajectoryCostSoftObjective;
18
19/**
20 *
21 * Helper class for creating built-in objectives.
22 *
23 * @author Andras Szabolcs Nagy
24 *
25 */
26public class Objectives {
27
28 private Objectives() {
29 }
30
31 /**
32 * This objective uses VIATRA Queries to calculate fitness and/or goal constraints. Use methods on the returned
33 * objective to configure it.
34 *
35 * @param name
36 * @return The objective.
37 * @see ConstraintsObjective
38 */
39 public static ConstraintsObjective createConstraintsObjective(String name) {
40 return new ConstraintsObjective(name);
41 }
42
43 /**
44 * This objective calculates fitness on the trajectory by adding either fix costs to the rules, or by calculating
45 * custom fitness on activation of rules.
46 *
47 * @param name
48 * @return The objective.
49 * @see TrajectoryCostSoftObjective
50 */
51 public static TrajectoryCostSoftObjective createTrajcetoryCostObjective(String name) {
52 return new TrajectoryCostSoftObjective(name);
53 }
54
55 /**
56 * This objective adds a goal constraint that a solution state should not have any activations.
57 *
58 * @return The objective.
59 * @see NoRuleActivationsHardObjective
60 */
61 public static NoRuleActivationsHardObjective createNoRuleActivationsHardConstraint() {
62 return new NoRuleActivationsHardObjective();
63 }
64
65 /**
66 * This objective adds a goal constraint that a solution state should not have any activations.
67 *
68 * @param name
69 * @return The objective.
70 * @see NoRuleActivationsHardObjective
71 */
72 public static NoRuleActivationsHardObjective createNoRuleActivationsHardConstraint(String name) {
73 return new NoRuleActivationsHardObjective(name);
74 }
75
76 /**
77 * This objective can combine the calculated fitness value of other objectives. Weights are supported.
78 *
79 * @param name
80 * @return The objective.
81 * @see NoRuleActivationsHardObjective
82 */
83 public static CompositeObjective createCompositeObjective(String name) {
84 return new CompositeObjective(name);
85 }
86
87 /**
88 * This hard objective is fulfilled in any circumstances. Use it if all states should be regarded as a valid
89 * solution.
90 *
91 * @return The objective.
92 * @see AlwaysSatisfiedDummyHardObjective
93 */
94 public static AlwaysSatisfiedDummyHardObjective createAlwaysSatisfiedDummyHardObjective() {
95 return new AlwaysSatisfiedDummyHardObjective();
96 }
97
98 /**
99 * This hard objective is fulfilled in any circumstances. Use it if all states should be regarded as a valid
100 * solution.
101 *
102 * @param name
103 * @return The objective.
104 * @see AlwaysSatisfiedDummyHardObjective
105 */
106 public static AlwaysSatisfiedDummyHardObjective createDummyHardObjective(String name) {
107 return new AlwaysSatisfiedDummyHardObjective(name);
108 }
109
110 /**
111 * This hard objective is never fulfilled. Use it if all states should be regarded as an invalid solution.
112 *
113 * @return The objective.
114 * @see AlwaysSatisfiedDummyHardObjective
115 */
116 public static NeverSatisfiedDummyHardObjective createNeverSatisfiedDummyHardObjective() {
117 return new NeverSatisfiedDummyHardObjective();
118 }
119
120 /**
121 * This hard objective is never fulfilled. Use it if all states should be regarded as an invalid solution.
122 *
123 * @return The objective.
124 * @see AlwaysSatisfiedDummyHardObjective
125 */
126 public static NeverSatisfiedDummyHardObjective createNeverSatisfiedDummyHardObjective(String name) {
127 return new NeverSatisfiedDummyHardObjective(name);
128 }
129
130 /**
131 * This hard objective is fulfilled if the length of the trajectory is in the specified interval (inclusive). Use
132 * {@link DepthHardObjective#withMinDepth(int)} and {@link DepthHardObjective#withMaxDepth(int)} to configure.
133 *
134 * @return The objective.
135 * @see DepthHardObjective
136 */
137 public static DepthHardObjective createDepthHardObjective() {
138 return new DepthHardObjective();
139 }
140
141 /**
142 * This hard objective is fulfilled if the length of the trajectory is in the specified interval (inclusive). Use
143 * {@link DepthHardObjective#withMinDepth(int)} and {@link DepthHardObjective#withMaxDepth(int)} to configure.
144 *
145 * @param name
146 * @return The objective.
147 * @see DepthHardObjective
148 */
149 public static DepthHardObjective createDepthHardObjective(String name) {
150 return new DepthHardObjective(name);
151 }
152
153}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Solution.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Solution.java
new file mode 100644
index 00000000..b776db7a
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Solution.java
@@ -0,0 +1,60 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api;
10
11import java.util.Collection;
12import java.util.HashSet;
13import java.util.Iterator;
14import java.util.Set;
15
16public class Solution {
17
18 private Set<SolutionTrajectory> trajectories;
19 private final Object stateId;
20
21 public Solution(Object stateId, SolutionTrajectory trajectory) {
22 this.stateId = stateId;
23 trajectories = new HashSet<>();
24 trajectories.add(trajectory);
25 }
26
27 public void addTrajectory(SolutionTrajectory trajectory) {
28 trajectories.add(trajectory);
29 }
30
31 public SolutionTrajectory getArbitraryTrajectory() {
32 return trajectories.iterator().next();
33 }
34
35 public SolutionTrajectory getShortestTrajectory() {
36 Iterator<SolutionTrajectory> iterator = trajectories.iterator();
37 SolutionTrajectory shortestTrajecotry = iterator.next();
38 int minSize = shortestTrajecotry.getTrajectoryLength();
39
40 while (iterator.hasNext()) {
41 SolutionTrajectory traj = iterator.next();
42 int size = traj.getTrajectoryLength();
43 if (size < minSize) {
44 shortestTrajecotry = traj;
45 minSize = size;
46 }
47 }
48
49 return shortestTrajecotry;
50 }
51
52 public Collection<SolutionTrajectory> getTrajectories() {
53 return trajectories;
54 }
55
56 public Object getStateCode() {
57 return stateId;
58 }
59
60}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/SolutionTrajectory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/SolutionTrajectory.java
new file mode 100644
index 00000000..d1a41065
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/SolutionTrajectory.java
@@ -0,0 +1,338 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api;
10
11import java.lang.reflect.InvocationTargetException;
12import java.util.HashSet;
13import java.util.List;
14import java.util.Objects;
15import java.util.function.Consumer;
16
17import org.eclipse.emf.common.notify.Notifier;
18import org.eclipse.emf.edit.command.ChangeCommand;
19import org.eclipse.emf.edit.domain.EditingDomain;
20import org.eclipse.viatra.dse.base.DseIdPoolHelper;
21import org.eclipse.viatra.dse.designspace.api.IBacktrackListener;
22import org.eclipse.viatra.dse.objectives.Fitness;
23import org.eclipse.viatra.dse.statecode.IStateCoder;
24import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
25import org.eclipse.viatra.dse.util.EMFHelper;
26import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine;
27import org.eclipse.viatra.query.runtime.api.IPatternMatch;
28import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
29import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher;
30import org.eclipse.viatra.query.runtime.emf.EMFScope;
31import org.eclipse.viatra.query.runtime.matchers.ViatraQueryRuntimeException;
32import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
33import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
34
35import com.google.common.util.concurrent.UncheckedExecutionException;
36
37/**
38 * A SolutionTrajectory represents a trajectory (i.e. sequence of transformation
39 * rule applications), which can transform the initial model to a desired state.
40 * An instance of this class holds the the actual rule sequence and the
41 * corresponding activation codes. Furthermore it can be used to perform the
42 * transformation on a given model (if possible).
43 * <p>
44 * It is also possible to undo the transformation if initialized with an editing
45 * domain.
46 * <p>
47 * The instance of this class can be reused for different models.
48 *
49 * @author Andras Szabolcs Nagy
50 *
51 */
52public class SolutionTrajectory {
53
54 private final List<Object> activationCodes;
55 private final List<BatchTransformationRule<?, ?>> transformationRules;
56 private final IStateCoderFactory stateCoderFactory;
57 private Fitness fitness;
58 private Solution solution;
59
60 private ViatraQueryEngine engine;
61 private Notifier model;
62 private EditingDomain editingDomain;
63 private IStateCoder stateCoder;
64 private IBacktrackListener listener;
65
66 private int currentIndex;
67
68 public SolutionTrajectory(final List<Object> activationCodes,
69 final List<BatchTransformationRule<?, ?>> transformationRules, final IStateCoderFactory stateCoderFactory,
70 final IBacktrackListener backtrackListener) {
71 Objects.requireNonNull(transformationRules, "Parameter transformationRules cannot be null!");
72 Objects.requireNonNull(stateCoderFactory, "Parameter stateCoderFactory cannot be null!");
73 Objects.requireNonNull(activationCodes, "Parameter activations cannot be null!");
74 Preconditions.checkState(transformationRules.size() == activationCodes.size(),
75 "The two List parameters must be the same in size.");
76
77 this.activationCodes = activationCodes;
78 this.transformationRules = transformationRules;
79 this.stateCoderFactory = stateCoderFactory;
80 this.listener = backtrackListener;
81 currentIndex = 0;
82 }
83
84 /**
85 * Initialize this SolutionTrajectory for transforming the model along the
86 * trajectory.
87 *
88 * @param model The model.
89 * @throws ViatraQueryRuntimeException If the VIATRA Query fails to initialize.
90 */
91 public void setModel(Notifier model) {
92 editingDomain = null;
93 EMFScope scope = new EMFScope(model);
94 this.engine = ViatraQueryEngine.on(scope);
95 this.model = model;
96 stateCoder = stateCoderFactory.createStateCoder();
97 stateCoder.init(model);
98 currentIndex = 0;
99 DseIdPoolHelper.INSTANCE.disposeByThread();
100 DseIdPoolHelper.INSTANCE.registerRules(rule -> {
101 int id = 0;
102 for (BatchTransformationRule<?, ?> r : transformationRules.subList(0, currentIndex)) {
103 if (r.equals(rule)) {
104 id++;
105 }
106 }
107 return id;
108 }, new HashSet<BatchTransformationRule<?, ?>>(transformationRules));
109 }
110
111 /**
112 * Initialize this SolutionTrajectory for transforming the given model along the
113 * trajectory.
114 * <p>
115 * The transformation will be reversible by creating an {@link EditingDomain} on
116 * the model.
117 *
118 * @param modelRoot The root of the model.
119 * @throws ViatraQueryRuntimeException If the VIATRA Query fails to initialize.
120 */
121 public void setModelWithEditingDomain(Notifier modelRoot) {
122 setModel(modelRoot);
123 editingDomain = EMFHelper.createEditingDomain(model);
124 }
125
126 /**
127 * Transforms the given model along the trajectory.
128 *
129 * @param modelRoot The root of the model.
130 * @throws ViatraQueryRuntimeException If the VIATRA Query fails to initialize.
131 */
132 public void doTransformation(Notifier modelRoot) {
133 setModel(modelRoot);
134 doTransformation();
135 }
136
137 /**
138 * Transforms the given model along the trajectory.
139 * <p>
140 * The transformation will be reversible by creating an {@link EditingDomain} on
141 * the model.
142 *
143 * @param modelRoot The root of the model.
144 * @throws ViatraQueryRuntimeException If the VIATRA Query fails to initialize.
145 */
146 public void doTransformationUndoable(Notifier modelRoot) {
147 setModelWithEditingDomain(modelRoot);
148 doTransformation();
149 }
150
151 /**
152 * Transforms the given model along the trajectory. To initialize the model call
153 * the {@link SolutionTrajectory#setModel(Notifier)} method.
154 *
155 * @throws Exception If the activation to fire is not found.
156 * Possible problems: wrong model, bad state
157 * serializer.
158 * @throws ViatraQueryRuntimeException If the VIATRA Query fails to initialize.
159 */
160 public void doTransformation() {
161 while (doNextTransformation())
162 ;
163 }
164
165 /**
166 * Transforms the given model by one step to the solution (makes one step in the
167 * trajectory). To initialize the model call the
168 * {@link SolutionTrajectory#setModel(Notifier)} method.
169 *
170 * @throws ViatraQueryRuntimeException
171 */
172 public boolean doNextTransformation() {
173 if (currentIndex >= activationCodes.size()) {
174 return false;
175 } else {
176 doNextTransformation(currentIndex);
177 currentIndex++;
178 return true;
179 }
180 }
181
182 @SuppressWarnings("unchecked")
183 private void doNextTransformation(int index) {
184 Objects.requireNonNull(model, "The model cannot be null! Use the setModel method.");
185
186 // cast for the ".process(match)" method.
187 BatchTransformationRule<?, ?> tr = transformationRules.get(index);
188 Object activationCode = activationCodes.get(index);
189
190 ViatraQueryMatcher<?> matcher = tr.getPrecondition().getMatcher(engine);
191
192 boolean isActivationFound = false;
193 for (final IPatternMatch match : matcher.getAllMatches()) {
194 Object matchHash = stateCoder.createActivationCode(match);
195 if (matchHash.equals(activationCode)) {
196 @SuppressWarnings("rawtypes")
197 final Consumer action = tr.getAction();
198
199 if (editingDomain == null) {
200 action.accept(match);
201 } else {
202 ChangeCommand cc = new ChangeCommand(model) {
203 @Override
204 protected void doExecute() {
205 action.accept(match);
206 }
207 };
208 long start = System.nanoTime();
209 editingDomain.getCommandStack().execute(cc);
210 listener.forwardWorked(System.nanoTime() - start);
211 }
212
213 isActivationFound = true;
214 break;
215 }
216 }
217 if (!isActivationFound) {
218 throw new UncheckedExecutionException(
219 "Activation was not found for transformation! Possible cause: wrong model, bad state coder. index: "
220 + index + " Activation code: " + activationCode,
221 null);
222 }
223 }
224
225 /**
226 * Call this method to undo the last transformation.
227 *
228 * @return True, if it was successful.
229 */
230 public boolean undoLastTransformation() {
231 Objects.requireNonNull(editingDomain, "To be able to undo the transformation initialize with editing domain.");
232 long start = System.nanoTime();
233 boolean result;
234
235 if (currentIndex > 0) {
236 try {
237 ((AdvancedViatraQueryEngine) engine).delayUpdatePropagation(() -> {
238 editingDomain.getCommandStack().undo();
239 return null;
240 });
241 } catch (InvocationTargetException e) {
242 throw new RuntimeException(e);
243 }
244 currentIndex--;
245 result = true;
246 }
247 result = false;
248 listener.backtrackWorked(System.nanoTime() - start);
249 return result;
250 }
251
252 /**
253 * Call this method to undo the transformation.
254 */
255 public void undoTransformation() {
256 while (undoLastTransformation())
257 ;
258 }
259
260 public List<Object> getActivationCodes() {
261 return activationCodes;
262 }
263
264 public List<BatchTransformationRule<?, ?>> getTransformationRules() {
265 return transformationRules;
266 }
267
268 public IStateCoderFactory getStateCoderFactory() {
269 return stateCoderFactory;
270 }
271
272 public ViatraQueryEngine getEngine() {
273 return engine;
274 }
275
276 public Notifier getModel() {
277 return model;
278 }
279
280 public IStateCoder getStateCoder() {
281 return stateCoder;
282 }
283
284 public int getCurrentIndex() {
285 return currentIndex;
286 }
287
288 public int getTrajectoryLength() {
289 return activationCodes.size();
290 }
291
292 public Fitness getFitness() {
293 return fitness;
294 }
295
296 public void setFitness(Fitness fitness) {
297 this.fitness = fitness;
298 }
299
300 public String toPrettyString() {
301 StringBuilder sb = new StringBuilder();
302 sb.append("Fitness: ");
303 sb.append(fitness.toString());
304 sb.append(" | Trajectory (");
305 sb.append(activationCodes.size());
306 sb.append("): ");
307 for (Object object : activationCodes) {
308 sb.append(object.toString());
309 sb.append(" | ");
310 }
311 return sb.toString();
312 }
313
314 @Override
315 public int hashCode() {
316 return activationCodes.hashCode();
317 }
318
319 @Override
320 public boolean equals(Object obj) {
321 if (this == obj) {
322 return true;
323 }
324 if (obj instanceof SolutionTrajectory) {
325 SolutionTrajectory that = (SolutionTrajectory) obj;
326 return activationCodes.equals(that.activationCodes);
327 }
328 return false;
329 }
330
331 public Solution getSolution() {
332 return solution;
333 }
334
335 public void setSolution(Solution solution) {
336 this.solution = solution;
337 }
338}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Strategies.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Strategies.java
new file mode 100644
index 00000000..ed7a90da
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Strategies.java
@@ -0,0 +1,123 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api;
10
11import org.eclipse.viatra.dse.api.strategy.impl.BestFirstStrategy;
12import org.eclipse.viatra.dse.api.strategy.impl.BreadthFirstStrategy;
13import org.eclipse.viatra.dse.api.strategy.impl.DepthFirstStrategy;
14import org.eclipse.viatra.dse.api.strategy.impl.FixedPriorityStrategy;
15import org.eclipse.viatra.dse.api.strategy.impl.HillClimbingStrategy;
16import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
17
18/**
19 * Helper class for instantiating strategies. To implement a new strategy use the {@link IStrategy} interface.
20 *
21 * @author Andras Szabolcs Nagy
22 *
23 */
24public final class Strategies {
25
26 private Strategies() {
27 }
28
29 /**
30 * Creates a depth-first search exploration strategy without a depth limit.
31 *
32 * @return The strategy.
33 * @see DepthFirstStrategy
34 */
35 public static DepthFirstStrategy createDfsStrategy() {
36 return new DepthFirstStrategy();
37 }
38
39 /**
40 * Creates a depth-first search exploration strategy with a depth limit. A negative depth limit means no
41 * depth limit, zero means that it will check the initial state.
42 *
43 * @param depthLimit
44 * @return The strategy.
45 * @see DepthFirstStrategy
46 */
47 public static DepthFirstStrategy createDfsStrategy(int depthLimit) {
48 return new DepthFirstStrategy(depthLimit);
49 }
50
51 /**
52 * Creates a fixed priority exploration strategy without a depth limit. It is a depth-first search exploration
53 * strategy but from a current state it only explores the activations with the highest priority. Priorities can be
54 * defined on the strategy itself.
55 *
56 * @return The strategy.
57 * @see FixedPriorityStrategy
58 */
59 public static FixedPriorityStrategy createFixedPriorityStrategy() {
60 return createFixedPriorityStrategy(-1);
61 }
62
63 /**
64 * Creates a fixed priority exploration strategy with a depth limit, where a zero or negative depth limit means no
65 * depth limit. It is a depth-first search exploration strategy but from a current state it only explores the
66 * activations with the highest priority. Priorities can be defined on the strategy itself.
67 *
68 * @param depthLimit
69 * @return The strategy.
70 * @see FixedPriorityStrategy
71 */
72 public static FixedPriorityStrategy createFixedPriorityStrategy(int depthLimit) {
73 return new FixedPriorityStrategy().withDepthLimit(depthLimit);
74 }
75
76 /**
77 * Creates a breadth-first search exploration strategy without a depth limit.
78 *
79 * @return The strategy.
80 * @see BreadthFirstStrategy
81 */
82 public static BreadthFirstStrategy createBfsStrategy() {
83 return new BreadthFirstStrategy();
84 }
85
86 /**
87 * Creates a breadth-first search exploration strategy with a depth limit. A zero or negative depth limit means no
88 * depth limit.
89 *
90 * @param depthLimit
91 * @return The strategy.
92 * @see BreadthFirstStrategy
93 */
94 public static BreadthFirstStrategy createBfsStrategy(int depthLimit) {
95 return new BreadthFirstStrategy(depthLimit);
96 }
97
98 /**
99 * Creates a hill climbing exploration strategy. By default, it explores all neighborhood states and chooses the
100 * best one to continue with until all neighborhood states are dominated by the current state. Other options are
101 * available on the strategy.
102 *
103 * @return The strategy.
104 * @see HillClimbingStrategy
105 */
106 public static HillClimbingStrategy creatHillClimbingStrategy() {
107 return new HillClimbingStrategy();
108 }
109
110 /**
111 * See {@link BestFirstStrategy}.
112 */
113 public static BestFirstStrategy createBestFirstStrategy() {
114 return new BestFirstStrategy();
115 }
116
117 /**
118 * See {@link BestFirstStrategy}.
119 */
120 public static BestFirstStrategy createBestFirstStrategy(int depthLimit) {
121 return new BestFirstStrategy(depthLimit);
122 }
123}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BestFirstStrategy.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BestFirstStrategy.java
new file mode 100644
index 00000000..fe5604a1
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BestFirstStrategy.java
@@ -0,0 +1,228 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.impl;
10
11import java.util.Arrays;
12import java.util.Collection;
13import java.util.Iterator;
14import java.util.PriorityQueue;
15
16import org.apache.log4j.Logger;
17import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
18import org.eclipse.viatra.dse.base.ThreadContext;
19import org.eclipse.viatra.dse.objectives.Fitness;
20import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
21import org.eclipse.viatra.dse.solutionstore.SolutionStore;
22
23/**
24 * This exploration strategy eventually explorers the whole design space but goes in the most promising directions
25 * first, based on the {@link Fitness}.
26 *
27 * There are a few parameter to tune such as
28 * <ul>
29 * <li>maximum depth</li>
30 * <li>continue the exploration from a state that satisfies the hard objectives (the default that it will
31 * backtrack),</li>
32 * <li>whether to continue the exploration from the newly explored state if it is at least equally good than the
33 * previous one or only if it is better (default is "at least equally good").</li>
34 * </ul>
35 *
36 * @author Andras Szabolcs Nagy
37 *
38 */
39public class BestFirstStrategy implements IStrategy {
40
41 private ThreadContext context;
42 private SolutionStore solutionStore;
43
44 private int maxDepth;
45 private boolean isInterrupted = false;
46 private boolean backTrackIfSolution = true;
47 private boolean onlyBetterFirst = false;
48
49 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore;
50 private Logger logger = Logger.getLogger(IStrategy.class);
51
52 private static class TrajectoryWithFitness {
53
54 public Object[] trajectory;
55 public Fitness fitness;
56
57 public TrajectoryWithFitness(Object[] trajectory, Fitness fitness) {
58 super();
59 this.trajectory = trajectory;
60 this.fitness = fitness;
61 }
62
63 @Override
64 public String toString() {
65 return Arrays.toString(trajectory) + fitness.toString();
66 }
67
68 }
69
70 /**
71 * Creates a new best-first search algorithm without depth limit.
72 */
73 public BestFirstStrategy() {
74 this(-1);
75 }
76
77 /**
78 * Creates a new best-first search algorithm with depth limit.
79 *
80 * @param maxDepth
81 * A negative <code>maxDepth</code> means no depth limit, zero means the checking of the initial state.
82 */
83 public BestFirstStrategy(int maxDepth) {
84 if (maxDepth < 0) {
85 this.maxDepth = Integer.MAX_VALUE;
86 } else {
87 this.maxDepth = maxDepth;
88 }
89 }
90
91 public BestFirstStrategy continueIfHardObjectivesFulfilled() {
92 backTrackIfSolution = false;
93 return this;
94 }
95
96 public BestFirstStrategy goOnOnlyIfFitnessIsBetter() {
97 onlyBetterFirst = true;
98 return this;
99 }
100
101 @Override
102 public void initStrategy(ThreadContext context) {
103 this.context = context;
104 this.solutionStore = context.getGlobalContext().getSolutionStore();
105 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
106
107 trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11,
108 (o1, o2) -> objectiveComparatorHelper.compare(o2.fitness, o1.fitness));
109 }
110
111 @Override
112 public void explore() {
113 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
114
115 boolean globalConstraintsAreSatisfied = context.checkGlobalConstraints();
116 if (!globalConstraintsAreSatisfied) {
117 logger.info("Global contraint is not satisifed in the first state. Terminate.");
118 return;
119 }
120
121 final Fitness firstFittness = context.calculateFitness();
122 if (firstFittness.isSatisifiesHardObjectives()) {
123 context.newSolution();
124 logger.info("First state is a solution. Terminate.");
125 return;
126 }
127
128 if (maxDepth == 0) {
129 return;
130 }
131
132 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]);
133 TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness);
134 trajectoiresToExplore.add(currentTrajectoryWithFittness);
135
136 mainLoop: while (!isInterrupted) {
137
138 if (currentTrajectoryWithFittness == null) {
139 if (trajectoiresToExplore.isEmpty()) {
140 logger.debug("State space is fully traversed.");
141 return;
142 } else {
143 currentTrajectoryWithFittness = trajectoiresToExplore.element();
144 if (logger.isDebugEnabled()) {
145 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness);
146 }
147 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory);
148 }
149 }
150
151 Collection<Object> activationIds = context.getUntraversedActivationIds();
152 Iterator<Object> iterator = activationIds.iterator();
153
154 while (!isInterrupted && iterator.hasNext()) {
155 final Object nextActivation = iterator.next();
156 if (!iterator.hasNext()) {
157 logger.debug("Last untraversed activation of the state.");
158 trajectoiresToExplore.remove(currentTrajectoryWithFittness);
159 }
160
161 if (logger.isDebugEnabled()) {
162 logger.debug("Executing new activation: " + nextActivation);
163 }
164 context.executeAcitvationId(nextActivation);
165 if (context.isCurrentStateAlreadyTraversed()) {
166 logger.info("The new state is already visited.");
167 context.backtrack();
168 } else if (!context.checkGlobalConstraints()) {
169 logger.debug("Global contraint is not satisifed.");
170 context.backtrack();
171 } else {
172 final Fitness nextFitness = context.calculateFitness();
173 if (nextFitness.isSatisifiesHardObjectives()) {
174 solutionStore.newSolution(context);
175 logger.debug("Found a solution.");
176 if (backTrackIfSolution) {
177 context.backtrack();
178 continue;
179 }
180 }
181 if (context.getDepth() >= maxDepth) {
182 logger.debug("Reached max depth.");
183 context.backtrack();
184 continue;
185 }
186
187 TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness(
188 context.getTrajectory().toArray(), nextFitness);
189 trajectoiresToExplore.add(nextTrajectoryWithFittness);
190
191 int compare = objectiveComparatorHelper.compare(currentTrajectoryWithFittness.fitness,
192 nextTrajectoryWithFittness.fitness);
193 if (compare < 0) {
194 logger.debug("Better fitness, moving on: " + nextFitness);
195 currentTrajectoryWithFittness = nextTrajectoryWithFittness;
196 continue mainLoop;
197 } else if (compare == 0) {
198 if (onlyBetterFirst) {
199 logger.debug("Equally good fitness, backtrack: " + nextFitness);
200 context.backtrack();
201 continue;
202 } else {
203 logger.debug("Equally good fitness, moving on: " + nextFitness);
204 currentTrajectoryWithFittness = nextTrajectoryWithFittness;
205 continue mainLoop;
206 }
207 } else {
208 logger.debug("Worse fitness.");
209 currentTrajectoryWithFittness = null;
210 continue mainLoop;
211 }
212 }
213 }
214
215 logger.debug("State is fully traversed.");
216 trajectoiresToExplore.remove(currentTrajectoryWithFittness);
217 currentTrajectoryWithFittness = null;
218
219 }
220 logger.info("Interrupted.");
221 }
222
223 @Override
224 public void interruptStrategy() {
225 isInterrupted = true;
226 }
227
228}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BreadthFirstStrategy.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BreadthFirstStrategy.java
new file mode 100644
index 00000000..6b7d9817
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BreadthFirstStrategy.java
@@ -0,0 +1,220 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.impl;
10
11import java.util.Collection;
12import java.util.Iterator;
13import java.util.concurrent.BrokenBarrierException;
14import java.util.concurrent.ConcurrentLinkedQueue;
15import java.util.concurrent.CyclicBarrier;
16import java.util.concurrent.atomic.AtomicBoolean;
17
18import org.apache.log4j.Logger;
19import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
20import org.eclipse.viatra.dse.base.GlobalContext;
21import org.eclipse.viatra.dse.base.ThreadContext;
22import org.eclipse.viatra.dse.objectives.Fitness;
23import org.eclipse.viatra.dse.solutionstore.SolutionStore;
24
25/**
26 * A breadth-first search algorithm implementation, that
27 * <ul>
28 * <li>can work with multiple threads,</li>
29 * <li>indeterministic,</li>
30 * <li>saves all states (trajectories) as solutions that fulfill all the hard objectives,</li>
31 * <li>can have a depth limit,</li>
32 * <li>will backtrack when a model satisfies the hard objectives (after saving it as a solution) and will not explore
33 * beyond that state.</li>
34 * </ul>
35 *
36 * @author Andras Szabolcs Nagy
37 *
38 */
39public class BreadthFirstStrategy implements IStrategy {
40
41 private static final class BfsSharedObject {
42 private final ConcurrentLinkedQueue<Object[]> trajectoryQueue1 = new ConcurrentLinkedQueue<>();
43 private final ConcurrentLinkedQueue<Object[]> trajectoryQueue2 = new ConcurrentLinkedQueue<>();
44
45 private final AtomicBoolean pushToQueue1 = new AtomicBoolean(false);
46 private final AtomicBoolean designSpaceTraversed = new AtomicBoolean(false);
47
48 public final CyclicBarrier barrier;
49
50 public BfsSharedObject(int numberOfThreads) {
51 barrier = new CyclicBarrier(numberOfThreads, () -> {
52 boolean oldValue = pushToQueue1.get();
53 pushToQueue1.set(!oldValue);
54 if (trajectoryQueue1.isEmpty() && trajectoryQueue2.isEmpty()) {
55 designSpaceTraversed.set(true);
56 }
57 });
58 }
59
60 public Object[] poll() {
61 if (pushToQueue1.get()) {
62 return trajectoryQueue2.poll();
63 } else {
64 return trajectoryQueue1.poll();
65 }
66 }
67
68 public void push(Object[] trajectory) {
69 if (pushToQueue1.get()) {
70 trajectoryQueue1.add(trajectory);
71 } else {
72 trajectoryQueue2.add(trajectory);
73 }
74 }
75
76 public boolean isDesignSpaceTraversed() {
77 return designSpaceTraversed.get();
78 }
79 }
80
81 private int maxDepth = 0;
82 private BfsSharedObject shared;
83 private boolean isInterrupted = false;
84 private ThreadContext context;
85 private Logger logger = Logger.getLogger(IStrategy.class);
86 private SolutionStore solutionStore;
87 private boolean isFirstThread = false;
88
89 /**
90 * Creates a new breadth-first search algorithm without depth limit.
91 */
92 public BreadthFirstStrategy() {
93 this.maxDepth = Integer.MAX_VALUE;
94 }
95
96 /**
97 * Creates a new breadth-first search algorithm with depth limit.
98 *
99 * @param maxDepth
100 * A negative <code>maxDepth</code> means no depth limit, zero means the checking of the initial state.
101 */
102 public BreadthFirstStrategy(int maxDepth) {
103 if (maxDepth < 0) {
104 this.maxDepth = Integer.MAX_VALUE;
105 } else {
106 this.maxDepth = maxDepth;
107 }
108 }
109
110 @Override
111 public void initStrategy(ThreadContext context) {
112 this.context = context;
113 this.solutionStore = context.getGlobalContext().getSolutionStore();
114
115 GlobalContext globalContext = context.getGlobalContext();
116 if (globalContext.getSharedObject() == null) {
117 isFirstThread = true;
118 shared = new BfsSharedObject(globalContext.getThreadPool().getMaximumPoolSize());
119 globalContext.setSharedObject(shared);
120 logger.info("Breadth-first exploration strategy is inited.");
121 } else {
122 shared = (BfsSharedObject) globalContext.getSharedObject();
123 }
124 }
125
126 @Override
127 public void explore() {
128
129 if (isFirstThread) {
130
131 boolean globalConstraintsAreSatisfied = context.checkGlobalConstraints();
132 if (!globalConstraintsAreSatisfied) {
133 logger.info("Global contraint is not satisifed in the first state. Terminate.");
134 return;
135 }
136
137 Fitness fitness = context.calculateFitness();
138 if (fitness.isSatisifiesHardObjectives()) {
139 context.newSolution();
140 logger.info("First state is a solution. Terminate.");
141 return;
142 }
143
144 Object[] currentTrajectory = context.getTrajectory().toArray(new Object[0]);
145
146 shared.push(currentTrajectory);
147
148 startThreads();
149 } else {
150 try {
151 shared.barrier.await();
152 } catch (InterruptedException | BrokenBarrierException e) {
153 }
154 }
155
156 mainLoop: while (!isInterrupted && !shared.isDesignSpaceTraversed()) {
157
158 Object[] next = shared.poll();
159 while (next == null) {
160 try {
161 logger.debug("Reached barrier.");
162 shared.barrier.await();
163 } catch (InterruptedException | BrokenBarrierException e1) {
164 }
165 if (isInterrupted || shared.isDesignSpaceTraversed()) {
166 break mainLoop;
167 }
168 next = shared.poll();
169 }
170
171 context.backtrackUntilRoot();
172
173 context.executeTrajectory(next);
174
175 Collection<Object> activationIds = context.getCurrentActivationIds();
176 int i = activationIds.size() - 1;
177
178 while (!isInterrupted && i >= 0) {
179
180 Iterator<Object> iterator = activationIds.iterator();
181 int index = i--;
182 while (iterator.hasNext() && index > 0) {
183 index--;
184 iterator.next();
185 }
186 Object activationIdToTry = iterator.next();
187
188 context.executeAcitvationId(activationIdToTry);
189
190 if (context.isCurrentStateAlreadyTraversed()) {
191 logger.info("The new state is already visited.");
192 } else if (!context.checkGlobalConstraints()) {
193 logger.debug("Global contraint is not satisifed.");
194 } else if (context.calculateFitness().isSatisifiesHardObjectives()) {
195 solutionStore.newSolution(context);
196 logger.debug("Found a solution.");
197 } else if (context.getDepth() >= maxDepth) {
198 logger.debug("Reached max depth.");
199 } else {
200 Object[] currentTrajectory = context.getTrajectory().toArray(new Object[0]);
201 shared.push(currentTrajectory);
202 }
203
204 context.backtrack();
205 }
206
207 }
208 }
209
210 private void startThreads() {
211 context.startAllThreads(() -> new BreadthFirstStrategy(maxDepth));
212 }
213
214 @Override
215 public void interruptStrategy() {
216 isInterrupted = true;
217 shared.barrier.reset();
218 }
219
220}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/DepthFirstStrategy.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/DepthFirstStrategy.java
new file mode 100644
index 00000000..22a4a683
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/DepthFirstStrategy.java
@@ -0,0 +1,188 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.impl;
10
11import java.util.Collection;
12import java.util.Iterator;
13import java.util.Random;
14import java.util.concurrent.atomic.AtomicBoolean;
15
16import org.apache.log4j.Logger;
17import org.eclipse.viatra.dse.api.DSEException;
18import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
19import org.eclipse.viatra.dse.base.ThreadContext;
20import org.eclipse.viatra.dse.objectives.Fitness;
21
22/**
23 * A depth-first search algorithm implementation, that
24 * <ul>
25 * <li>can work with multiple threads,</li>
26 * <li>randomly traverses the search space,</li>
27 * <li>saves all states (trajectories) as solutions that fulfill all the hard objectives,</li>
28 * <li>can have a depth limit,</li>
29 * <li>will backtrack when a model satisfies the hard objectives (after saving it as a solution), which can be modified
30 * by calling {@link #continueIfHardObjectivesFulfilled()}</li>
31 * </ul>
32 *
33 * @author Andras Szabolcs Nagy
34 *
35 */
36public class DepthFirstStrategy implements IStrategy {
37
38 private int maxDepth;
39 private AtomicBoolean isInterrupted = new AtomicBoolean(false);
40 private ThreadContext context;
41
42 private Logger logger = Logger.getLogger(IStrategy.class);
43
44 private Random random = new Random();
45 private boolean backTrackIfSolution = true;
46
47 /**
48 * Creates a new depth-first search algorithm without depth limit.
49 */
50 public DepthFirstStrategy() {
51 this.maxDepth = Integer.MAX_VALUE;
52 }
53
54 /**
55 * Creates a new depth-first search algorithm with depth limit.
56 *
57 * @param maxDepth
58 * A negative <code>maxDepth</code> means no depth limit, zero means the checking of the initial state.
59 */
60 public DepthFirstStrategy(int maxDepth) {
61 if (maxDepth < 0) {
62 this.maxDepth = Integer.MAX_VALUE;
63 } else {
64 this.maxDepth = maxDepth;
65 }
66 }
67
68 /**
69 * If called, the algorithm will not backtrack after the hard objectives are fulfilled, instead it goes deeper in
70 * the search space.
71 */
72 public DepthFirstStrategy continueIfHardObjectivesFulfilled() {
73 backTrackIfSolution = false;
74 return this;
75 }
76
77 @Override
78 public void initStrategy(ThreadContext context) {
79 this.context = context;
80
81 if (context.getSharedObject() == null) {
82 context.setSharedObject(new Object());
83 logger.info("Depth-first exploration strategy is initied.");
84 startThreads();
85 }
86
87 }
88
89 private void startThreads() {
90 context.startAllThreads(() -> new DepthFirstStrategy(maxDepth));
91 }
92
93 @Override
94 public void explore() {
95
96 mainloop: do {
97
98 boolean globalConstraintsAreSatisfied = context.checkGlobalConstraints();
99 if (!globalConstraintsAreSatisfied) {
100 boolean isSuccessfulUndo = context.backtrack();
101 if (!isSuccessfulUndo) {
102 logger.info("Global contraint is not satisifed and cannot backtrack.");
103 break;
104 } else {
105 logger.debug("Global contraint is not satisifed, backtrack.");
106 continue;
107 }
108 }
109
110 Fitness fitness = context.calculateFitness();
111 if (fitness.isSatisifiesHardObjectives()) {
112 context.newSolution();
113 if (backTrackIfSolution) {
114 boolean isSuccessfulUndo = context.backtrack();
115 if (!isSuccessfulUndo) {
116 logger.info("Found a solution but cannot backtrack.");
117 break;
118 } else {
119 logger.debug("Found a solution, backtrack.");
120 continue;
121 }
122 }
123 }
124
125 if (context.getDepth() >= maxDepth) {
126 boolean isSuccessfulUndo = context.backtrack();
127 if (!isSuccessfulUndo) {
128 logger.info("Reached max depth but cannot bactrack.");
129 break;
130 } else {
131 logger.debug("Reached max depth, bactrack.");
132 continue;
133 }
134 }
135
136 if (isInterrupted.get()) {
137 logger.info("Interrupted, stop exploration.");
138 break;
139 }
140
141 Object activationId = null;
142 Collection<Object> activationIds;
143
144 do {
145 activationIds = context.getUntraversedActivationIds();
146 if (activationIds.isEmpty()) {
147 boolean isSuccessfulUndo = context.backtrack();
148 if (!isSuccessfulUndo) {
149 logger.info("No more transitions from current state and cannot backtrack.");
150 break mainloop;
151 } else {
152 logger.debug("No more transitions from current state, backtrack.");
153 continue;
154 }
155 }
156 } while (activationIds.isEmpty());
157
158 int index = random.nextInt(activationIds.size());
159
160 Iterator<Object> iterator = activationIds.iterator();
161 while (index-- > 0) {
162 iterator.next();
163 }
164 activationId = iterator.next();
165
166 context.executeAcitvationId(activationId);
167
168 boolean loopInTrajectory = context.isCurrentStateInTrajectory();
169 if (loopInTrajectory) {
170 boolean isSuccessfulUndo = context.backtrack();
171 if (!isSuccessfulUndo) {
172 throw new DSEException("The new state is present in the trajectoy but cannot bactkrack. Should never happen!");
173 } else {
174 logger.info("The new state is already visited in the trajectory, backtrack.");
175 }
176 }
177
178 } while (true);
179
180 logger.info("Terminated.");
181 }
182
183 @Override
184 public void interruptStrategy() {
185 isInterrupted.set(true);
186 }
187
188}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/FixedPriorityStrategy.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/FixedPriorityStrategy.java
new file mode 100644
index 00000000..4ccda4ce
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/FixedPriorityStrategy.java
@@ -0,0 +1,208 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.impl;
10
11import java.util.Collection;
12import java.util.HashMap;
13import java.util.List;
14import java.util.Map;
15import java.util.Random;
16import java.util.concurrent.atomic.AtomicBoolean;
17
18import org.apache.log4j.Logger;
19import org.eclipse.viatra.dse.api.DSEException;
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.transformation.runtime.emf.rules.batch.BatchTransformationRule;
24
25import com.google.common.collect.Lists;
26
27/**
28 * Works as {@link DepthFirstStrategy} but:
29 * <ul>
30 * <li>works only with single thread,</li>
31 * <li>in a given state, it only traverses the activations with locally the highest priority.</li>
32 * </ul>
33 *
34 * @author Andras Szabolcs Nagy
35 *
36 */
37public class FixedPriorityStrategy implements IStrategy {
38
39 private int maxDepth = Integer.MAX_VALUE;
40 private AtomicBoolean isInterrupted = new AtomicBoolean(false);
41 private ThreadContext context;
42
43 private Logger logger = Logger.getLogger(IStrategy.class);
44 private Map<BatchTransformationRule<?, ?>, Integer> priorities = new HashMap<BatchTransformationRule<?, ?>, Integer>();
45
46 private Random random = new Random();
47 private Map<Object, List<Object>> bestPriorityInState = new HashMap<>();
48
49 /**
50 * Adds a depth limit to the strategy.
51 *
52 * @param depthLimit
53 * The depth limit.
54 * @return The actual instance to enable a builder pattern like usage.
55 */
56 public FixedPriorityStrategy withDepthLimit(int maxDepth) {
57 if (maxDepth < 0) {
58 this.maxDepth = Integer.MAX_VALUE;
59 } else {
60 this.maxDepth = maxDepth;
61 }
62 return this;
63 }
64
65 /**
66 * Assigns a priority to a rule. Unassigned rule will have a priority of 0.
67 *
68 * @param rule
69 * The transformation rule.
70 * @param priority
71 * The priority of the rule. Higher is better.
72 * @return The actual instance to enable a builder pattern like usage.
73 */
74 public FixedPriorityStrategy withRulePriority(BatchTransformationRule<?, ?> rule, int priority) {
75 priorities.put(rule, priority);
76 return this;
77 }
78
79 public Map<BatchTransformationRule<?, ?>, Integer> getPriorities() {
80 return priorities;
81 }
82
83 @Override
84 public void initStrategy(ThreadContext context) {
85 this.context = context;
86
87 logger.info("Fixed priority exploration strategy is initied.");
88 }
89
90 @Override
91 public void explore() {
92
93 mainloop: do {
94
95 boolean globalConstraintsAreSatisfied = context.checkGlobalConstraints();
96 if (!globalConstraintsAreSatisfied) {
97 boolean isSuccessfulUndo = context.backtrack();
98 if (!isSuccessfulUndo) {
99 logger.info("Global contraint is not satisifed and cannot backtrack.");
100 break;
101 } else {
102 logger.debug("Global contraint is not satisifed, backtrack.");
103 continue;
104 }
105 }
106
107 Fitness fitness = context.calculateFitness();
108 if (fitness.isSatisifiesHardObjectives()) {
109 context.newSolution();
110 boolean isSuccessfulUndo = context.backtrack();
111 if (!isSuccessfulUndo) {
112 logger.info("Found a solution but cannot backtrack.");
113 break;
114 } else {
115 logger.debug("Found a solution, backtrack.");
116 continue;
117 }
118 }
119
120 if (context.getDepth() >= maxDepth) {
121 boolean isSuccessfulUndo = context.backtrack();
122 if (!isSuccessfulUndo) {
123 logger.info("Reached max depth but cannot bactrack.");
124 break;
125 } else {
126 logger.debug("Reached max depth, bactrack.");
127 continue;
128 }
129 }
130
131 if (isInterrupted.get()) {
132 logger.info("Interrupted, stop exploration.");
133 break;
134 }
135
136 List<Object> transitions;
137
138 do {
139
140 transitions = bestPriorityInState.get(context.getCurrentStateId());
141
142 if (transitions == null) {
143 Integer bestPriority = getBestPriority(context.getCurrentActivationIds());
144 transitions = Lists.newArrayList();
145 for (Object iTransition : context.getCurrentActivationIds()) {
146 Integer integer = priorities.get(context.getRuleByActivationId(iTransition));
147 if (integer == null) {
148 integer = Integer.valueOf(0);
149 }
150 if (integer.equals(bestPriority)) {
151 transitions.add(iTransition);
152 }
153 }
154 bestPriorityInState.put(context.getCurrentStateId(), transitions);
155 }
156
157 if (transitions.isEmpty()) {
158 boolean isSuccessfulUndo = context.backtrack();
159 if (!isSuccessfulUndo) {
160 logger.info("No more transitions from current state and cannot backtrack.");
161 break mainloop;
162 } else {
163 logger.debug("No more transitions from current state, backtrack.");
164 continue;
165 }
166 }
167 } while (transitions.isEmpty());
168
169 int index = random.nextInt(transitions.size());
170 Object transition = transitions.remove(index);
171
172 context.executeAcitvationId(transition);
173
174 boolean loopInTrajectory = context.isCurrentStateInTrajectory();
175 if (loopInTrajectory) {
176 boolean isSuccessfulUndo = context.backtrack();
177 if (!isSuccessfulUndo) {
178 throw new DSEException(
179 "The new state is present in the trajectoy but cannot bactkrack. Should never happen!");
180 } else {
181 logger.info("The new state is already visited in the trajectory, backtrack.");
182 }
183 }
184
185 } while (true);
186
187 logger.info("Terminated.");
188 }
189
190 @Override
191 public void interruptStrategy() {
192 isInterrupted.set(true);
193 }
194
195 private Integer getBestPriority(Collection<? extends Object> transitions) {
196 Integer bestPriority = Integer.MIN_VALUE;
197 for (Object iTransition : transitions) {
198 Integer priority = priorities.get(context.getRuleByActivationId(iTransition));
199 if (priority == null) {
200 priority = Integer.valueOf(0);
201 }
202 if (priority > bestPriority) {
203 bestPriority = priority;
204 }
205 }
206 return bestPriority;
207 }
208}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/HillClimbingStrategy.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/HillClimbingStrategy.java
new file mode 100644
index 00000000..0ccb0668
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/HillClimbingStrategy.java
@@ -0,0 +1,142 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.impl;
10
11import java.util.ArrayList;
12import java.util.Collection;
13import java.util.Random;
14import java.util.concurrent.atomic.AtomicBoolean;
15
16import org.apache.log4j.Logger;
17import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
18import org.eclipse.viatra.dse.base.ThreadContext;
19import org.eclipse.viatra.dse.objectives.Fitness;
20import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
21import org.eclipse.viatra.dse.objectives.TrajectoryFitness;
22
23public class HillClimbingStrategy implements IStrategy {
24
25 private AtomicBoolean isInterrupted = new AtomicBoolean(false);
26 private ThreadContext context;
27
28 private Logger logger = Logger.getLogger(IStrategy.class);
29
30 private Random random = new Random();
31 private double percentOfOpenedStates;
32 private ObjectiveComparatorHelper objectiveComparatorHelper;
33
34 public HillClimbingStrategy() {
35 this(2);
36 }
37
38 public HillClimbingStrategy(double percentOfOpenedStates) {
39 this.percentOfOpenedStates = percentOfOpenedStates;
40 }
41
42 @Override
43 public void initStrategy(ThreadContext context) {
44 this.context = context;
45 objectiveComparatorHelper = context.getObjectiveComparatorHelper();
46 logger.info("Hill climbing exploration strategy is initied.");
47 }
48
49 @Override
50 public void explore() {
51
52 boolean globalConstraintsAreSatisfied = context.checkGlobalConstraints();
53 if (!globalConstraintsAreSatisfied) {
54 boolean isSuccessfulUndo = context.backtrack();
55 if (!isSuccessfulUndo) {
56 logger.info("Global contraint is not satisifed and cannot backtrack.");
57 return;
58 }
59 }
60
61 mainloop: do {
62
63 Fitness previousFitness = context.calculateFitness();
64
65 logger.debug("Current depth: " + context.getDepth() + " Fitness: " + previousFitness);
66
67 Collection<Object> transitionsFromCurrentState = context.getCurrentActivationIds();
68
69 while (transitionsFromCurrentState.isEmpty()) {
70 logger.debug("No transitions from current state: considered as a solution.");
71 saveSolutionAndBacktrack();
72 continue mainloop;
73 }
74
75 ArrayList<Object> transitionsToTry = new ArrayList<>(transitionsFromCurrentState.size());
76 for (Object transition : transitionsFromCurrentState) {
77 transitionsToTry.add(transition);
78 }
79 double numberOfTransitionsToTry = transitionsToTry.size() * percentOfOpenedStates;
80
81 for (; numberOfTransitionsToTry > 0 && !transitionsToTry.isEmpty(); numberOfTransitionsToTry--) {
82 int index = random.nextInt(transitionsToTry.size());
83 Object transition = transitionsToTry.remove(index);
84
85 context.executeAcitvationId(transition);
86
87 if (!context.checkGlobalConstraints()) {
88 logger.debug("Global contraint is not satisifed, backtrack.");
89 context.backtrack();
90 continue;
91 }
92 if (context.isCurrentStateInTrajectory()) {
93 logger.debug("Current state is in trajectory, backtrack.");
94 context.backtrack();
95 continue;
96 }
97
98 Fitness fitness = context.calculateFitness();
99 objectiveComparatorHelper.addTrajectoryFitness(
100 new TrajectoryFitness(context.getTrajectoryInfo().getLastActivationId(), fitness));
101 context.backtrack();
102 }
103
104 if (objectiveComparatorHelper.getTrajectoryFitnesses().isEmpty()) {
105 logger.debug("No viable transitions from current state: considered as a solution.");
106 saveSolutionAndBacktrack();
107 continue;
108 }
109
110 TrajectoryFitness randomBestFitness = objectiveComparatorHelper.getRandomBest();
111 objectiveComparatorHelper.clearTrajectoryFitnesses();
112
113 int compare = objectiveComparatorHelper.compare(previousFitness, randomBestFitness.fitness);
114
115 if (compare > 0) {
116 saveSolutionAndBacktrack();
117 continue;
118 } else {
119 previousFitness = randomBestFitness.fitness;
120 Object transition = randomBestFitness.trajectory[randomBestFitness.trajectory.length - 1];
121 context.executeAcitvationId(transition);
122 }
123
124 } while (!isInterrupted.get());
125
126 logger.info("Terminated.");
127 }
128
129 private void saveSolutionAndBacktrack() {
130 context.calculateFitness();
131 context.newSolution();
132 logger.debug("Found solution: " + context.getTrajectoryInfo().toString());
133 logger.debug("Backtrack for more solutions, if needed.");
134 context.backtrackUntilRoot();
135 }
136
137 @Override
138 public void interruptStrategy() {
139 isInterrupted.set(true);
140 }
141
142}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/RandomSearchStrategy.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/RandomSearchStrategy.java
new file mode 100644
index 00000000..af8fb8cc
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/RandomSearchStrategy.java
@@ -0,0 +1,163 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.impl;
10
11import java.util.Collection;
12import java.util.Iterator;
13import java.util.Random;
14import java.util.concurrent.atomic.AtomicBoolean;
15import java.util.concurrent.atomic.AtomicInteger;
16
17import org.apache.log4j.Logger;
18import org.eclipse.viatra.dse.api.DSEException;
19import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
20import org.eclipse.viatra.dse.base.GlobalContext;
21import org.eclipse.viatra.dse.base.ThreadContext;
22import org.eclipse.viatra.dse.designspace.api.TrajectoryInfo;
23import org.eclipse.viatra.dse.objectives.Fitness;
24
25public class RandomSearchStrategy implements IStrategy {
26
27 private static class SharedData {
28 public final AtomicInteger triesLeft;
29 public final int minDepth;
30 public final int maxDepth;
31
32 public SharedData(int minDepth, int maxDepth, int numberOfTries) {
33 this.minDepth = minDepth;
34 this.maxDepth = maxDepth;
35 this.triesLeft = new AtomicInteger(numberOfTries);
36 }
37 }
38
39 private int maxDepth = -1;
40 private Random rnd = new Random();
41 private SharedData shared;
42 private TrajectoryInfo trajectoryInfo;
43 int nth;
44 private ThreadContext context;
45 private AtomicBoolean isInterrupted = new AtomicBoolean(false);
46 private Logger logger = Logger.getLogger(IStrategy.class);
47
48 public RandomSearchStrategy(int minDepth, int maxDepth, int numberOfTries) {
49 shared = new SharedData(minDepth, maxDepth, numberOfTries);
50 }
51
52 private RandomSearchStrategy() {
53 }
54
55 @Override
56 public void initStrategy(ThreadContext context) {
57 this.context = context;
58 trajectoryInfo = context.getTrajectoryInfo();
59 GlobalContext gc = context.getGlobalContext();
60
61 Object sharedObject = gc.getSharedObject();
62 if (sharedObject == null) {
63 gc.setSharedObject(shared);
64 logger.info("Random exploration strategy is initied.");
65 startThreads();
66 } else {
67 shared = (SharedData) sharedObject;
68 }
69
70 maxDepth = rnd.nextInt(shared.maxDepth - shared.minDepth) + shared.minDepth;
71
72 }
73
74 @Override
75 public void explore() {
76
77 do {
78
79 boolean globalConstraintsAreSatisfied = context.checkGlobalConstraints();
80 if (!globalConstraintsAreSatisfied) {
81 boolean isSuccessfulUndo = context.backtrack();
82 if (!isSuccessfulUndo) {
83 logger.info("Global contraint is not satisifed and cannot backtrack.");
84 break;
85 } else {
86 logger.debug("Global contraint is not satisifed, backtrack.");
87 continue;
88 }
89 }
90
91 Fitness fitness = context.calculateFitness();
92 if (fitness.isSatisifiesHardObjectives()) {
93 context.newSolution();
94 boolean isSuccessfulUndo = context.backtrack();
95 if (!isSuccessfulUndo) {
96 logger.info("Found a solution but cannot backtrack.");
97 break;
98 } else {
99 logger.debug("Found a solution, backtrack.");
100 continue;
101 }
102 }
103
104 if (trajectoryInfo.getDepth() < maxDepth) {
105
106 Collection<Object> transitions = context.getCurrentActivationIds();
107 int index = rnd.nextInt(transitions.size());
108 Object transition = getByIndex(transitions, index);
109 context.executeAcitvationId(transition);
110
111 } else {
112
113 nth = shared.triesLeft.getAndDecrement();
114 logger.debug(nth + " tries left");
115 if (nth > 0) {
116
117 context.backtrackUntilRoot();
118 maxDepth = rnd.nextInt(shared.maxDepth - shared.minDepth) + shared.minDepth;
119
120 } else {
121 break;
122 }
123 }
124
125 boolean loopInTrajectory = context.isCurrentStateInTrajectory();
126 if (loopInTrajectory) {
127 boolean isSuccessfulUndo = context.backtrack();
128 if (!isSuccessfulUndo) {
129 throw new DSEException(
130 "The new state is present in the trajectoy but cannot bactkrack. Should never happen!");
131 } else {
132 logger.info("The new state is already visited in the trajectory, backtrack.");
133 }
134 }
135
136 } while (isInterrupted.get());
137
138 logger.info("Terminated.");
139 }
140
141 @Override
142 public void interruptStrategy() {
143 isInterrupted.set(true);
144 }
145
146 private void startThreads() {
147 context.startAllThreads(RandomSearchStrategy::new);
148 }
149
150 private static Object getByIndex(Collection<Object> availableTransitions, int index) {
151 int i = 0;
152 Iterator<Object> iterator = availableTransitions.iterator();
153 while (iterator.hasNext()) {
154 Object transition = iterator.next();
155 if (i == index) {
156 return transition;
157 } else {
158 ++i;
159 }
160 }
161 throw new IndexOutOfBoundsException("size: " + availableTransitions.size() + ", index: " + index);
162 }
163}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategy.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategy.java
new file mode 100644
index 00000000..8c164396
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategy.java
@@ -0,0 +1,44 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.interfaces;
10
11import org.eclipse.viatra.dse.base.ThreadContext;
12import org.eclipse.viatra.dse.solutionstore.SolutionStore;
13
14/**
15 * This high level interface is responsible for defining basic operations of an exploration strategy.
16 *
17 * @author Andras Szabolcs Nagy
18 *
19 */
20public interface IStrategy {
21
22 /**
23 * Initializes the strategy with a specific {@link ThreadContext}.
24 *
25 * @param context
26 * The context.
27 */
28 void initStrategy(ThreadContext context);
29
30 /**
31 * This method explores the design space as the implementation specifies. It will be called only once, hence the
32 * exploration loop is run by the implementation. The termination condition is also specified by the implementation
33 * and when it returns the exploration thread will be disposed.
34 */
35 void explore();
36
37 /**
38 * The implementation of this interface should be ready to be interrupted. If this method is called, the
39 * {@link IStrategy#explore()} method should return ASAP.
40 *
41 * This method is also called by the {@link SolutionStore} class if enough solutions are found.
42 */
43 void interruptStrategy();
44}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategyFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategyFactory.java
new file mode 100644
index 00000000..b3352d13
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategyFactory.java
@@ -0,0 +1,13 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.interfaces;
10
11public interface IStrategyFactory {
12 IStrategy createStrategy();
13}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ActivationCodesConflictSet.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ActivationCodesConflictSet.java
new file mode 100644
index 00000000..d3990c23
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ActivationCodesConflictSet.java
@@ -0,0 +1,213 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import java.util.Collection;
12import java.util.HashMap;
13import java.util.HashSet;
14import java.util.Map;
15import java.util.Objects;
16import java.util.Set;
17
18import org.eclipse.viatra.dse.statecode.IStateCoder;
19import org.eclipse.viatra.query.runtime.api.IPatternMatch;
20import org.eclipse.viatra.transformation.evm.api.Activation;
21import org.eclipse.viatra.transformation.evm.api.resolver.ChangeableConflictSet;
22import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver;
23import org.eclipse.viatra.transformation.evm.api.resolver.ConflictSet;
24
25public class ActivationCodesConflictSet implements ChangeableConflictSet {
26
27 private static class ActivationCodesMultiBiMap {
28 public Map<Activation<?>, Object> activationsToCodes = new HashMap<>();
29 public Map<Object, Set<Activation<?>>> codesToActivations = new HashMap<>();
30
31 public void addActivation(Activation<?> activation, Object activationCode) {
32 activationsToCodes.put(activation, activationCode);
33 codesToActivations.computeIfAbsent(activationCode, k -> new HashSet<>()).add(activation);
34 }
35
36 public void removeActivaion(Activation<?> activation) {
37 Object activationCode = activationsToCodes.remove(activation);
38 Set<Activation<?>> activations = codesToActivations.get(activationCode);
39 if (activations != null) {
40 activations.remove(activation);
41 }
42 }
43
44 public void clear() {
45 activationsToCodes.clear();
46 codesToActivations.clear();
47 }
48 }
49
50 protected ActivationCodesMultiBiMap activationCodes;
51 protected IStateCoder stateCoder;
52
53 protected Set<Activation<?>> newActivations = new HashSet<>();
54 protected Set<Activation<?>> removedActivations = new HashSet<>();
55// private Logger logger = Logger.getLogger(getClass());
56
57 private boolean isIncremental = false;
58 private ConflictSet nextActivationsConflictSet;
59
60 public void setIncremental(boolean isIncremental) {
61 this.isIncremental = isIncremental;
62 }
63
64 public ActivationCodesConflictSet(ConflictSet nextActivationsConflictSet, IStateCoder stateCoder) {
65 Objects.requireNonNull(nextActivationsConflictSet);
66 this.nextActivationsConflictSet = nextActivationsConflictSet;
67 this.stateCoder = stateCoder;
68 activationCodes = new ActivationCodesMultiBiMap();
69 }
70
71 private Object createActivationCode(Activation<?> activation) {
72 return stateCoder.createActivationCode((IPatternMatch) activation.getAtom());
73 }
74
75 @Override
76 public boolean removeActivation(Activation<?> activation) {
77 if (isIncremental) {
78//*
79 removedActivations.add(activation);
80 newActivations.remove(activation);
81/*/
82 if(!removedActivations.add(activation)) {
83 logger.debug("Abnormal: already marked to remove: " + activation);
84 } else {
85 logger.debug("marked to remove: " + activation);
86 }
87 if(newActivations.remove(activation)) {
88 logger.debug("Abnormal: removed from new activations: " + activation);
89 }
90//*/
91 }
92 return false;
93 }
94
95 @Override
96 public boolean addActivation(Activation<?> activation) {
97 if (isIncremental) {
98//*
99 newActivations.add(activation);
100 removedActivations.remove(activation);
101 /*/
102 if (activation.isEnabled()) {
103 if (!newActivations.add(activation)) {
104 logger.debug("Abnormal: already added as new: " + activation);
105 } else {
106 logger.debug("activation added: " + activation);
107 }
108 }
109 if(removedActivations.remove(activation)) {
110 logger.debug("Abnormal: was already marked to remove: " + activation);
111 }
112//*/
113 }
114 return false;
115 }
116
117 public Object getActivationId(Activation<?> activation) {
118 return activationCodes.activationsToCodes.get(activation);
119 }
120
121 public Activation<?> getActivation(Object activationId) {
122 Set<Activation<?>> activationsSet = activationCodes.codesToActivations.get(activationId);
123 if (activationsSet == null || activationsSet.isEmpty()) {
124 return null;
125 } else {
126 return activationsSet.iterator().next();
127 }
128 }
129
130 public void updateActivationCodes() {
131// logger.debug("Updating activation codes.");
132
133 if (isIncremental) {
134 for (Activation<?> activation : removedActivations) {
135 activationCodes.removeActivaion(activation);
136// logger.debug("removed activation: " + activationId);
137 }
138
139 for (Activation<?> activation : newActivations) {
140 if (activation.getState().isInactive()) {
141 continue;
142 }
143 Object activationCode = createActivationCode(activation);
144 activationCodes.addActivation(activation, activationCode);
145// logger.debug("new activation: " + activationId);
146// Activation<?> similarActivation = activationIds.inverse().get(activationId);
147// if (similarActivation != null) {
148// logger.debug("Activation " + toStringAct(activation) + " is already present with id: " + activationId);
149// if (similarActivation.isEnabled()) {
150// logger.warn("Duplicate activation code: " + activationId);
151// } else {
152// logger.debug("Force put: " + activationId);
153// }
154// continue;
155// }
156// activationIds.put(activation, activationId);
157 }
158 removedActivations.clear();
159 newActivations.clear();
160 } else {
161 activationCodes.clear();
162 for (Activation<?> activation : nextActivationsConflictSet.getNextActivations()) {
163 Object activationCode = createActivationCode(activation);
164 activationCodes.addActivation(activation, activationCode);
165 }
166 }
167
168
169 }
170
171 protected void reinitWithActivations(ConflictSet nextActivationsConflictSet) {
172 this.nextActivationsConflictSet = nextActivationsConflictSet;
173 activationCodes.clear();
174 for (Activation<?> activation : nextActivationsConflictSet.getNextActivations()) {
175 Object activationCode = createActivationCode(activation);
176 activationCodes.addActivation(activation, activationCode);
177 }
178 }
179
180 @Override
181 public Activation<?> getNextActivation() {
182 throw new UnsupportedOperationException();
183 }
184
185 @Override
186 public Set<Activation<?>> getNextActivations() {
187 throw new UnsupportedOperationException();
188 }
189
190 @Override
191 public Set<Activation<?>> getConflictingActivations() {
192 throw new UnsupportedOperationException();
193 }
194
195 @Override
196 public ConflictResolver getConflictResolver() {
197 throw new UnsupportedOperationException();
198 }
199
200 @Override
201 public String toString() {
202 StringBuilder sb = new StringBuilder();
203 for (Object activationCode : activationCodes.activationsToCodes.values()) {
204 sb.append(activationCode);
205 sb.append(" | ");
206 }
207 return sb.toString();
208 }
209
210 public Collection<Object> getCurrentActivationCodes() {
211 return activationCodes.activationsToCodes.values();
212 }
213}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DesignSpaceManager.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DesignSpaceManager.java
new file mode 100644
index 00000000..4c6b4097
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DesignSpaceManager.java
@@ -0,0 +1,563 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import java.lang.reflect.InvocationTargetException;
12import java.util.ArrayList;
13import java.util.Collection;
14import java.util.HashMap;
15import java.util.Iterator;
16import java.util.List;
17import java.util.Map;
18import java.util.Random;
19
20import org.apache.log4j.Logger;
21import org.eclipse.emf.common.notify.Notifier;
22import org.eclipse.emf.edit.command.ChangeCommand;
23import org.eclipse.emf.edit.domain.EditingDomain;
24import org.eclipse.viatra.dse.api.DSEException;
25import org.eclipse.viatra.dse.api.SolutionTrajectory;
26import org.eclipse.viatra.dse.designspace.api.IBacktrackListener;
27import org.eclipse.viatra.dse.designspace.api.IDesignSpace;
28import org.eclipse.viatra.dse.designspace.api.TrajectoryInfo;
29import org.eclipse.viatra.dse.objectives.ActivationFitnessProcessor;
30import org.eclipse.viatra.dse.statecode.IStateCoder;
31import org.eclipse.viatra.dse.visualizer.IExploreEventHandler;
32import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine;
33import org.eclipse.viatra.query.runtime.api.IPatternMatch;
34import org.eclipse.viatra.transformation.evm.api.Activation;
35import org.eclipse.viatra.transformation.evm.api.Context;
36import org.eclipse.viatra.transformation.evm.api.resolver.ChangeableConflictSet;
37import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
38
39public class DesignSpaceManager implements IBacktrackListener {
40
41 private final IStateCoder stateCoder;
42 private final EditingDomain domain;
43 private Notifier model;
44
45 private IDesignSpace designSpace;
46
47 private final TrajectoryInfo trajectory;
48
49 // the occurence vector callback
50 private List<IExploreEventHandler> handlers;
51
52 // Dummy context for evm
53 private final Context evmContext = Context.create();
54
55 private Logger logger = Logger.getLogger(this.getClass());
56
57 private boolean isNewState = false;
58 private Map<BatchTransformationRule<?, ?>, ActivationFitnessProcessor> activationFitnessProcessors;
59 private Map<BatchTransformationRule<?, ?>, String> activationFitnessProcessorNames;
60 private ThreadContext context;
61
62 private ActivationCodesConflictSet activationCodes;
63 private ChangeableConflictSet conflictSet;
64
65 private AdvancedViatraQueryEngine engine;
66
67 private Random random = new Random();
68
69 private long forwardTime = 0;
70 private long backtrackingTime = 0;
71
72 public DesignSpaceManager(ThreadContext context) {
73
74 this.context = context;
75 model = context.getModel();
76 designSpace = context.getGlobalContext().getDesignSpace();
77 domain = context.getEditingDomain();
78
79 conflictSet = context.getConflictResolver().getLastCreatedConflictSet();
80
81 stateCoder = context.getStateCoder();
82 Object initialStateId = stateCoder.createStateCode();
83 designSpace.addState(null, null, initialStateId);
84
85 activationCodes = context.getActivationCodesConflictSet();
86
87 engine = (AdvancedViatraQueryEngine) context.getQueryEngine();
88
89 this.trajectory = new TrajectoryInfo(initialStateId);
90
91 logger.debug("DesignSpaceManager initialized with initial model: " + initialStateId);
92 }
93
94 public void fireActivation(final Object transition) {
95 if (fireActivationSilent(transition)) {
96 return;
97 }
98
99 StringBuilder sb = new StringBuilder();
100 sb.append(
101 "A retrieved Transition SHOULD have a matching Activation. Possible causes: the state serializer is faulty; the algorithm choosed a wrong Transition.");
102 sb.append("\nSought transition: ");
103 sb.append(transition);
104 Object currentStateId = getCurrentState();
105 sb.append("\nCurrent known state: ");
106 sb.append(currentStateId);
107 Object actualStateId = stateCoder.createStateCode();
108 sb.append("\nActual state: ");
109 sb.append((actualStateId.equals(currentStateId) ? "same as current" : actualStateId));
110 sb.append("\n");
111 sb.append(trajectory);
112 sb.append("\nAvailable transitions:");
113 for (Activation<?> act : conflictSet.getNextActivations()) {
114 IPatternMatch match = (IPatternMatch) act.getAtom();
115 Object code = generateMatchCode(match);
116 sb.append("\n\t");
117 sb.append(code);
118 }
119
120 throw new DSEException(sb.toString());
121 }
122
123 public boolean tryFireActivation(final Object transition) {
124 return fireActivationSilent(transition);
125 }
126
127 private boolean fireActivationSilent(final Object transition) {
128 final Activation<?> activation = getActivationById(transition);
129
130 if (activation == null) {
131 return false;
132 }
133
134 BatchTransformationRule<?, ?> rule = getRuleByActivation(activation);
135
136 Map<String, Double> measureCosts = new HashMap<String, Double>();
137 if (activationFitnessProcessors != null && activationFitnessProcessors.containsKey(rule)) {
138 IPatternMatch match = (IPatternMatch) activation.getAtom();
139 ActivationFitnessProcessor processor = activationFitnessProcessors.get(rule);
140 double fitness = processor.process(match);
141 measureCosts.put(activationFitnessProcessorNames.get(rule), fitness);
142 }
143
144 ChangeCommand rc = new ChangeCommand(model) {
145 @Override
146 protected void doExecute() {
147 activation.fire(evmContext);
148 }
149 };
150
151 Object previousState = trajectory.getCurrentStateId();
152
153 long start = System.nanoTime();
154 domain.getCommandStack().execute(rc);
155 forwardTime += System.nanoTime() - start;
156
157 Object newStateId = stateCoder.createStateCode();
158 updateActivationCodes();
159
160 if (designSpace != null) {
161 isNewState = !designSpace.isTraversed(newStateId);
162 designSpace.addState(previousState, transition, newStateId);
163 }
164
165 trajectory.addStep(transition, rule, newStateId, measureCosts);
166
167 if (handlers != null) {
168 for (IExploreEventHandler iExploreEventHandler : handlers) {
169 iExploreEventHandler.transitionFired(transition);
170 }
171 }
172
173 logger.debug("Executed activation: " + transition);/*
174 * + " from state: " + previousState + " to " + newStateId);
175 */
176
177 return true;
178 }
179
180 public boolean executeRandomActivationId() {
181 Collection<Object> transitions = getTransitionsFromCurrentState();
182 int size = transitions.size();
183 if (size == 0) {
184 return false;
185 }
186
187 int index = random.nextInt(size);
188 Iterator<Object> iterator = transitions.iterator();
189 for (int i = 0; i < index; ++i) {
190 iterator.next();
191 }
192 Object transition = iterator.next();
193
194 fireActivation(transition);
195 return true;
196 }
197
198 public int executeTrajectory(Object[] trajectoryToExecute) {
199 return executeTrajectory(trajectoryToExecute, 0, trajectoryToExecute.length, false, true);
200 }
201
202 public int executeTrajectory(Object[] trajectoryToExecute, int fromIncludedIndex, int toExcludedIndex) {
203 return executeTrajectory(trajectoryToExecute, fromIncludedIndex, toExcludedIndex, false, true);
204 }
205
206 public int executeTrajectoryByTrying(Object[] trajectoryToExecute) {
207 return executeTrajectory(trajectoryToExecute, 0, trajectoryToExecute.length, true, true);
208 }
209
210 public int executeTrajectoryByTrying(Object[] trajectoryToExecute, int fromIncludedIndex, int toExcludedIndex) {
211 return executeTrajectory(trajectoryToExecute, fromIncludedIndex, toExcludedIndex, true, true);
212 }
213
214 public int executeTrajectoryWithoutStateCoding(Object[] trajectoryToExecute) {
215 return executeTrajectory(trajectoryToExecute, 0, trajectoryToExecute.length, false, false);
216 }
217
218 public int executeTrajectoryWithoutStateCoding(Object[] trajectoryToExecute, int fromIncludedIndex,
219 int toExcludedIndex) {
220 return executeTrajectory(trajectoryToExecute, fromIncludedIndex, toExcludedIndex, false, false);
221 }
222
223 public int executeTrajectoryByTryingWithoutStateCoding(Object[] trajectoryToExecute) {
224 return executeTrajectory(trajectoryToExecute, 0, trajectoryToExecute.length, true, false);
225 }
226
227 public int executeTrajectoryByTryingWithoutStateCoding(Object[] trajectoryToExecute, int fromIncludedIndex,
228 int toExcludedIndex) {
229 return executeTrajectory(trajectoryToExecute, fromIncludedIndex, toExcludedIndex, true, false);
230 }
231
232 private int executeTrajectory(Object[] trajectoryToExecute, int fromIncludedIndex, int toExcludedIndex,
233 boolean tryAllActivations, boolean createStateCode) {
234 logger.debug("Executing trajectory.");
235 int unsuccesfulIndex = -1;
236 if (tryAllActivations) {
237 unsuccesfulIndex = 0;
238 }
239 for (int i = fromIncludedIndex; i < toExcludedIndex; i++) {
240 Object activationId = trajectoryToExecute[i];
241 final Activation<?> activation = getActivationById(activationId);
242
243 if (activation == null) {
244 logger.debug("Couldn't execute activation: " + activationId);
245 if (tryAllActivations) {
246 unsuccesfulIndex++;
247 continue;
248 } else {
249 unsuccesfulIndex = i;
250 logger.debug("Trajectory execution stopped at index " + i + "/" + trajectoryToExecute.length);
251 break;
252 }
253 }
254
255 BatchTransformationRule<?, ?> rule = getRuleByActivation(activation);
256
257 Map<String, Double> measureCosts = new HashMap<String, Double>();
258 if (activationFitnessProcessors != null && activationFitnessProcessors.containsKey(rule)) {
259 IPatternMatch match = (IPatternMatch) activation.getAtom();
260 ActivationFitnessProcessor processor = activationFitnessProcessors.get(rule);
261 double fitness = processor.process(match);
262 measureCosts.put(activationFitnessProcessorNames.get(rule), fitness);
263 }
264
265 ChangeCommand rc = new ChangeCommand(model) {
266 @Override
267 protected void doExecute() {
268 activation.fire(evmContext);
269 }
270 };
271
272 long start = System.nanoTime();
273 domain.getCommandStack().execute(rc);
274 forwardTime += System.nanoTime() - start;
275
276 Object newStateId = null;
277 if (createStateCode) {
278 newStateId = stateCoder.createStateCode();
279 }
280 updateActivationCodes();
281
282 trajectory.addStep(activationId, rule, newStateId, measureCosts);
283
284 logger.debug("Activation executed: " + activationId);
285 }
286 if (!createStateCode) {
287 trajectory.modifyLastStateCode(stateCoder.createStateCode());
288 }
289 logger.debug("Trajectory execution finished.");
290 return unsuccesfulIndex;
291
292 }
293
294 public Object getTransitionByActivation(Activation<?> activation) {
295 return activationCodes.getActivationId(activation);
296 }
297
298 public Activation<?> getActivationById(Object activationId) {
299 return activationCodes.getActivation(activationId);
300 }
301
302 public BatchTransformationRule<?, ?> getRuleByActivation(Activation<?> activation) {
303 return context.getGlobalContext().getSpecificationRuleMap().get(activation.getInstance().getSpecification());
304 }
305
306 public BatchTransformationRule<?, ?> getRuleByActivationId(Object activationId) {
307 return getRuleByActivation(getActivationById(activationId));
308 }
309
310 /**
311 * Returns true if the given state is not owned by this crawler.
312 *
313 **/
314 public boolean isNewModelStateAlreadyTraversed() {
315 return !isNewState;
316 }
317
318 public List<Object> getTrajectoryFromRoot() {
319 return trajectory.getTrajectory();
320 }
321
322 public Collection<Object> getTransitionsFromCurrentState() {
323 return activationCodes.getCurrentActivationCodes();
324 }
325
326 public Collection<Object> getUntraversedTransitionsFromCurrentState() {
327 if (designSpace == null) {
328 throw new DSEException("Unsupported without a design space");
329 }
330 Object currentState = trajectory.getCurrentStateId();
331 Collection<Object> traversedIds = designSpace.getActivationIds(currentState);
332
333 List<Object> untraversedTransitions = new ArrayList<>();
334 for (Object activationId : activationCodes.getCurrentActivationCodes()) {
335 if (!traversedIds.contains(activationId)) {
336 untraversedTransitions.add(activationId);
337 }
338 }
339
340 return untraversedTransitions;
341 }
342
343 public boolean undoLastTransformation() {
344
345 if (!trajectory.canStepBack()) {
346 return false;
347 }
348
349 long start = System.nanoTime();
350 try {
351 engine.delayUpdatePropagation(() -> {
352 domain.getCommandStack().undo();
353 return null;
354 });
355 } catch (InvocationTargetException e) {
356 throw new RuntimeException(e);
357 }
358 updateActivationCodes();
359
360 Object lastActivationId = trajectory.getLastActivationId();
361
362 trajectory.backtrack();
363
364 if (handlers != null) {
365 for (IExploreEventHandler iExploreEventHandler : handlers) {
366 iExploreEventHandler.undo(lastActivationId);
367 }
368 }
369
370 logger.debug("Backtrack.");
371 backtrackingTime += System.nanoTime() - start;
372
373 return true;
374 }
375
376 public void backtrackXTimes(int steps) {
377 long start = System.nanoTime();
378 try {
379 engine.delayUpdatePropagation(() -> {
380 for (int i = steps; i > 0; i--) {
381 domain.getCommandStack().undo();
382 trajectory.backtrack();
383 }
384 return null;
385 });
386 } catch (InvocationTargetException e) {
387 throw new RuntimeException(e);
388 }
389 backtrackingTime += System.nanoTime() - start;
390 updateActivationCodes();
391 logger.debug("Backtracked " + steps + " times.");
392 }
393
394 public int backtrackUntilLastCommonActivation(Object[] newTrajectory) {
395 long start = System.nanoTime();
396 Iterator<Object> currentTrajectoryIterator = trajectory.getTrajectory().iterator();
397 if (!currentTrajectoryIterator.hasNext()) {
398 return 0;
399 }
400 int indexOfLastCommonActivation = 0;
401 for (Object activationCode : newTrajectory) {
402 if (currentTrajectoryIterator.hasNext()) {
403 Object activationCodeFromCurrent = currentTrajectoryIterator.next();
404 if (activationCodeFromCurrent.equals(activationCode)) {
405 indexOfLastCommonActivation++;
406 } else {
407 break;
408 }
409 } else {
410 // current trajectory is smaller
411 break;
412 }
413 }
414 int numberOfBacktracks = trajectory.getDepth() - indexOfLastCommonActivation;
415 if (numberOfBacktracks > 0) {
416 try {
417 engine.delayUpdatePropagation(() -> {
418 for (int i = numberOfBacktracks; i > 0; i--) {
419 domain.getCommandStack().undo();
420 trajectory.backtrack();
421 }
422 return null;
423 });
424 } catch (InvocationTargetException e) {
425 throw new RuntimeException(e);
426 }
427 }
428 backtrackingTime += System.nanoTime() - start;
429 updateActivationCodes();
430 logger.debug("Backtracked " + numberOfBacktracks + " times.");
431 return indexOfLastCommonActivation;
432 }
433
434 public void executeTrajectoryWithMinimalBacktrack(Object[] trajectory) {
435 executeTrajectoryWithMinimalBacktrack(trajectory, trajectory.length);
436 }
437
438 public void executeTrajectoryWithMinimalBacktrack(Object[] trajectory, int toExcludedIndex) {
439 int fromIndex = backtrackUntilLastCommonActivation(trajectory);
440 executeTrajectory(trajectory, fromIndex, toExcludedIndex, false, true);
441 }
442
443 public void executeTrajectoryWithMinimalBacktrackWithoutStateCoding(Object[] trajectory) {
444 executeTrajectoryWithMinimalBacktrackWithoutStateCoding(trajectory, trajectory.length);
445 }
446
447 public void executeTrajectoryWithMinimalBacktrackWithoutStateCoding(Object[] trajectory, int toExcludedIndex) {
448 int fromIndex = backtrackUntilLastCommonActivation(trajectory);
449 executeTrajectory(trajectory, fromIndex, toExcludedIndex, false, false);
450 Object stateCode = stateCoder.createStateCode();
451 this.trajectory.modifyLastStateCode(stateCode);
452 }
453
454 public void undoUntilRoot() {
455 long start = System.nanoTime();
456 try {
457 engine.delayUpdatePropagation(() -> {
458 while (trajectory.canStepBack()) {
459 domain.getCommandStack().undo();
460 trajectory.backtrack();
461 }
462 return null;
463 });
464 } catch (InvocationTargetException e) {
465 throw new RuntimeException(e);
466 }
467 backtrackingTime += System.nanoTime() - start;
468 updateActivationCodes();
469 logger.debug("Backtracked to root.");
470 }
471
472 private Object generateMatchCode(IPatternMatch match) {
473 return stateCoder.createActivationCode(match);
474 }
475
476 public Object getCurrentState() {
477 return trajectory.getCurrentStateId();
478 }
479
480 public SolutionTrajectory createSolutionTrajectroy() {
481 return trajectory.createSolutionTrajectory(context.getGlobalContext().getStateCoderFactory(), this);
482 }
483
484 public TrajectoryInfo getTrajectoryInfo() {
485 return trajectory;
486 }
487
488 public void setDesignSpace(IDesignSpace designSpace) {
489 this.designSpace = designSpace;
490 }
491
492 public IDesignSpace getDesignSpace() {
493 return designSpace;
494 }
495
496 public void registerExploreEventHandler(IExploreEventHandler handler) {
497 if (handler == null) {
498 return;
499 }
500 if (handlers == null) {
501 handlers = new ArrayList<IExploreEventHandler>();
502 }
503 handlers.add(handler);
504 }
505
506 public void deregisterExploreEventHandler(IExploreEventHandler handler) {
507 if (handler == null) {
508 return;
509 }
510 if (handlers != null) {
511 handlers.remove(handler);
512 }
513 }
514
515 public void registerActivationCostProcessor(String name, BatchTransformationRule<?, ?> rule,
516 ActivationFitnessProcessor activationFitnessProcessor) {
517 if (activationFitnessProcessors == null || activationFitnessProcessorNames == null) {
518 activationFitnessProcessors = new HashMap<BatchTransformationRule<?, ?>, ActivationFitnessProcessor>();
519 activationFitnessProcessorNames = new HashMap<BatchTransformationRule<?, ?>, String>();
520 }
521 activationFitnessProcessors.put(rule, activationFitnessProcessor);
522 activationFitnessProcessorNames.put(rule, name);
523 }
524
525 public boolean isCurentStateInTrajectory() {
526 Object currentStateId = trajectory.getCurrentStateId();
527 List<Object> stateTrajectory = trajectory.getStateTrajectory();
528 int size = stateTrajectory.size();
529 for (int i = 0; i < size - 1; i++) {
530 Object stateId = stateTrajectory.get(i);
531 if (currentStateId.equals(stateId)) {
532 return true;
533 }
534 }
535 return false;
536 }
537
538 public IStateCoder getStateCoder() {
539 return stateCoder;
540 }
541
542 private void updateActivationCodes() {
543 activationCodes.updateActivationCodes();
544 }
545
546 public long getForwardTime() {
547 return forwardTime;
548 }
549
550 public long getBacktrackingTime() {
551 return backtrackingTime;
552 }
553
554 @Override
555 public void forwardWorked(long nanos) {
556 forwardTime += nanos;
557 }
558
559 @Override
560 public void backtrackWorked(long nanos) {
561 backtrackingTime += nanos;
562 }
563}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictResolver.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictResolver.java
new file mode 100644
index 00000000..35504b56
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictResolver.java
@@ -0,0 +1,35 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import org.eclipse.viatra.dse.statecode.IStateCoder;
12import org.eclipse.viatra.transformation.evm.api.resolver.ChangeableConflictSet;
13import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver;
14
15public class DseConflictResolver implements ConflictResolver {
16
17 private ConflictResolver activationOrderingconflictResolver;
18 private IStateCoder stateCoder;
19 private DseConflictSet lastCreatedConflictSet;
20
21 public DseConflictResolver(ConflictResolver activationOrderingConflictResolver, IStateCoder stateCoder) {
22 this.activationOrderingconflictResolver = activationOrderingConflictResolver;
23 this.stateCoder = stateCoder;
24 }
25
26 @Override
27 public ChangeableConflictSet createConflictSet() {
28 lastCreatedConflictSet = new DseConflictSet(this, activationOrderingconflictResolver, stateCoder);
29 return lastCreatedConflictSet;
30 }
31
32 public DseConflictSet getLastCreatedConflictSet() {
33 return lastCreatedConflictSet;
34 }
35}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictSet.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictSet.java
new file mode 100644
index 00000000..cba595f4
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictSet.java
@@ -0,0 +1,83 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import java.util.Set;
12
13import org.eclipse.viatra.dse.statecode.IStateCoder;
14import org.eclipse.viatra.transformation.evm.api.Activation;
15import org.eclipse.viatra.transformation.evm.api.resolver.ChangeableConflictSet;
16import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver;
17
18public class DseConflictSet implements ChangeableConflictSet {
19
20 private ActivationCodesConflictSet activationCodesConflictSet;
21 private ChangeableConflictSet activationOrderingConflictSet;
22 private ChangeableConflictSet prevActivationOrderingConflictSet;
23 private ConflictResolver resolver;
24
25 public DseConflictSet(ConflictResolver resolver, ConflictResolver activationOrderingConflictResolver,
26 IStateCoder stateCoder) {
27 this.resolver = resolver;
28 activationOrderingConflictSet = activationOrderingConflictResolver.createConflictSet();
29 activationCodesConflictSet = new ActivationCodesConflictSet(activationOrderingConflictSet, stateCoder);
30 }
31
32 @Override
33 public Activation<?> getNextActivation() {
34 return activationOrderingConflictSet.getNextActivation();
35 }
36
37 @Override
38 public Set<Activation<?>> getNextActivations() {
39 return activationOrderingConflictSet.getNextActivations();
40 }
41
42 @Override
43 public Set<Activation<?>> getConflictingActivations() {
44 return activationOrderingConflictSet.getConflictingActivations();
45 }
46
47 @Override
48 public ConflictResolver getConflictResolver() {
49 return resolver;
50 }
51
52 @Override
53 public boolean addActivation(Activation<?> activation) {
54 activationCodesConflictSet.addActivation(activation);
55 return activationOrderingConflictSet.addActivation(activation);
56 }
57
58 @Override
59 public boolean removeActivation(Activation<?> activation) {
60 activationCodesConflictSet.removeActivation(activation);
61 return activationOrderingConflictSet.removeActivation(activation);
62 }
63
64 public ActivationCodesConflictSet getActivationCodesConflictSet() {
65 return activationCodesConflictSet;
66 }
67
68 public void changeActivationOrderingConflictSet(ChangeableConflictSet newActivationOrderingConflictSet) {
69 for (Activation<?> activation : activationOrderingConflictSet.getConflictingActivations()) {
70 newActivationOrderingConflictSet.addActivation(activation);
71 }
72 activationCodesConflictSet.reinitWithActivations(newActivationOrderingConflictSet);
73 ChangeableConflictSet tmp = activationOrderingConflictSet;
74 activationOrderingConflictSet = newActivationOrderingConflictSet;
75 prevActivationOrderingConflictSet = tmp;
76 }
77
78 public void changeActivationOrderingConflictSetBack() {
79 ChangeableConflictSet newActivationOrderingConflictSet =
80 prevActivationOrderingConflictSet.getConflictResolver().createConflictSet();
81 changeActivationOrderingConflictSet(newActivationOrderingConflictSet);
82 }
83}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseEvmRuleBase.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseEvmRuleBase.java
new file mode 100644
index 00000000..838c1d1b
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseEvmRuleBase.java
@@ -0,0 +1,21 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import org.eclipse.viatra.transformation.evm.api.Agenda;
12import org.eclipse.viatra.transformation.evm.api.RuleBase;
13import org.eclipse.viatra.transformation.evm.api.event.EventRealm;
14
15public class DseEvmRuleBase extends RuleBase {
16
17 public DseEvmRuleBase(EventRealm eventRealm, Agenda agenda) {
18 super(eventRealm, agenda);
19 }
20
21}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseIdPoolHelper.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseIdPoolHelper.java
new file mode 100644
index 00000000..f6fee7be
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseIdPoolHelper.java
@@ -0,0 +1,68 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import java.util.Collection;
12import java.util.HashMap;
13import java.util.concurrent.ConcurrentHashMap;
14
15import org.eclipse.viatra.dse.api.DSEException;
16import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
17
18public enum DseIdPoolHelper {
19
20 INSTANCE;
21
22 public static interface IGetRuleExecutions {
23 int getRuleExecutions(BatchTransformationRule<?, ?> rule);
24 }
25
26 public static class IdProvider {
27
28 private final BatchTransformationRule<?, ?> rule;
29 private IGetRuleExecutions getRuleExecutions;
30
31 public IdProvider(IGetRuleExecutions getRuleExecutions, BatchTransformationRule<?, ?> rule) {
32 this.getRuleExecutions = getRuleExecutions;
33 this.rule = rule;
34 }
35
36 public int getId() {
37 return getRuleExecutions.getRuleExecutions(rule);
38 }
39
40 }
41
42 private ConcurrentHashMap<Thread, HashMap<BatchTransformationRule<?, ?>, IdProvider>> idProviders = new ConcurrentHashMap<>();
43
44 public int getId(BatchTransformationRule<?, ?> rule) {
45 Thread currentThread = Thread.currentThread();
46 HashMap<BatchTransformationRule<?, ?>, IdProvider> ruleMap = idProviders.get(currentThread);
47 if (ruleMap == null) {
48 throw new DSEException("There is no registered id provider");
49 }
50 IdProvider idProvider = ruleMap.get(rule);
51 return idProvider.getId();
52 }
53
54 public void registerRules(IGetRuleExecutions getRuleExecutions, Collection<BatchTransformationRule<?, ?>> rules) {
55 Thread currentThread = Thread.currentThread();
56 HashMap<BatchTransformationRule<?, ?>, IdProvider> ruleMap = new HashMap<>();
57 for (BatchTransformationRule<?, ?> rule : rules) {
58 IdProvider idProvider = new IdProvider(getRuleExecutions, rule);
59 ruleMap.put(rule, idProvider);
60 }
61 idProviders.put(currentThread, ruleMap);
62 }
63
64 public void disposeByThread() {
65 Thread currentThread = Thread.currentThread();
66 idProviders.remove(currentThread);
67 }
68}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ExplorerThread.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ExplorerThread.java
new file mode 100644
index 00000000..f2231e5c
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ExplorerThread.java
@@ -0,0 +1,88 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import org.apache.log4j.Logger;
12import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
13import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
14import org.eclipse.viatra.transformation.evm.api.RuleEngine;
15
16/**
17 * This class implements the {@link Runnable} interface, to able to run an exploration strategy in a separate thread. It
18 * is also responsible to initialize the exploration, start the exploration (call the {@link IStrategy#explore()}
19 * method), catch any exception during exploration and to shutdown the thread correctly.
20 *
21 * @author Földenyi Miklos & Nagy Andras Szabolcs
22 *
23 */
24public class ExplorerThread implements Runnable {
25
26 private final ThreadContext threadContext;
27
28 private IStrategy strategy;
29
30 public ExplorerThread(final ThreadContext context) {
31 this.threadContext = context;
32 strategy = threadContext.getStrategy();
33 }
34
35 /**
36 * Signals the {@link IStrategy} instance that execution should be stopped. By contract, the strategy is to
37 * stop execution at the next stage of execution where stopping and exiting is appropriate.
38 */
39 public void stopRunning() {
40 strategy.interruptStrategy();
41 }
42
43 /**
44 * Starts the design space exploration. Returns only when the {@link IStrategy#explore()} method returns.
45 */
46 public void run() {
47 GlobalContext globalContext = threadContext.getGlobalContext();
48 try {
49
50 threadContext.init();
51
52 strategy.initStrategy(threadContext);
53
54 strategy.explore();
55
56 threadContext.backtrackUntilRoot();
57
58 } catch (Throwable e) {
59 Logger.getLogger(IStrategy.class).error("Thread stopped unexpectedly!", e);
60 globalContext.registerException(e);
61 } finally {
62 globalContext.strategyFinished(this);
63 dispose();
64 }
65 }
66
67 /**
68 * Disposes of this strategy. Recursively calls dispose on the underlying {@link RuleEngine} and
69 * {@link ViatraQueryEngine}. Calling this is only required if the design space exploration was launched in thread, as
70 * the underlying engines get collected on the stop of the running {@link Thread}.
71 */
72 public void dispose() {
73 threadContext.getRuleEngine().dispose();
74 DseIdPoolHelper.INSTANCE.disposeByThread();
75 }
76
77 /**
78 * Returns the associated {@link ThreadContext} that houses all the thread specific data about the exploration
79 * process, and is also the gateway to the {@link GlobalContext} which stores data relevant to the design space
80 * exploration process as a whole.
81 *
82 * @return the relevant {@link ThreadContext}.
83 */
84 public ThreadContext getThreadContext() {
85 return threadContext;
86 }
87
88}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/GlobalContext.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/GlobalContext.java
new file mode 100644
index 00000000..7325ead3
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/GlobalContext.java
@@ -0,0 +1,374 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import java.util.ArrayList;
12import java.util.Collection;
13import java.util.HashMap;
14import java.util.HashSet;
15import java.util.List;
16import java.util.Map;
17import java.util.Set;
18import java.util.concurrent.ConcurrentLinkedQueue;
19import java.util.concurrent.atomic.AtomicBoolean;
20
21import org.apache.log4j.Logger;
22import org.eclipse.emf.common.notify.Notifier;
23import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
24import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategyFactory;
25import org.eclipse.viatra.dse.designspace.api.IDesignSpace;
26import org.eclipse.viatra.dse.multithreading.DSEThreadPool;
27import org.eclipse.viatra.dse.objectives.IGlobalConstraint;
28import org.eclipse.viatra.dse.objectives.IObjective;
29import org.eclipse.viatra.dse.objectives.LeveledObjectivesHelper;
30import org.eclipse.viatra.dse.solutionstore.SolutionStore;
31import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
32import org.eclipse.viatra.dse.util.EMFHelper;
33import org.eclipse.viatra.dse.visualizer.IDesignSpaceVisualizer;
34import org.eclipse.viatra.transformation.evm.api.RuleSpecification;
35import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver;
36import org.eclipse.viatra.transformation.evm.specific.ConflictResolvers;
37import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
38
39import com.google.common.base.Preconditions;
40import com.google.common.collect.ImmutableList;
41
42/**
43 * Creates new contexts for strategies. It is needed because of the multithreading.
44 *
45 * @author Andras Szabolcs Nagy
46 *
47 */
48public class GlobalContext {
49
50 // **** fields and methods for multi threading *****//
51 // *************************************************//
52
53 public enum ExplorationProcessState {
54 NOT_STARTED,
55 RUNNING,
56 STOPPING,
57 COMPLETED
58 }
59
60 private ConcurrentLinkedQueue<Throwable> exceptions = new ConcurrentLinkedQueue<Throwable>();
61
62 private volatile ExplorationProcessState state = ExplorationProcessState.NOT_STARTED;
63 private final Set<ExplorerThread> runningThreads = new HashSet<ExplorerThread>();
64 private DSEThreadPool threadPool = new DSEThreadPool();
65 private int numberOfStartedThreads = 0;
66 private IDesignSpace designSpace;
67
68 private AtomicBoolean firstThreadContextInited = new AtomicBoolean(false);
69 private AtomicBoolean firstThreadContextIniting = new AtomicBoolean(false);
70
71 private Map<RuleSpecification<?>, BatchTransformationRule<?,?>> specificationRuleMap;
72
73 private Object terminationSnycObject = new Object();
74
75 private Logger logger = Logger.getLogger(IStrategy.class);
76
77 private boolean isAlreadyInited;
78
79 public void waitForTermination() {
80 synchronized (terminationSnycObject) {
81 while (!isDone()) {
82 try {
83 terminationSnycObject.wait();
84 } catch (InterruptedException e) {
85 }
86 }
87 }
88 }
89
90 /**
91 * Starts a new thread to explore the design space.
92 *
93 * @param originalThreadContext The context of the thread which starts the new thread.
94 * @param model The model to start from.
95 * @param cloneModel It should be true in most cases.
96 * @param strategy The strategy, the thread will use.
97 * @return The {@link ExplorerThread}
98 */
99 private synchronized ExplorerThread tryStartNewThread(ThreadContext originalThreadContext, Notifier model,
100 IStrategy strategy) {
101
102 if(!isAlreadyInited) {
103 isAlreadyInited = true;
104 init();
105 }
106
107 if (state != ExplorationProcessState.COMPLETED && state != ExplorationProcessState.STOPPING
108 && threadPool.canStartNewThread()) {
109
110 ThreadContext newThreadContext = new ThreadContext(this, strategy, model);
111
112 // TODO : clone undo list? slave strategy can't go further back...
113 ExplorerThread explorerThread = new ExplorerThread(newThreadContext);
114 newThreadContext.setExplorerThread(explorerThread);
115
116 boolean isSuccessful = threadPool.tryStartNewStrategy(explorerThread);
117
118 if (isSuccessful) {
119 runningThreads.add(explorerThread);
120
121 state = ExplorationProcessState.RUNNING;
122 ++numberOfStartedThreads;
123
124 logger.info("New thread started, active threads: " + runningThreads.size());
125
126 return explorerThread;
127 }
128 }
129 return null;
130 }
131
132 public synchronized ExplorerThread tryStartNewThread(ThreadContext originalThreadContext, IStrategy strategy) {
133 return tryStartNewThread(originalThreadContext, EMFHelper.clone(originalThreadContext.getModel()), strategy);
134 }
135
136 public synchronized ExplorerThread tryStartNewThreadWithoutModelClone(ThreadContext originalThreadContext,
137 IStrategy strategy) {
138 return tryStartNewThread(originalThreadContext, originalThreadContext.getModel(), strategy);
139 }
140
141 public synchronized ExplorerThread startFirstThread(IStrategy strategy, Notifier model) {
142 Preconditions.checkState(!isAlreadyInited, "First thread is already started.");
143 return tryStartNewThread(null, EMFHelper.clone(model), strategy);
144 }
145
146 public synchronized ExplorerThread startFirstThreadWithoutModelClone(IStrategy strategy, Notifier model) {
147 Preconditions.checkState(!isAlreadyInited, "First thread is already started.");
148 return tryStartNewThread(null, model, strategy);
149 }
150
151 public synchronized void startAllThreads(ThreadContext originalThreadContext, IStrategyFactory strategyFactory) {
152 while (canStartNewThread()) {
153 tryStartNewThread(originalThreadContext, strategyFactory.createStrategy());
154 }
155 }
156
157 /**
158 * Starts a new thread to explore the design space.
159 *
160 * @param strategyBase
161 * The {@link Strategy}.
162 * @param tedToClone
163 * The model to clone. Hint: context.getTed()
164 */
165
166 public synchronized void strategyFinished(ExplorerThread strategy) {
167 runningThreads.remove(strategy);
168
169 logger.info("Thread finished, active threads: " + runningThreads.size());
170
171 // is the first part necessary?
172 if (runningThreads.isEmpty()) {
173 state = ExplorationProcessState.COMPLETED;
174 threadPool.shutdown();
175
176 // if the main thread (which started the exploration)
177 // is waiting for the solution, than wake it up
178 synchronized (terminationSnycObject) {
179 terminationSnycObject.notify();
180 logger.info("Exploration terminated.");
181 }
182
183 }
184 }
185
186 public synchronized boolean isDone() {
187 return state == ExplorationProcessState.COMPLETED && runningThreads.isEmpty();
188 }
189
190 public synchronized boolean isNotStarted() {
191 return state == ExplorationProcessState.NOT_STARTED;
192 }
193
194 public boolean canStartNewThread() {
195 return (state == ExplorationProcessState.NOT_STARTED || state == ExplorationProcessState.RUNNING)
196 && threadPool.canStartNewThread();
197 }
198
199 public synchronized void stopAllThreads() {
200 if (state == ExplorationProcessState.RUNNING) {
201 state = ExplorationProcessState.STOPPING;
202 logger.info("Stopping all threads.");
203 for (ExplorerThread strategy : runningThreads) {
204 strategy.stopRunning();
205 }
206 }
207 }
208
209 public void registerException(Throwable e) {
210 exceptions.add(e);
211 }
212
213 // ******* fields and methods for exploration *******//
214 // **************************************************//
215
216 private List<IObjective> objectives = new ArrayList<IObjective>();
217 private IObjective[][] leveledObjectives;
218 private List<IGlobalConstraint> globalConstraints = new ArrayList<IGlobalConstraint>();
219 private Set<BatchTransformationRule<?, ?>> transformations = new HashSet<BatchTransformationRule<?, ?>>();
220 private IStateCoderFactory stateCoderFactory;
221 private SolutionStore solutionStore = new SolutionStore(1);
222 private Object sharedObject;
223 private List<IDesignSpaceVisualizer> visualizers;
224
225 private ConflictResolver conflictResolver = ConflictResolvers.createArbitraryResolver();
226
227 private void init() {
228 leveledObjectives = new LeveledObjectivesHelper(objectives).initLeveledObjectives();
229
230 specificationRuleMap = new HashMap<>();
231 for (BatchTransformationRule<?,?> rule : transformations) {
232 specificationRuleMap.put(rule.getRuleSpecification(), rule);
233 }
234 }
235
236 public List<IDesignSpaceVisualizer> getVisualizers() {
237 return ImmutableList.copyOf(visualizers);
238 }
239
240 public void registerDesignSpaceVisualizer(IDesignSpaceVisualizer visualizer) {
241 if (visualizer == null) {
242 return;
243 }
244 if (visualizers == null) {
245 visualizers = new ArrayList<IDesignSpaceVisualizer>();
246 }
247 visualizers.add(visualizer);
248 }
249
250 public void deregisterDesignSpaceVisualizer(IDesignSpaceVisualizer visualizer) {
251 if (visualizer == null) {
252 return;
253 }
254 if (visualizers != null) {
255 visualizers.remove(visualizer);
256 }
257 }
258
259 public boolean isDesignSpaceVisualizerRegistered(IDesignSpaceVisualizer visualizer) {
260 if (visualizers != null) {
261 return visualizers.contains(visualizer);
262 }
263 return false;
264 }
265
266 public void initVisualizersForThread(ThreadContext threadContext) {
267 if (visualizers != null && !visualizers.isEmpty()) {
268 for (IDesignSpaceVisualizer visualizer : visualizers) {
269 visualizer.init(threadContext);
270 threadContext.getDesignSpaceManager().registerExploreEventHandler(visualizer);
271 }
272 }
273 }
274
275 public boolean isExceptionHappendInOtherThread() {
276 return !exceptions.isEmpty();
277 }
278
279 public Collection<Throwable> getExceptions() {
280 return exceptions;
281 }
282
283 public IStateCoderFactory getStateCoderFactory() {
284 return stateCoderFactory;
285 }
286
287 public void setStateCoderFactory(IStateCoderFactory stateCoderFactory) {
288 this.stateCoderFactory = stateCoderFactory;
289 }
290
291 public Set<BatchTransformationRule<?, ?>> getTransformations() {
292 return transformations;
293 }
294
295 public void setTransformations(Set<BatchTransformationRule<?, ?>> transformations) {
296 this.transformations = transformations;
297 }
298
299 public DSEThreadPool getThreadPool() {
300 return threadPool;
301 }
302
303 public IDesignSpace getDesignSpace() {
304 return designSpace;
305 }
306
307 public void setDesignSpace(IDesignSpace designSpace) {
308 this.designSpace = designSpace;
309 }
310
311 public int getNumberOfStartedThreads() {
312 return numberOfStartedThreads;
313 }
314
315 public Object getSharedObject() {
316 return sharedObject;
317 }
318
319 public void setSharedObject(Object sharedObject) {
320 this.sharedObject = sharedObject;
321 }
322
323 public ExplorationProcessState getState() {
324 return state;
325 }
326
327 public List<IObjective> getObjectives() {
328 return objectives;
329 }
330
331 public void setObjectives(List<IObjective> objectives) {
332 this.objectives = objectives;
333 }
334
335 public List<IGlobalConstraint> getGlobalConstraints() {
336 return globalConstraints;
337 }
338
339 public void setGlobalConstraints(List<IGlobalConstraint> globalConstraints) {
340 this.globalConstraints = globalConstraints;
341 }
342
343 AtomicBoolean getFirstThreadContextInited() {
344 return firstThreadContextInited;
345 }
346
347 AtomicBoolean getFirstThreadContextIniting() {
348 return firstThreadContextIniting;
349 }
350
351 public IObjective[][] getLeveledObjectives() {
352 return leveledObjectives;
353 }
354
355 public void setSolutionStore(SolutionStore solutionStore) {
356 this.solutionStore = solutionStore;
357 }
358
359 public SolutionStore getSolutionStore() {
360 return solutionStore;
361 }
362
363 public Map<RuleSpecification<?>, BatchTransformationRule<?, ?>> getSpecificationRuleMap() {
364 return specificationRuleMap;
365 }
366
367 public void setConflictResolver(ConflictResolver conflictResolver) {
368 this.conflictResolver = conflictResolver;
369 }
370
371 public ConflictResolver getConflictResolver() {
372 return conflictResolver;
373 }
374}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/IDseStrategyContext.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/IDseStrategyContext.java
new file mode 100644
index 00000000..d630964f
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/IDseStrategyContext.java
@@ -0,0 +1,117 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import java.util.Collection;
12import java.util.List;
13import java.util.Set;
14
15import org.eclipse.emf.common.notify.Notifier;
16import org.eclipse.emf.edit.domain.EditingDomain;
17import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
18import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategyFactory;
19import org.eclipse.viatra.dse.designspace.api.IDesignSpace;
20import org.eclipse.viatra.dse.designspace.api.TrajectoryInfo;
21import org.eclipse.viatra.dse.objectives.Fitness;
22import org.eclipse.viatra.dse.objectives.IGlobalConstraint;
23import org.eclipse.viatra.dse.objectives.IObjective;
24import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
25import org.eclipse.viatra.dse.solutionstore.SolutionStore;
26import org.eclipse.viatra.dse.statecode.IStateCoder;
27import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
28import org.eclipse.viatra.transformation.evm.api.Activation;
29import org.eclipse.viatra.transformation.evm.api.RuleEngine;
30import org.eclipse.viatra.transformation.evm.api.RuleSpecification;
31import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
32
33/**
34 * This interface is only to overview the required methods for exploration strategies. It is not used explicitly.
35 *
36 * @author Andras Szabolcs Nagy
37 *
38 */
39public interface IDseStrategyContext {
40
41 void init();
42
43 Notifier getModel();
44 EditingDomain getEditingDomain();
45 ViatraQueryEngine getQueryEngine();
46 RuleEngine getRuleEngine();
47 IStrategy getStrategy();
48 ExplorerThread getExplorerThread();
49 List<IObjective> getObjectives();
50 IObjective[][] getLeveledObjectives();
51 List<IGlobalConstraint> getGlobalConstraints();
52
53 SolutionStore getSolutionStore();
54 void newSolution();
55// TODO void newSolution(TrajectoryFitness trajectoryFitness);
56
57
58 ObjectiveComparatorHelper getObjectiveComparatorHelper();
59
60 GlobalContext getGlobalContext();
61 Set<BatchTransformationRule<?, ?>> getRules();
62 BatchTransformationRule<?, ?> getRuleByRuleSpecification(RuleSpecification<?> ruleSpecification);
63 ExplorerThread tryStartNewThread(IStrategy strategy); /*IDseStrategyContext originalContext*/
64 ExplorerThread tryStartNewThreadWithoutModelClone(IStrategy strategy);
65 void startAllThreads(IStrategyFactory strategyFactory);
66 Object getSharedObject();
67 void setSharedObject(Object sharedObject);
68
69
70 DesignSpaceManager getDesignSpaceManager();
71 IStateCoder getStateCoder();
72 IDesignSpace getDesignSpace();
73 TrajectoryInfo getTrajectoryInfo();
74 List<Object> getTrajectory();
75 List<Object> getTrajectoryCopied();
76 int getDepth();
77 Object getCurrentStateId();
78
79 Object getTransitionByActivation(Activation<?> activation);
80 Activation<?> getActivationById(Object activationId);
81 BatchTransformationRule<?, ?> getRuleByActivation(Activation<?> activation);
82 BatchTransformationRule<?, ?> getRuleByActivationId(Object activationId);
83
84 Collection<Object> getCurrentActivationIds();
85 Collection<Object> getUntraversedActivationIds();
86// TODO Object getArbitraryActivationId();
87// TODO Object getArbitraryUntraversedActivationId();
88
89 void executeAcitvationId(Object activationId);
90 boolean tryExecuteAcitvationId(Object activationId);
91 boolean executeRandomActivationId();
92 void executeTrajectory(Object[] activationIds);
93 void executeTrajectory(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex);
94 int executeTrajectoryByTrying(Object[] activationIds);
95 int executeTrajectoryByTrying(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex);
96 int executeTrajectoryWithoutStateCoding(Object[] activationIds);
97 int executeTrajectoryWithoutStateCoding(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex);
98 int executeTrajectoryByTryingWithoutStateCoding(Object[] activationIds);
99 int executeTrajectoryByTryingWithoutStateCoding(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex);
100 void executeTrajectoryWithMinimalBacktrack(Object[] trajectory);
101 void executeTrajectoryWithMinimalBacktrack(Object[] trajectory, int toExcludedIndex);
102 void executeTrajectoryWithMinimalBacktrackWithoutStateCoding(Object[] trajectory);
103 void executeTrajectoryWithMinimalBacktrackWithoutStateCoding(Object[] trajectory, int toExcludedIndex);
104
105 boolean backtrack();
106 // TODO int backtrack(int times);
107 void backtrackUntilLastCommonActivation(Object[] trajectory);
108 void backtrackUntilRoot();
109
110 Fitness calculateFitness();
111 Fitness getLastFitness();
112 boolean checkGlobalConstraints();
113 boolean isCurrentStateAlreadyTraversed();
114 // this needs states stored:
115 boolean isCurrentStateInTrajectory();
116
117}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/SingletonSetConflictResolver.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/SingletonSetConflictResolver.java
new file mode 100644
index 00000000..8c0a715a
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/SingletonSetConflictResolver.java
@@ -0,0 +1,53 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import org.eclipse.viatra.transformation.evm.api.RuleEngine;
12import org.eclipse.viatra.transformation.evm.api.resolver.ChangeableConflictSet;
13import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver;
14
15/**
16 *
17 * @author Andras Szabolcs Nagy
18 *
19 */
20public class SingletonSetConflictResolver implements ConflictResolver {
21
22 protected ChangeableConflictSet conflictSet;
23 protected ConflictResolver conflictResolver;
24 protected ConflictResolver prevConflictResolver;
25 protected RuleEngine ruleEngine;
26
27 public SingletonSetConflictResolver(ConflictResolver conflictResolver) {
28 this.conflictResolver = conflictResolver;
29 conflictSet = conflictResolver.createConflictSet();
30 }
31
32 @Override
33 public ChangeableConflictSet createConflictSet() {
34 return conflictSet;
35 }
36
37 public void changeConflictResolver(ConflictResolver conflictResolver) {
38 ConflictResolver tmp = this.conflictResolver;
39 this.conflictResolver = conflictResolver;
40 prevConflictResolver = tmp;
41 conflictSet = conflictResolver.createConflictSet();
42 ruleEngine.setConflictResolver(this);
43 }
44
45 public void changeConflictResolverBack() {
46 changeConflictResolver(prevConflictResolver);
47 }
48
49 public void setRuleEngine(RuleEngine ruleEngine) {
50 this.ruleEngine = ruleEngine;
51 ruleEngine.setConflictResolver(this);
52 }
53}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ThreadContext.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ThreadContext.java
new file mode 100644
index 00000000..b62442ce
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ThreadContext.java
@@ -0,0 +1,542 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import java.util.ArrayList;
12import java.util.Collection;
13import java.util.List;
14import java.util.Set;
15import java.util.concurrent.atomic.AtomicBoolean;
16
17import org.apache.log4j.Logger;
18import org.eclipse.emf.common.notify.Notifier;
19import org.eclipse.emf.edit.domain.EditingDomain;
20import org.eclipse.viatra.dse.api.DSEException;
21import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
22import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategyFactory;
23import org.eclipse.viatra.dse.designspace.api.IDesignSpace;
24import org.eclipse.viatra.dse.designspace.api.TrajectoryInfo;
25import org.eclipse.viatra.dse.objectives.Fitness;
26import org.eclipse.viatra.dse.objectives.IGlobalConstraint;
27import org.eclipse.viatra.dse.objectives.IObjective;
28import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
29import org.eclipse.viatra.dse.solutionstore.SolutionStore;
30import org.eclipse.viatra.dse.statecode.IStateCoder;
31import org.eclipse.viatra.dse.util.EMFHelper;
32import org.eclipse.viatra.query.runtime.api.IPatternMatch;
33import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
34import org.eclipse.viatra.query.runtime.emf.EMFScope;
35import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
36import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
37import org.eclipse.viatra.transformation.evm.api.Activation;
38import org.eclipse.viatra.transformation.evm.api.RuleEngine;
39import org.eclipse.viatra.transformation.evm.api.RuleSpecification;
40import org.eclipse.viatra.transformation.evm.api.event.EventFilter;
41import org.eclipse.viatra.transformation.evm.api.resolver.ChangeableConflictSet;
42import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver;
43import org.eclipse.viatra.transformation.evm.api.resolver.ConflictSet;
44import org.eclipse.viatra.transformation.evm.specific.RuleEngines;
45import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
46
47/**
48 * This class holds all the information that is related to a single processing thread of the DesignSpaceExploration
49 * process. For any attributes related to the Design Space Exploration process as a whole, see {@link GlobalContext}.
50 *
51 * @author Miklos Foldenyi
52 *
53 */
54public class ThreadContext implements IDseStrategyContext{
55
56 private final GlobalContext globalContext;
57 private final IStrategy strategy;
58 private ExplorerThread explorerThread;
59 private RuleEngine ruleEngine;
60 private ViatraQueryEngine queryEngine;
61 private EditingDomain domain;
62 private Notifier model;
63 private DesignSpaceManager designSpaceManager;
64 private List<IObjective> objectives;
65 private List<IGlobalConstraint> globalConstraints;
66 private Fitness lastFitness;
67 private ObjectiveComparatorHelper objectiveComparatorHelper;
68 private IStateCoder stateCoder;
69 private DseConflictResolver dseConflictResolver;
70 private DseConflictSet dseConflictSet;
71 private ActivationCodesConflictSet activationCodesConflictSet;
72
73 /**
74 * This value is true after the {@link ThreadContext} has been initialized in it's own thread.
75 */
76 private AtomicBoolean inited = new AtomicBoolean(false);
77
78 private boolean isFirstThread = false;
79 private IObjective[][] leveledObjectives;
80
81 private static class GetRuleExecutionsImpl implements DseIdPoolHelper.IGetRuleExecutions {
82
83 private List<BatchTransformationRule<?, ?>> executedRules;
84
85 public GetRuleExecutionsImpl(List<BatchTransformationRule<?, ?>> executedRulesView) {
86 this.executedRules = executedRulesView;
87 }
88
89 @Override
90 public int getRuleExecutions(BatchTransformationRule<?, ?> rule) {
91 int nextId = 0;
92 for (BatchTransformationRule<?, ?> r : executedRules) {
93 if (r.equals(rule)) {
94 nextId ++;
95 }
96 }
97 return nextId;
98 }
99
100 }
101
102 public DseConflictResolver getConflictResolver() {
103 return dseConflictResolver;
104 }
105
106 public ConflictSet getConflictSet() {
107 return dseConflictSet;
108 }
109
110 /**
111 * Creates a {@link ThreadContext} and sets it up to be initialized on the given {@link TransactionalEditingDomain}
112 *
113 * @param globalContext
114 * @param strategyBase
115 * @param domain
116 * @param trajectoryInfoToClone
117 * @param parentGuidance
118 */
119 public ThreadContext(final GlobalContext globalContext, IStrategy strategy, Notifier model) {
120 Preconditions.checkArgument(model != null, "Cannot initialize ThreadContext on a null model.");
121 this.globalContext = globalContext;
122 this.strategy = strategy;
123 this.model = model;
124 }
125
126 /**
127 * Initializes the {@link ThreadContext} by initializing the underlying {@link ViatraQueryEngine} and
128 * {@link RuleEngine}. {@link Guidance} initialization is also happening within this method.
129 *
130 * @throws DSEException
131 */
132 public void init() {
133
134 AtomicBoolean isFirst = globalContext.getFirstThreadContextIniting();
135 AtomicBoolean isFirstReady = globalContext.getFirstThreadContextInited();
136 if (!isFirstReady.get()) {
137 if (!isFirst.compareAndSet(false, true)) {
138 try {
139 do {
140 Thread.sleep(5);
141 } while (!isFirstReady.get());
142 } catch (InterruptedException e) {
143 }
144 } else {
145 isFirstThread = true;
146 }
147 }
148 // prohibit re-initialization
149 Preconditions.checkArgument(!inited.getAndSet(true), "This Thread context has been initialized already!");
150
151 try {
152 // initialize query engine
153 final EMFScope scope = new EMFScope(model);
154 queryEngine = ViatraQueryEngine.on(scope);
155
156
157 stateCoder = getGlobalContext().getStateCoderFactory().createStateCoder();
158 stateCoder.init(model);
159 stateCoder.createStateCode();
160
161 ConflictResolver activationOrderingCconflictResolver = globalContext.getConflictResolver();
162 dseConflictResolver = new DseConflictResolver(activationOrderingCconflictResolver, stateCoder);
163
164 ruleEngine = RuleEngines.createViatraQueryRuleEngine(queryEngine);
165 ruleEngine.setConflictResolver(dseConflictResolver);
166 for (BatchTransformationRule<?, ?> tr : globalContext.getTransformations()) {
167 ruleEngine.addRule(tr.getRuleSpecification(), (EventFilter<IPatternMatch>) tr.getFilter());
168 }
169 dseConflictSet = dseConflictResolver.getLastCreatedConflictSet();
170 activationCodesConflictSet = dseConflictSet.getActivationCodesConflictSet();
171 activationCodesConflictSet.updateActivationCodes();
172
173
174 } catch (ViatraQueryException e) {
175 throw new DSEException("Failed to create unmanaged ViatraQueryEngine on the model.", e);
176 }
177
178 if (isFirstThread) {
179
180 objectives = globalContext.getObjectives();
181 leveledObjectives = globalContext.getLeveledObjectives();
182 globalConstraints = globalContext.getGlobalConstraints();
183
184 } else {
185 objectives = new ArrayList<IObjective>();
186
187 IObjective[][] leveledObjectivesToCopy = globalContext.getLeveledObjectives();
188 leveledObjectives = new IObjective[leveledObjectivesToCopy.length][];
189 for (int i = 0; i < leveledObjectivesToCopy.length; i++) {
190 leveledObjectives[i] = new IObjective[leveledObjectivesToCopy[i].length];
191 for (int j = 0; j < leveledObjectivesToCopy[i].length; j++) {
192 leveledObjectives[i][j] = leveledObjectivesToCopy[i][j].createNew();
193 objectives.add(leveledObjectives[i][j]);
194 }
195 }
196
197 globalConstraints = new ArrayList<IGlobalConstraint>();
198 for (IGlobalConstraint globalConstraint : globalContext.getGlobalConstraints()) {
199 globalConstraints.add(globalConstraint.createNew());
200 }
201
202 }
203 // create the thread specific DesignSpaceManager
204 this.domain = EMFHelper.createEditingDomain(model);
205 designSpaceManager = new DesignSpaceManager(this);
206
207 boolean isThereHardObjective = false;
208 for (IObjective objective : objectives) {
209 objective.init(this);
210 if (objective.isHardObjective()) {
211 isThereHardObjective = true;
212 }
213 }
214 if (!isThereHardObjective) {
215 Logger.getLogger(IStrategy.class).warn(
216 "No hard objective is specified: all reachable state is a solution. Use a dummy hard objective to be explicit.");
217 }
218
219 for (IGlobalConstraint globalConstraint : globalConstraints) {
220 globalConstraint.init(this);
221 }
222
223 DseIdPoolHelper.INSTANCE.registerRules(new GetRuleExecutionsImpl(getDesignSpaceManager().getTrajectoryInfo().getRules()), getRules());
224
225 globalContext.initVisualizersForThread(this);
226
227 if (isFirstThread) {
228 isFirstReady.set(true);
229 }
230
231 }
232
233 public Fitness calculateFitness() {
234 Fitness result = new Fitness();
235
236 boolean satisifiesHardObjectives = true;
237
238 for (IObjective objective : objectives) {
239 Double fitness = objective.getFitness(this);
240 result.put(objective.getName(), fitness);
241 if (objective.isHardObjective() && !objective.satisifiesHardObjective(fitness)) {
242 satisifiesHardObjectives = false;
243 }
244 }
245
246 result.setSatisifiesHardObjectives(satisifiesHardObjectives);
247
248 lastFitness = result;
249
250 return result;
251 }
252
253 public boolean checkGlobalConstraints() {
254 for (IGlobalConstraint globalConstraint : globalContext.getGlobalConstraints()) {
255 if (!globalConstraint.checkGlobalConstraint(this)) {
256 return false;
257 }
258 }
259 return true;
260 }
261
262 public RuleEngine getRuleEngine() {
263 return ruleEngine;
264 }
265
266 public GlobalContext getGlobalContext() {
267 return globalContext;
268 }
269
270 public DesignSpaceManager getDesignSpaceManager() {
271 return designSpaceManager;
272 }
273
274 public EditingDomain getEditingDomain() {
275 return domain;
276 }
277
278 public Notifier getModel() {
279 return model;
280 }
281
282 public ViatraQueryEngine getQueryEngine() {
283 return queryEngine;
284 }
285
286 public IStrategy getStrategy() {
287 return strategy;
288 }
289
290 public ExplorerThread getExplorerThread() {
291 return explorerThread;
292 }
293
294 public void setExplorerThread(ExplorerThread explorerThread) {
295 this.explorerThread = explorerThread;
296 }
297
298 public Fitness getLastFitness() {
299 return lastFitness;
300 }
301
302 public ObjectiveComparatorHelper getObjectiveComparatorHelper() {
303 if (objectiveComparatorHelper == null) {
304 objectiveComparatorHelper = new ObjectiveComparatorHelper(leveledObjectives);
305 }
306 return objectiveComparatorHelper;
307 }
308
309 public IObjective[][] getLeveledObjectives() {
310 return leveledObjectives;
311 }
312
313 public List<IObjective> getObjectives() {
314 return objectives;
315 }
316
317 public List<IGlobalConstraint> getGlobalConstraints() {
318 return globalConstraints;
319 }
320
321 @Override
322 public SolutionStore getSolutionStore() {
323 return globalContext.getSolutionStore();
324 }
325
326 @Override
327 public void newSolution() {
328 globalContext.getSolutionStore().newSolution(this);
329 }
330
331 @Override
332 public Object getSharedObject() {
333 return globalContext.getSharedObject();
334 }
335
336 @Override
337 public void setSharedObject(Object sharedObject) {
338 globalContext.setSharedObject(sharedObject);
339 }
340
341 @Override
342 public Set<BatchTransformationRule<?, ?>> getRules() {
343 return globalContext.getTransformations();
344 }
345
346 @Override
347 public BatchTransformationRule<?, ?> getRuleByRuleSpecification(RuleSpecification<?> ruleSpecification) {
348 return globalContext.getSpecificationRuleMap().get(ruleSpecification);
349 }
350
351 @Override
352 public ExplorerThread tryStartNewThread(IStrategy strategy) {
353 return globalContext.tryStartNewThread(this, strategy);
354 }
355
356 @Override
357 public ExplorerThread tryStartNewThreadWithoutModelClone(IStrategy strategy) {
358 return globalContext.tryStartNewThreadWithoutModelClone(this, strategy);
359 }
360
361 @Override
362 public void startAllThreads(IStrategyFactory strategyFactory) {
363 globalContext.startAllThreads(this, strategyFactory);
364 }
365
366 @Override
367 public IStateCoder getStateCoder() {
368 return stateCoder;
369 }
370
371 @Override
372 public IDesignSpace getDesignSpace() {
373 return globalContext.getDesignSpace();
374 }
375
376 @Override
377 public TrajectoryInfo getTrajectoryInfo() {
378 return designSpaceManager.getTrajectoryInfo();
379 }
380
381 @Override
382 public List<Object> getTrajectory() {
383 return designSpaceManager.getTrajectoryInfo().getTrajectory();
384 }
385
386 @Override
387 public List<Object> getTrajectoryCopied() {
388 return new ArrayList<Object>(getTrajectory());
389 }
390
391 @Override
392 public int getDepth() {
393 return designSpaceManager.getTrajectoryInfo().getDepth();
394 }
395
396 @Override
397 public Object getCurrentStateId() {
398 return designSpaceManager.getTrajectoryInfo().getCurrentStateId();
399 }
400
401 @Override
402 public Object getTransitionByActivation(Activation<?> activation) {
403 return designSpaceManager.getTransitionByActivation(activation);
404 }
405
406 @Override
407 public Activation<?> getActivationById(Object activationId) {
408 return designSpaceManager.getActivationById(activationId);
409 }
410
411 @Override
412 public BatchTransformationRule<?, ?> getRuleByActivation(Activation<?> activation) {
413 return designSpaceManager.getRuleByActivation(activation);
414 }
415
416 @Override
417 public BatchTransformationRule<?, ?> getRuleByActivationId(Object activationId) {
418 return designSpaceManager.getRuleByActivationId(activationId);
419 }
420
421 @Override
422 public Collection<Object> getCurrentActivationIds() {
423 return designSpaceManager.getTransitionsFromCurrentState();
424 }
425
426 @Override
427 public Collection<Object> getUntraversedActivationIds() {
428 return designSpaceManager.getUntraversedTransitionsFromCurrentState();
429 }
430
431 @Override
432 public void executeAcitvationId(Object activationId) {
433 designSpaceManager.fireActivation(activationId);
434 }
435
436 @Override
437 public boolean tryExecuteAcitvationId(Object activationId) {
438 return designSpaceManager.tryFireActivation(activationId);
439 }
440
441 @Override
442 public boolean executeRandomActivationId() {
443 return designSpaceManager.executeRandomActivationId();
444 }
445
446 @Override
447 public void executeTrajectory(Object[] activationIds) {
448 designSpaceManager.executeTrajectory(activationIds);
449 }
450
451 @Override
452 public void executeTrajectory(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex) {
453 designSpaceManager.executeTrajectory(activationIds, fromIncludedIndex, toExcludedIndex);
454 }
455
456 @Override
457 public int executeTrajectoryByTrying(Object[] activationIds) {
458 return designSpaceManager.executeTrajectoryByTrying(activationIds);
459 }
460
461 @Override
462 public int executeTrajectoryByTrying(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex) {
463 return designSpaceManager.executeTrajectoryByTrying(activationIds, fromIncludedIndex, toExcludedIndex);
464 }
465
466 @Override
467 public int executeTrajectoryWithoutStateCoding(Object[] activationIds) {
468 return designSpaceManager.executeTrajectoryWithoutStateCoding(activationIds);
469 }
470
471 @Override
472 public int executeTrajectoryWithoutStateCoding(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex) {
473 return designSpaceManager.executeTrajectoryWithoutStateCoding(activationIds, fromIncludedIndex, toExcludedIndex);
474 }
475
476 @Override
477 public int executeTrajectoryByTryingWithoutStateCoding(Object[] activationIds) {
478 return designSpaceManager.executeTrajectoryByTryingWithoutStateCoding(activationIds);
479 }
480
481 @Override
482 public int executeTrajectoryByTryingWithoutStateCoding(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex) {
483 return designSpaceManager.executeTrajectoryByTryingWithoutStateCoding(activationIds, fromIncludedIndex, toExcludedIndex);
484 }
485
486 @Override
487 public void executeTrajectoryWithMinimalBacktrack(Object[] trajectory) {
488 designSpaceManager.executeTrajectoryWithMinimalBacktrack(trajectory);
489 }
490
491 @Override
492 public void executeTrajectoryWithMinimalBacktrack(Object[] trajectory, int toExcludedIndex) {
493 designSpaceManager.executeTrajectoryWithMinimalBacktrack(trajectory, toExcludedIndex);
494 }
495
496 @Override
497 public void executeTrajectoryWithMinimalBacktrackWithoutStateCoding(Object[] trajectory) {
498 designSpaceManager.executeTrajectoryWithMinimalBacktrackWithoutStateCoding(trajectory);
499 }
500
501 @Override
502 public void executeTrajectoryWithMinimalBacktrackWithoutStateCoding(Object[] trajectory, int toExcludedIndex) {
503 designSpaceManager.executeTrajectoryWithMinimalBacktrackWithoutStateCoding(trajectory, toExcludedIndex);
504 }
505
506 @Override
507 public boolean backtrack() {
508 return designSpaceManager.undoLastTransformation();
509 }
510
511 @Override
512 public void backtrackUntilLastCommonActivation(Object[] trajectory) {
513 designSpaceManager.backtrackUntilLastCommonActivation(trajectory);
514 }
515
516 @Override
517 public void backtrackUntilRoot() {
518 designSpaceManager.undoUntilRoot();
519 }
520
521 @Override
522 public boolean isCurrentStateAlreadyTraversed() {
523 return designSpaceManager.isNewModelStateAlreadyTraversed();
524 }
525
526 @Override
527 public boolean isCurrentStateInTrajectory() {
528 return designSpaceManager.isCurentStateInTrajectory();
529 }
530
531 public ActivationCodesConflictSet getActivationCodesConflictSet() {
532 return activationCodesConflictSet;
533 }
534
535 public void changeActivationOrdering(ChangeableConflictSet activationOrderingConflictSet) {
536 this.dseConflictSet.changeActivationOrderingConflictSet(activationOrderingConflictSet);
537 }
538
539 public void changeActivationOrderingBack() {
540 this.dseConflictSet.changeActivationOrderingConflictSetBack();
541 }
542}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/DesignSpace.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/DesignSpace.java
new file mode 100644
index 00000000..bc0f08d4
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/DesignSpace.java
@@ -0,0 +1,106 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.designspace.api;
10
11import java.util.ArrayList;
12import java.util.Collection;
13import java.util.Collections;
14import java.util.HashMap;
15import java.util.HashSet;
16import java.util.List;
17import java.util.Map;
18import java.util.Random;
19import java.util.Set;
20
21public class DesignSpace implements IDesignSpace {
22
23 Set<Object> statesView;
24
25 Set<Object> rootStates;
26 Set<Object> rootStatesView;
27
28 Map<Object, List<Object>> statesAndActivations;
29
30 Random random = new Random();
31
32 public DesignSpace() {
33 rootStates = new HashSet<>();
34 rootStatesView = Collections.unmodifiableSet(rootStates);
35
36 statesAndActivations = new HashMap<>();
37 statesView = statesAndActivations.keySet();
38 }
39
40 @Override
41 public synchronized Collection<Object> getStates() {
42 return statesView;
43 }
44
45 @Override
46 public synchronized Collection<Object> getRoots() {
47 return rootStatesView;
48 }
49
50 @Override
51 public synchronized void addState(Object sourceStateId, Object firedActivationId, Object newStateId) {
52
53 List<Object> activationIds = statesAndActivations.get(newStateId);
54
55 if (activationIds == null) {
56 activationIds = new ArrayList<Object>();
57 statesAndActivations.put(newStateId, activationIds);
58
59 if (sourceStateId == null) {
60 rootStates.add(newStateId);
61 return;
62 }
63 }
64
65 activationIds = statesAndActivations.get(sourceStateId);
66
67 if (activationIds == null) {
68 activationIds = new ArrayList<Object>();
69 activationIds.add(firedActivationId);
70 statesAndActivations.put(sourceStateId, activationIds);
71 } else {
72 activationIds.add(firedActivationId);
73 }
74 }
75
76 public synchronized boolean isTraversed(Object stateId) {
77 return statesAndActivations.containsKey(stateId);
78 }
79
80 @Override
81 public synchronized Collection<Object> getActivationIds(Object stateId) {
82 return statesAndActivations.get(stateId);
83 }
84
85 @Override
86 public synchronized Object getRandomActivationId(Object stateId) {
87 List<Object> activations = statesAndActivations.get(stateId);
88 int index = random.nextInt(activations.size());
89 return activations.get(index);
90 }
91
92 @Override
93 public synchronized long getNumberOfStates() {
94 return statesAndActivations.size();
95 }
96
97 @Override
98 public synchronized long getNumberOfTransitions() {
99 int numberOfTransitions = 0;
100 for (List<Object> activations : statesAndActivations.values()) {
101 numberOfTransitions += activations.size();
102 }
103 return numberOfTransitions;
104 }
105
106}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IBacktrackListener.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IBacktrackListener.java
new file mode 100644
index 00000000..5c688276
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IBacktrackListener.java
@@ -0,0 +1,7 @@
1package org.eclipse.viatra.dse.designspace.api;
2
3public interface IBacktrackListener {
4 void forwardWorked(long nanos);
5
6 void backtrackWorked(long nanos);
7}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IDesignSpace.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IDesignSpace.java
new file mode 100644
index 00000000..a1d64bbf
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IDesignSpace.java
@@ -0,0 +1,27 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.designspace.api;
10
11import java.util.Collection;
12
13public interface IDesignSpace {
14
15 Collection<Object> getStates();
16 Collection<Object> getRoots();
17 void addState(Object sourceStateId, Object firedActivationId, Object newStateId);
18
19 boolean isTraversed(Object stateId);
20
21 Collection<Object> getActivationIds(Object stateId);
22 Object getRandomActivationId(Object stateId);
23
24 long getNumberOfStates();
25 long getNumberOfTransitions();
26
27}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/TrajectoryInfo.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/TrajectoryInfo.java
new file mode 100644
index 00000000..acd88416
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/TrajectoryInfo.java
@@ -0,0 +1,154 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.designspace.api;
10
11import java.util.ArrayList;
12import java.util.Collections;
13import java.util.List;
14import java.util.Map;
15import java.util.Objects;
16
17import org.eclipse.viatra.dse.api.DSEException;
18import org.eclipse.viatra.dse.api.SolutionTrajectory;
19import org.eclipse.viatra.dse.base.DesignSpaceManager;
20import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
21import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
22
23public class TrajectoryInfo {
24
25 private final List<Object> trajectory;
26 private final List<Object> trajectoryView;
27 private final List<BatchTransformationRule<?, ?>> rules;
28 private final List<BatchTransformationRule<?, ?>> rulesView;
29 private final List<Object> stateIds;
30 private final List<Object> stateIdsView;
31 private final List<Map<String, Double>> measuredCosts;
32
33 public TrajectoryInfo(Object initialStateId) {
34 Objects.requireNonNull(initialStateId);
35
36 stateIds = new ArrayList<>();
37 stateIds.add(initialStateId);
38
39 trajectory = new ArrayList<>();
40 rules = new ArrayList<>();
41 measuredCosts = new ArrayList<>();
42
43 trajectoryView = Collections.unmodifiableList(trajectory);
44 stateIdsView = Collections.unmodifiableList(stateIds);
45 rulesView = Collections.unmodifiableList(rules);
46 }
47
48 /**
49 * Copy constructor
50 *
51 * @since 0.17
52 */
53 public TrajectoryInfo(TrajectoryInfo other) {
54 this(other.stateIds, other.trajectory, other.rules, other.measuredCosts);
55 }
56
57 protected TrajectoryInfo(List<Object> stateIds, List<Object> trajectory, List<BatchTransformationRule<?, ?>> rules, List<Map<String, Double>> measuredCosts) {
58
59 this.stateIds = new ArrayList<>(stateIds);
60 this.trajectory = new ArrayList<>(trajectory);
61 this.rules = new ArrayList<>(rules);
62 trajectoryView = Collections.unmodifiableList(trajectory);
63 stateIdsView = Collections.unmodifiableList(stateIds);
64 rulesView = Collections.unmodifiableList(rules);
65 this.measuredCosts = new ArrayList<>(measuredCosts);
66 }
67
68 public void addStep(Object activationId, BatchTransformationRule<?, ?> rule, Object newStateId, Map<String, Double> measuredCosts) {
69 stateIds.add(newStateId);
70 trajectory.add(activationId);
71 rules.add(rule);
72 this.measuredCosts.add(measuredCosts);
73 }
74
75 public void backtrack() {
76 int size = trajectory.size();
77
78 if (size == 0) {
79 throw new DSEException("Cannot step back any further!");
80 }
81
82 trajectory.remove(size - 1);
83 rules.remove(size - 1);
84 stateIds.remove(size);
85 measuredCosts.remove(size - 1);
86 }
87
88 public Object getInitialStateId() {
89 return stateIds.get(0);
90 }
91
92 public Object getCurrentStateId() {
93 return stateIds.get(stateIds.size() - 1);
94 }
95
96 public Object getLastActivationId() {
97 return trajectory.get(trajectory.size() - 1);
98 }
99
100 public List<Object> getTrajectory() {
101 return trajectoryView;
102 }
103
104 public List<Object> getStateTrajectory() {
105 return stateIdsView;
106 }
107
108 public List<BatchTransformationRule<?, ?>> getRules() {
109 return rulesView;
110 }
111
112 public int getDepth() {
113 return trajectory.size();
114 }
115
116 public List<Map<String, Double>> getMeasuredCosts() {
117 return measuredCosts;
118 }
119
120 public SolutionTrajectory createSolutionTrajectory(final IStateCoderFactory stateCoderFactory, final IBacktrackListener listener) {
121
122 List<Object> activationIds = new ArrayList<>(trajectory);
123 List<BatchTransformationRule<?, ?>> copiedRules = new ArrayList<>(rules);
124
125 return new SolutionTrajectory(activationIds, copiedRules, stateCoderFactory, listener);
126 }
127
128 public boolean canStepBack() {
129 return !trajectory.isEmpty();
130 }
131
132 @Override
133 public String toString() {
134 StringBuilder sb = new StringBuilder("Trajectory:\n");
135 for (Object activationId : trajectory) {
136 sb.append(activationId);
137 sb.append("\n");
138 }
139 return sb.toString();
140 }
141
142 /**
143 * This method is only used by the {@link DesignSpaceManager}.
144 * @param stateCode
145 * @return false if the initial state code is the last one, otherwise true.
146 */
147 public boolean modifyLastStateCode(Object stateCode) {
148 if (stateIds.size() == 1) {
149 return false;
150 }
151 stateIds.set(stateIds.size() - 1, stateCode);
152 return true;
153 }
154}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/multithreading/DSEThreadPool.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/multithreading/DSEThreadPool.java
new file mode 100644
index 00000000..17e96a75
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/multithreading/DSEThreadPool.java
@@ -0,0 +1,58 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.multithreading;
10
11import java.util.concurrent.RejectedExecutionException;
12import java.util.concurrent.SynchronousQueue;
13import java.util.concurrent.ThreadPoolExecutor;
14import java.util.concurrent.TimeUnit;
15
16import org.apache.log4j.Logger;
17import org.eclipse.viatra.dse.api.DesignSpaceExplorer;
18import org.eclipse.viatra.dse.base.ExplorerThread;
19
20/**
21 *
22 * @author Andras Szabolcs Nagy
23 *
24 */
25public class DSEThreadPool extends ThreadPoolExecutor {
26
27 private static final long THREAD_KEEP_ALIVE_IN_SECONDS = 60;
28
29 public DSEThreadPool() {
30 // Based on the Executors.newCachedThreadPool()
31 super(0, getProcNumber(), THREAD_KEEP_ALIVE_IN_SECONDS, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
32 }
33
34 // helper for constructor
35 private static int getProcNumber() {
36 return Runtime.getRuntime().availableProcessors();
37 }
38
39 public boolean tryStartNewStrategy(ExplorerThread strategy) {
40
41 if (!canStartNewThread()) {
42 return false;
43 }
44
45 try {
46 submit(strategy);
47 } catch (RejectedExecutionException e) {
48 Logger.getLogger(DesignSpaceExplorer.class).info("Couldn't start new thread.", e);
49 return false;
50 }
51
52 return true;
53 }
54
55 public boolean canStartNewThread() {
56 return getMaximumPoolSize() > getActiveCount();
57 }
58}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ActivationFitnessProcessor.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ActivationFitnessProcessor.java
new file mode 100644
index 00000000..c06d2916
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ActivationFitnessProcessor.java
@@ -0,0 +1,15 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import org.eclipse.viatra.query.runtime.api.IPatternMatch;
12
13public interface ActivationFitnessProcessor {
14 public double process(IPatternMatch match);
15} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Comparators.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Comparators.java
new file mode 100644
index 00000000..b1bd9349
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Comparators.java
@@ -0,0 +1,31 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import java.util.Comparator;
12
13/**
14 * This helper class holds comparators for objective implementations.
15 *
16 * @author Andras Szabolcs Nagy
17 *
18 */
19public class Comparators {
20
21 private Comparators() { /*Utility class constructor*/ }
22
23 public static final Comparator<Double> HIGHER_IS_BETTER = (o1, o2) -> o1.compareTo(o2);
24
25 public static final Comparator<Double> LOWER_IS_BETTER = (o1, o2) -> o2.compareTo(o1);
26
27 private static final Double ZERO = Double.valueOf(0);
28
29 public static final Comparator<Double> DIFFERENCE_TO_ZERO_IS_BETTER = (o1, o2) -> ZERO.compareTo(Math.abs(o1)-Math.abs(o2));
30
31}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Fitness.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Fitness.java
new file mode 100644
index 00000000..8beef3bd
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Fitness.java
@@ -0,0 +1,29 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import java.util.HashMap;
12
13public class Fitness extends HashMap<String, Double>{
14
15 private boolean satisifiesHardObjectives;
16
17 public boolean isSatisifiesHardObjectives() {
18 return satisifiesHardObjectives;
19 }
20
21 public void setSatisifiesHardObjectives(boolean satisifiesHardObjectives) {
22 this.satisifiesHardObjectives = satisifiesHardObjectives;
23 }
24
25 @Override
26 public String toString() {
27 return super.toString() + " hardObjectives=" + satisifiesHardObjectives;
28 }
29}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IGlobalConstraint.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IGlobalConstraint.java
new file mode 100644
index 00000000..2f7f0347
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IGlobalConstraint.java
@@ -0,0 +1,58 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import org.eclipse.viatra.dse.base.ThreadContext;
12
13/**
14 *
15 * Implementation of this interface represents a global constraint of the DSE problem, which can halt an exploration
16 * continuing from a state which dissatisfies the global constraint.
17 * <p>
18 * Certain global constraints can have inner state for the validation. In this case a new instance is necessary for
19 * every new thread, and the {@code createNew} method should not return the same instance more than once.
20 *
21 * @author Andras Szabolcs Nagy
22 *
23 */
24public interface IGlobalConstraint {
25
26 /**
27 * Returns the name of the global constraint.
28 *
29 * @return The name of the global constraint.
30 */
31 String getName();
32
33 /**
34 * Checks whether the current state satisfies the global constraint.
35 *
36 * @param context
37 * The {@link ThreadContext} which contains the necessary information.
38 * @return True if the state is valid and exploration can be continued from the actual state.
39 */
40 boolean checkGlobalConstraint(ThreadContext context);
41
42 /**
43 * Initializes the global constraint. It is called exactly once for every thread starts.
44 *
45 * @param context
46 * The {@link ThreadContext}.
47 */
48 void init(ThreadContext context);
49
50 /**
51 * Returns an instance of the {@link IGlobalConstraint}. If it returns the same instance, all the methods has to be
52 * thread save as they are called concurrently.
53 *
54 * @return An instance of the global constraint.
55 */
56 IGlobalConstraint createNew();
57
58}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IObjective.java
new file mode 100644
index 00000000..849dd4e8
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IObjective.java
@@ -0,0 +1,110 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import java.util.Comparator;
12
13import org.eclipse.viatra.dse.base.ThreadContext;
14
15/**
16 *
17 * Implementation of this interface represents a single objective of the DSE problem, which can assess a solution
18 * (trajectory) in a single number. It has a name and a comparator which orders two solution based on the calculated
19 * value.
20 * <p>
21 * Objectives can be either hard or soft objectives. Hard objectives can be satisfied or unsatisfied. If all of the hard
22 * objectives are satisfied on a single solution, then it is considered to be a valid (or goal) solution.
23 * <p>
24 * Certain objectives can have inner state for calculating the fitness value. In this case a new instance is necessary
25 * for every new thread, and the {@code createNew} method should not return the same instance more than once.
26 *
27 * @author Andras Szabolcs Nagy
28 *
29 */
30public interface IObjective {
31
32 /**
33 * Returns the name of the objective.
34 *
35 * @return The name of the objective.
36 */
37 String getName();
38
39 /**
40 * Sets the {@link Comparator} which is used to compare fitness (doubles). It determines whether the objective is to
41 * minimize or maximize (or minimize or maximize a delta from a given number).
42 *
43 * @param comparator The comparator.
44 */
45 void setComparator(Comparator<Double> comparator);
46
47 /**
48 * Returns a {@link Comparator} which is used to compare fitness (doubles). It determines whether the objective is
49 * to minimize or maximize (or minimize or maximize a delta from a given number).
50 *
51 * @return The comparator.
52 */
53 Comparator<Double> getComparator();
54
55 /**
56 * Calculates the value of the objective on a given solution (trajectory).
57 *
58 * @param context
59 * The {@link ThreadContext}
60 * @return The objective value in double.
61 */
62 Double getFitness(ThreadContext context);
63
64 /**
65 * Initializes the objective. It is called exactly once for every thread starts.
66 *
67 * @param context
68 * The {@link ThreadContext}.
69 */
70 void init(ThreadContext context);
71
72 /**
73 * Returns an instance of the {@link IObjective}. If it returns the same instance, all the methods has to be thread
74 * save as they are called concurrently.
75 *
76 * @return An instance of the objective.
77 */
78 IObjective createNew();
79
80 /**
81 * Returns true if the objective is a hard objective. In such a case the method
82 * {@link IObjective#satisifiesHardObjective(Double)} is called.
83 *
84 * @return True if the objective is a hard objective.
85 * @see IObjective#satisifiesHardObjective(Double)
86 * @see IObjective
87 */
88 boolean isHardObjective();
89
90 /**
91 * Determines if the given fitness value satisfies the hard objective.
92 *
93 * @param fitness
94 * The fitness value of a solution.
95 * @return True if it satisfies the hard objective or it is a soft constraint.
96 * @see IObjective
97 */
98 boolean satisifiesHardObjective(Double fitness);
99
100 /**
101 * Set the level of the objective.
102 */
103 void setLevel(int level);
104
105 /**
106 * Gets the level of the objective.
107 */
108 int getLevel();
109
110}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/LeveledObjectivesHelper.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/LeveledObjectivesHelper.java
new file mode 100644
index 00000000..2d81629b
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/LeveledObjectivesHelper.java
@@ -0,0 +1,114 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import java.util.ArrayList;
12import java.util.Arrays;
13import java.util.Comparator;
14import java.util.List;
15
16public class LeveledObjectivesHelper {
17
18 private List<IObjective> objectives = new ArrayList<IObjective>();
19 private IObjective[][] leveledObjectives;
20
21 public LeveledObjectivesHelper(List<IObjective> objectives) {
22 this.objectives = objectives;
23 }
24
25 public IObjective[][] initLeveledObjectives() {
26 if (objectives.isEmpty()) {
27 leveledObjectives = new IObjective[0][0];
28 return leveledObjectives;
29 }
30
31 int level = objectives.get(0).getLevel();
32 boolean oneLevelOnly = true;
33 for (IObjective objective : objectives) {
34 if (objective.getLevel() != level) {
35 oneLevelOnly = false;
36 break;
37 }
38 }
39
40 if (oneLevelOnly) {
41 leveledObjectives = new IObjective[1][objectives.size()];
42 for (int i = 0; i < objectives.size(); i++) {
43 leveledObjectives[0][i] = objectives.get(i);
44 }
45 return leveledObjectives;
46 }
47
48 IObjective[] objectivesArray = getSortedByLevelObjectives(objectives);
49
50 int numberOfLevels = getNumberOfObjectiveLevels(objectivesArray);
51
52 leveledObjectives = new IObjective[numberOfLevels][];
53
54 fillLeveledObjectives(objectivesArray);
55
56 return leveledObjectives;
57 }
58
59 private void fillLeveledObjectives(IObjective[] objectivesArray) {
60 int actLevel = objectivesArray[0].getLevel();
61 int levelIndex = 0;
62 int lastIndex = 0;
63 int corrigationForLastLevel = 0;
64 boolean oneObjectiveAtLastLevel = false;
65 for (int i = 0; i < objectivesArray.length; i++) {
66 if (i == objectivesArray.length - 1) {
67 corrigationForLastLevel = 1;
68 if (objectivesArray[i - 1].getLevel() != objectivesArray[i].getLevel()) {
69 oneObjectiveAtLastLevel = true;
70 corrigationForLastLevel = 0;
71 }
72 }
73 if (objectivesArray[i].getLevel() != actLevel || corrigationForLastLevel == 1 || oneObjectiveAtLastLevel) {
74 leveledObjectives[levelIndex] = new IObjective[i - lastIndex + corrigationForLastLevel];
75 for (int j = lastIndex; j < i + corrigationForLastLevel; j++) {
76 leveledObjectives[levelIndex][j - lastIndex] = objectivesArray[j];
77 }
78 if (oneObjectiveAtLastLevel) {
79 leveledObjectives[levelIndex + 1] = new IObjective[1];
80 leveledObjectives[levelIndex + 1][0] = objectivesArray[i];
81 }
82 actLevel = objectivesArray[i].getLevel();
83 levelIndex++;
84 lastIndex = i;
85 }
86 }
87 }
88
89 private int getNumberOfObjectiveLevels(IObjective[] objectivesArray) {
90
91 int actLevel = objectivesArray[0].getLevel();
92 int numberOfLevels = 1;
93
94 for (int i = 1; i < objectivesArray.length; i++) {
95 if (objectivesArray[i].getLevel() != actLevel) {
96 numberOfLevels++;
97 actLevel = objectivesArray[i].getLevel();
98 }
99 }
100
101 return numberOfLevels;
102 }
103
104 private IObjective[] getSortedByLevelObjectives(List<IObjective> objectives) {
105 IObjective[] objectivesArray = objectives.toArray(new IObjective[objectives.size()]);
106 Arrays.sort(objectivesArray, Comparator.comparingInt(IObjective::getLevel));
107 return objectivesArray;
108 }
109
110 public IObjective[][] getLeveledObjectives() {
111 return leveledObjectives;
112 }
113
114}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ObjectiveComparatorHelper.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ObjectiveComparatorHelper.java
new file mode 100644
index 00000000..39139bb0
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ObjectiveComparatorHelper.java
@@ -0,0 +1,217 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import java.util.ArrayList;
12import java.util.Arrays;
13import java.util.HashMap;
14import java.util.List;
15import java.util.Map;
16import java.util.Random;
17
18import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
19
20/**
21 * This class is responsible to compare and sort fitness values. {@link TrajectoryFitness} instances can be added to an
22 * instance of this class, that it can sort them.
23 *
24 * @author András Szabolcs Nagy
25 */
26public class ObjectiveComparatorHelper {
27
28 private IObjective[][] leveledObjectives;
29 private List<TrajectoryFitness> trajectoryFitnesses = new ArrayList<TrajectoryFitness>();
30 private Random random = new Random();
31 private boolean computeCrowdingDistance = false;
32
33 public ObjectiveComparatorHelper(IObjective[][] leveledObjectives) {
34 this.leveledObjectives = leveledObjectives;
35 }
36
37 public void setComputeCrowdingDistance(boolean computeCrowdingDistance) {
38 this.computeCrowdingDistance = computeCrowdingDistance;
39 }
40
41 /**
42 * Compares two fitnesses based on hierarchical dominance. Returns -1 if the second parameter {@code o2} is a better
43 * solution ({@code o2} dominates {@code o1}), 1 if the first parameter {@code o1} is better ({@code o1} dominates
44 * {@code o2}) and returns 0 if they are non-dominating each other.
45 */
46 public int compare(Fitness o1, Fitness o2) {
47
48 levelsLoop: for (int i = 0; i < leveledObjectives.length; i++) {
49
50 boolean o1HasBetterFitness = false;
51 boolean o2HasBetterFitness = false;
52
53 for (IObjective objective : leveledObjectives[i]) {
54 String objectiveName = objective.getName();
55 int sgn = objective.getComparator().compare(o1.get(objectiveName), o2.get(objectiveName));
56
57 if (sgn < 0) {
58 o2HasBetterFitness = true;
59 }
60 if (sgn > 0) {
61 o1HasBetterFitness = true;
62 }
63 if (o1HasBetterFitness && o2HasBetterFitness) {
64 continue levelsLoop;
65 }
66 }
67 if (o2HasBetterFitness && !o1HasBetterFitness) {
68 return -1;
69 } else if (!o2HasBetterFitness && o1HasBetterFitness) {
70 return 1;
71 }
72 }
73
74 return 0;
75
76 }
77
78 /**
79 * Adds a {@link TrajectoryFitness} to an inner list to compare later.
80 *
81 * @param trajectoryFitness
82 */
83 public void addTrajectoryFitness(TrajectoryFitness trajectoryFitness) {
84 trajectoryFitnesses.add(trajectoryFitness);
85 }
86
87 /**
88 * Clears the inner {@link TrajectoryFitness} list.
89 */
90 public void clearTrajectoryFitnesses() {
91 trajectoryFitnesses.clear();
92 }
93
94 /**
95 * Returns the inner {@link TrajectoryFitness} list.
96 */
97 public List<TrajectoryFitness> getTrajectoryFitnesses() {
98 return trajectoryFitnesses;
99 }
100
101 /**
102 * Returns a random {@link TrajectoryFitness} from the pareto front.
103 */
104 public TrajectoryFitness getRandomBest() {
105 List<TrajectoryFitness> paretoFront = getParetoFront();
106 int randomIndex = random.nextInt(paretoFront.size());
107 return paretoFront.get(randomIndex);
108 }
109
110 /**
111 * Returns the pareto front of the previously added {@link TrajectoryFitness}.
112 */
113 public List<TrajectoryFitness> getParetoFront() {
114 return getFronts().get(0);
115 }
116
117 /**
118 * Returns the previously added {@link TrajectoryFitness} instances in fronts.
119 */
120 public List<? extends List<TrajectoryFitness>> getFronts() {
121 Preconditions.checkArgument(!trajectoryFitnesses.isEmpty(), "No trajectory fitnesses were added.");
122 List<ArrayList<TrajectoryFitness>> fronts = new ArrayList<ArrayList<TrajectoryFitness>>();
123
124 Map<TrajectoryFitness, ArrayList<TrajectoryFitness>> dominatedInstances = new HashMap<TrajectoryFitness, ArrayList<TrajectoryFitness>>();
125 Map<TrajectoryFitness, Integer> dominatingInstances = new HashMap<TrajectoryFitness, Integer>();
126
127 // calculate dominations
128 for (TrajectoryFitness TrajectoryFitnessP : trajectoryFitnesses) {
129 dominatedInstances.put(TrajectoryFitnessP, new ArrayList<TrajectoryFitness>());
130 dominatingInstances.put(TrajectoryFitnessP, 0);
131
132 for (TrajectoryFitness TrajectoryFitnessQ : trajectoryFitnesses) {
133 int dominates = compare(TrajectoryFitnessP.fitness, TrajectoryFitnessQ.fitness);
134 if (dominates > 0) {
135 dominatedInstances.get(TrajectoryFitnessP).add(TrajectoryFitnessQ);
136 } else if (dominates < 0) {
137 dominatingInstances.put(TrajectoryFitnessP, dominatingInstances.get(TrajectoryFitnessP) + 1);
138 }
139 }
140
141 if (dominatingInstances.get(TrajectoryFitnessP) == 0) {
142 // p belongs to the first front
143 TrajectoryFitnessP.rank = 1;
144 if (fronts.isEmpty()) {
145 ArrayList<TrajectoryFitness> firstDominationFront = new ArrayList<TrajectoryFitness>();
146 firstDominationFront.add(TrajectoryFitnessP);
147 fronts.add(firstDominationFront);
148 } else {
149 List<TrajectoryFitness> firstDominationFront = fronts.get(0);
150 firstDominationFront.add(TrajectoryFitnessP);
151 }
152 }
153 }
154
155 // create fronts
156 int i = 1;
157 while (fronts.size() == i) {
158 ArrayList<TrajectoryFitness> nextDominationFront = new ArrayList<TrajectoryFitness>();
159 for (TrajectoryFitness TrajectoryFitnessP : fronts.get(i - 1)) {
160 for (TrajectoryFitness TrajectoryFitnessQ : dominatedInstances.get(TrajectoryFitnessP)) {
161 dominatingInstances.put(TrajectoryFitnessQ, dominatingInstances.get(TrajectoryFitnessQ) - 1);
162 if (dominatingInstances.get(TrajectoryFitnessQ) == 0) {
163 TrajectoryFitnessQ.rank = i + 1;
164 nextDominationFront.add(TrajectoryFitnessQ);
165 }
166 }
167 }
168 i++;
169 if (!nextDominationFront.isEmpty()) {
170 if (computeCrowdingDistance) {
171 crowdingDistanceAssignment(nextDominationFront, leveledObjectives);
172 }
173 fronts.add(nextDominationFront);
174 }
175 }
176
177 return fronts;
178 }
179
180 /**
181 * Executes the crowding distance assignment for the specified front.
182 *
183 * @param front
184 */
185 public static void crowdingDistanceAssignment(List<TrajectoryFitness> front, IObjective[][] leveledObjectives) {
186
187 for (TrajectoryFitness InstanceData : front) {
188 // initialize crowding distance
189 InstanceData.crowdingDistance = 0;
190 }
191
192 for (final IObjective[] objectives : leveledObjectives) {
193 for (final IObjective objective : objectives) {
194
195 final String m = objective.getName();
196 TrajectoryFitness[] sortedFront = front.toArray(new TrajectoryFitness[0]);
197 // sort using m-th objective value
198 Arrays.sort(sortedFront, (o1, o2) -> objective.getComparator().compare(o1.fitness.get(m), o2.fitness.get(m)));
199 // so that boundary points are always selected
200 sortedFront[0].crowdingDistance = Double.POSITIVE_INFINITY;
201 sortedFront[sortedFront.length - 1].crowdingDistance = Double.POSITIVE_INFINITY;
202 // If minimal and maximal fitness value for this objective are
203 // equal, then do not change crowding distance
204 if (sortedFront[0].fitness.get(m) != sortedFront[sortedFront.length - 1].fitness.get(m)) {
205 for (int i = 1; i < sortedFront.length - 1; i++) {
206 double newCrowdingDistance = sortedFront[i].crowdingDistance;
207 newCrowdingDistance += (sortedFront[i + 1].fitness.get(m) - sortedFront[i - 1].fitness.get(m))
208 / (sortedFront[sortedFront.length - 1].fitness.get(m) - sortedFront[0].fitness.get(m));
209
210 sortedFront[i].crowdingDistance = newCrowdingDistance;
211 }
212 }
213 }
214 }
215 }
216
217}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/TrajectoryFitness.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/TrajectoryFitness.java
new file mode 100644
index 00000000..f783afac
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/TrajectoryFitness.java
@@ -0,0 +1,84 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import java.util.Arrays;
12import java.util.List;
13
14import org.eclipse.viatra.dse.designspace.api.TrajectoryInfo;
15
16/**
17 * This class represents a trajectory and its fitness.
18 * @author Andras Szabolcs Nagy
19 *
20 */
21public class TrajectoryFitness {
22
23 public Object[] trajectory;
24 public Fitness fitness;
25
26 public int rank;
27 public double crowdingDistance;
28
29 private int hash;
30
31 public int survive;
32
33 /**
34 * Creates a {@link TrajectoryFitness} with the full trajectory.
35 * @param trajectory The trajectory.
36 * @param fitness The fitness.
37 */
38 public TrajectoryFitness(Object[] trajectory, Fitness fitness) {
39 this.fitness = fitness;
40 this.trajectory = trajectory;
41 }
42
43 /**
44 * Creates a {@link TrajectoryFitness} with the full trajectory.
45 * @param trajectoryInfo The trajectory.
46 * @param fitness The fitness.
47 */
48 public TrajectoryFitness(TrajectoryInfo trajectoryInfo, Fitness fitness) {
49 this.fitness = fitness;
50 List<Object> fullTraj = trajectoryInfo.getTrajectory();
51 trajectory = fullTraj.toArray(new Object[fullTraj.size()]);
52 }
53
54 /**
55 * Creates a {@link TrajectoryFitness} with the given activation id}
56 * @param transition The transition.
57 * @param fitness The fitness.
58 */
59 public TrajectoryFitness(Object transition, Fitness fitness) {
60 this.fitness = fitness;
61 trajectory = new Object[] {transition};
62 }
63
64 @Override
65 public boolean equals(Object obj) {
66 if (obj instanceof TrajectoryFitness) {
67 return Arrays.equals(trajectory, ((TrajectoryFitness) obj).trajectory);
68 }
69 return false;
70 }
71
72 @Override
73 public int hashCode() {
74 if (hash == 0 && trajectory.length > 0) {
75 hash = Arrays.hashCode(trajectory);
76 }
77 return hash;
78 }
79
80 @Override
81 public String toString() {
82 return Arrays.toString(trajectory) + fitness.toString();
83 }
84}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/AlwaysSatisfiedDummyHardObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/AlwaysSatisfiedDummyHardObjective.java
new file mode 100644
index 00000000..9898a3b5
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/AlwaysSatisfiedDummyHardObjective.java
@@ -0,0 +1,52 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import org.eclipse.viatra.dse.base.ThreadContext;
12import org.eclipse.viatra.dse.objectives.IObjective;
13
14/**
15 * This hard objective is fulfilled in any circumstances. Use it if all states should be regarded as a valid solution.
16 *
17 * @author Andras Szabolcs Nagy
18 *
19 */
20public class AlwaysSatisfiedDummyHardObjective extends BaseObjective {
21
22 private static final String DEFAULT_NAME = "AlwaysSatisfiedDummyHardObjective";
23
24 public AlwaysSatisfiedDummyHardObjective() {
25 super(DEFAULT_NAME);
26 }
27
28 public AlwaysSatisfiedDummyHardObjective(String name) {
29 super(name);
30 }
31
32 @Override
33 public Double getFitness(ThreadContext context) {
34 return 0d;
35 }
36
37 @Override
38 public boolean isHardObjective() {
39 return true;
40 }
41
42 @Override
43 public boolean satisifiesHardObjective(Double fitness) {
44 return true;
45 }
46
47 @Override
48 public IObjective createNew() {
49 return this;
50 }
51
52}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/BaseObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/BaseObjective.java
new file mode 100644
index 00000000..0a1de875
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/BaseObjective.java
@@ -0,0 +1,150 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import java.util.Comparator;
12import java.util.Objects;
13
14import org.eclipse.viatra.dse.base.ThreadContext;
15import org.eclipse.viatra.dse.objectives.Comparators;
16import org.eclipse.viatra.dse.objectives.IObjective;
17
18/**
19 * This abstract class implements the basic functionality of an objective ({@link IObjective} namely its name,
20 * comparator, level and fitness hard constraint.
21 *
22 * @author Andras Szabolcs Nagy
23 *
24 */
25public abstract class BaseObjective implements IObjective {
26
27 protected final String name;
28 protected Comparator<Double> comparator = Comparators.HIGHER_IS_BETTER;
29 protected int level = 0;
30
31 protected double fitnessConstraint;
32 protected boolean isThereFitnessConstraint = false;
33 protected Comparator<Double> fitnessConstraintComparator;
34
35 public BaseObjective(String name) {
36 Objects.requireNonNull(name, "Name of the objective cannot be null.");
37 this.name = name;
38 }
39
40 @Override
41 public String getName() {
42 return name;
43 }
44
45 @Override
46 public void setComparator(Comparator<Double> comparator) {
47 this.comparator = comparator;
48 }
49
50 @Override
51 public Comparator<Double> getComparator() {
52 return comparator;
53 }
54
55 @Override
56 public void setLevel(int level) {
57 this.level = level;
58 }
59
60 @Override
61 public int getLevel() {
62 return level;
63 }
64
65 public BaseObjective withLevel(int level) {
66 setLevel(level);
67 return this;
68 }
69
70 public BaseObjective withComparator(Comparator<Double> comparator) {
71 setComparator(comparator);
72 return this;
73 }
74
75 /**
76 * Adds a hard constraint on the fitness value. For example, the fitness value must be better than 10 to accept the
77 * current state as a solution.
78 *
79 * @param fitnessConstraint
80 * Solutions should be better than this value.
81 * @param fitnessConstraintComparator
82 * {@link Comparator} to determine if the current state is better than the given value.
83 * @return The actual instance to enable builder pattern like usage.
84 */
85 public BaseObjective withHardConstraintOnFitness(double fitnessConstraint,
86 Comparator<Double> fitnessConstraintComparator) {
87 this.fitnessConstraint = fitnessConstraint;
88 this.fitnessConstraintComparator = fitnessConstraintComparator;
89 this.isThereFitnessConstraint = true;
90 return this;
91 }
92
93 /**
94 * Adds a hard constraint on the fitness value. For example, the fitness value must be better than 10 to accept the
95 * current state as a solution. The provided comparator will be used.
96 *
97 * @param fitnessConstraint
98 * Solutions should be better than this value.
99 * @return The actual instance to enable builder pattern like usage.
100 */
101 public BaseObjective withHardConstraintOnFitness(double fitnessConstraint) {
102 return withHardConstraintOnFitness(fitnessConstraint, null);
103 }
104
105 @Override
106 public void init(ThreadContext context) {
107 if (fitnessConstraintComparator == null) {
108 fitnessConstraintComparator = comparator;
109 }
110 }
111
112 @Override
113 public boolean isHardObjective() {
114 return isThereFitnessConstraint;
115 }
116
117 @Override
118 public boolean satisifiesHardObjective(Double fitness) {
119 if (isThereFitnessConstraint) {
120 int compare = fitnessConstraintComparator.compare(fitness, fitnessConstraint);
121 if (compare < 0) {
122 return false;
123 }
124 }
125 return true;
126 }
127
128 @Override
129 public int hashCode() {
130 return name.hashCode();
131 }
132
133 @Override
134 public boolean equals(Object obj) {
135 if (this == obj) {
136 return true;
137 }
138 if (obj instanceof BaseObjective) {
139 BaseObjective baseObjective = (BaseObjective) obj;
140 return name.equals(baseObjective.getName());
141 }
142 return false;
143 }
144
145 @Override
146 public String toString() {
147 return name;
148 }
149
150}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/CompositeObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/CompositeObjective.java
new file mode 100644
index 00000000..cc48d22e
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/CompositeObjective.java
@@ -0,0 +1,137 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import java.util.ArrayList;
12import java.util.List;
13import java.util.Objects;
14
15import org.eclipse.viatra.dse.base.ThreadContext;
16import org.eclipse.viatra.dse.objectives.IObjective;
17import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
18
19/**
20 * This objective collects a list of other objectives. It returns the weighted sum of the objectives.
21 *
22 * @author Andras Szabolcs Nagy
23 *
24 */
25public class CompositeObjective extends BaseObjective {
26
27 public static final String DEFAULT_NAME = "CompositeObjective";
28 protected List<IObjective> objectives;
29 protected List<Double> weights;
30 protected boolean hardObjective;
31
32 public CompositeObjective(String name, List<IObjective> objectives, List<Double> weights) {
33 super(name);
34 Objects.requireNonNull(objectives, "The list of objectives cannot be null.");
35 Objects.requireNonNull(weights, "The list of weights cannot be null.");
36 Preconditions.checkState(objectives.size() == weights.size(), "The size of the objectives and weights must match.");
37 this.objectives = objectives;
38 this.weights = weights;
39 }
40
41 public CompositeObjective(List<IObjective> objectives, List<Double> weights) {
42 this(DEFAULT_NAME, objectives, weights);
43 }
44
45 public CompositeObjective(String name) {
46 this(name, new ArrayList<IObjective>(), new ArrayList<Double>());
47 }
48
49 public CompositeObjective() {
50 this(DEFAULT_NAME, new ArrayList<IObjective>(), new ArrayList<Double>());
51 }
52
53 /**
54 * Adds a new objective.
55 *
56 * @param objective
57 * @return The actual instance to enable builder pattern like usage.
58 */
59 public CompositeObjective withObjective(IObjective objective) {
60 objectives.add(objective);
61 weights.add(1d);
62 return this;
63 }
64
65 /**
66 * Adds a new objective.
67 *
68 * @param objective
69 * @return The actual instance to enable builder pattern like usage.
70 */
71 public CompositeObjective withObjective(IObjective objective, double weight) {
72 objectives.add(objective);
73 weights.add(weight);
74 return this;
75 }
76
77 @Override
78 public Double getFitness(ThreadContext context) {
79
80 double result = 0;
81
82 for (int i = 0; i < objectives.size(); i++) {
83 IObjective objective = objectives.get(i);
84 Double weight = weights.get(i);
85 result += objective.getFitness(context) * weight;
86 }
87 return result;
88 }
89
90 @Override
91 public void init(ThreadContext context) {
92 super.init(context);
93 hardObjective = false;
94 for (IObjective objective : objectives) {
95 objective.init(context);
96 if (objective.isHardObjective()) {
97 hardObjective = true;
98 }
99 }
100 }
101
102 @Override
103 public IObjective createNew() {
104
105 List<IObjective> newObjectives = new ArrayList<IObjective>();
106
107 for (IObjective objective : objectives) {
108 newObjectives.add(objective.createNew());
109 }
110
111 CompositeObjective objective = new CompositeObjective(name, newObjectives, weights);
112 if (isThereFitnessConstraint) {
113 objective.withHardConstraintOnFitness(fitnessConstraint, fitnessConstraintComparator);
114 }
115
116 return objective.withComparator(comparator).withLevel(level);
117 }
118
119 @Override
120 public boolean isHardObjective() {
121 return hardObjective;
122 }
123
124 @Override
125 public boolean satisifiesHardObjective(Double fitness) {
126
127 boolean hardObjectiveSatisfied = true;
128
129 for (IObjective objective : objectives) {
130 hardObjectiveSatisfied = objective.satisifiesHardObjective(fitness) ? hardObjectiveSatisfied : false;
131 }
132
133 hardObjectiveSatisfied = super.satisifiesHardObjective(fitness) ? hardObjectiveSatisfied : false;
134
135 return hardObjectiveSatisfied;
136 }
137}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ConstraintsObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ConstraintsObjective.java
new file mode 100644
index 00000000..77d416f5
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ConstraintsObjective.java
@@ -0,0 +1,316 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import java.util.ArrayList;
12import java.util.List;
13import java.util.Objects;
14
15import org.eclipse.viatra.dse.api.DSEException;
16import org.eclipse.viatra.dse.base.ThreadContext;
17import org.eclipse.viatra.dse.objectives.IObjective;
18import org.eclipse.viatra.query.runtime.api.IPatternMatch;
19import org.eclipse.viatra.query.runtime.api.IQuerySpecification;
20import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
21import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher;
22import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
23
24/**
25 * This objective serves as soft and as hard objective at the same time by defining two lists of VIATRA Query
26 * specifications.
27 *
28 * As a soft objective, it collects a list of VIATRA Query specifications, which have predefined weights. Then the
29 * fitness value of an arbitrary solution is calculated in the following way:
30 * <p>
31 * <code>fitness = sum( pattern[i].countMatches() * weight[i] )</code>
32 * <p>
33 * As a hard objective it collects a separate list of VIATRA Query specifications. If every one of them has a match the
34 * hard constraint is considered to be fulfilled.
35 *
36 * @author Andras Szabolcs Nagy
37 * @see IObjective
38 *
39 */
40public class ConstraintsObjective extends BaseObjective {
41
42 public static final String DEFAULT_NAME = "ConstraintsObjective";
43
44 public static class QueryConstraint {
45 public final String name;
46 public final IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> query;
47 public final Double weight;
48 public final ModelQueryType type;
49
50 public QueryConstraint(String name,
51 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> query, Double weight,
52 ModelQueryType type) {
53 this.name = name;
54 this.query = query;
55 this.weight = weight;
56 this.type = type;
57 }
58
59 public QueryConstraint(String name,
60 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> query, Double weight) {
61 this(name, query, weight, ModelQueryType.MUST_HAVE_MATCH);
62 }
63
64 public QueryConstraint(String name,
65 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> query, ModelQueryType type) {
66 this(name, query, 0d, type);
67 }
68 }
69
70 protected List<QueryConstraint> softConstraints;
71 protected List<QueryConstraint> hardConstraints;
72
73 protected List<ViatraQueryMatcher<? extends IPatternMatch>> softMatchers;
74 protected List<ViatraQueryMatcher<? extends IPatternMatch>> hardMatchers;
75 protected List<Integer> softMatches;
76 protected List<Integer> hardMatches;
77
78 public ConstraintsObjective(String name, List<QueryConstraint> softConstraints,
79 List<QueryConstraint> hardConstraints) {
80 super(name);
81 Objects.requireNonNull(softConstraints, "The list of soft constraints cannot be null.");
82 Objects.requireNonNull(hardConstraints, "The list of hard constraints cannot be null.");
83
84 this.softConstraints = softConstraints;
85 this.hardConstraints = hardConstraints;
86 }
87
88 public ConstraintsObjective(String name, List<QueryConstraint> hardConstraints) {
89 this(name, new ArrayList<QueryConstraint>(), hardConstraints);
90 }
91
92 public ConstraintsObjective(List<QueryConstraint> hardConstraints) {
93 this(DEFAULT_NAME, new ArrayList<QueryConstraint>(), hardConstraints);
94 }
95
96 public ConstraintsObjective(String name) {
97 this(name, new ArrayList<QueryConstraint>(), new ArrayList<QueryConstraint>());
98 }
99
100 public ConstraintsObjective() {
101 this(DEFAULT_NAME, new ArrayList<QueryConstraint>(), new ArrayList<QueryConstraint>());
102 }
103
104 /**
105 * Adds a new soft constraint.
106 *
107 * @param name
108 * A name for the soft constraint.
109 * @param softConstraint
110 * A VIATRA Query pattern specification.
111 * @param weight
112 * The weight of the pattern.
113 * @return The actual instance to enable builder pattern like usage.
114 */
115 public ConstraintsObjective withSoftConstraint(String name,
116 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> softConstraint, double weight) {
117 softConstraints.add(new QueryConstraint(name, softConstraint, weight));
118 return this;
119 }
120
121 /**
122 * Adds a new soft constraint with the name of the query specification's fully qualified name.
123 *
124 * @param softConstraint
125 * A VIATRA Query pattern specification.
126 * @param weight
127 * The weight of the pattern.
128 * @return The actual instance to enable builder pattern like usage.
129 */
130 public ConstraintsObjective withSoftConstraint(
131 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> softConstraint, double weight) {
132 return withSoftConstraint(softConstraint.getFullyQualifiedName(), softConstraint, weight);
133 }
134
135 /**
136 * Adds a new hard constraint.
137 *
138 * @param name
139 * A name for the hard constraint.
140 * @param softConstraint
141 * A VIATRA Query pattern specification.
142 * @param type
143 * {@link ModelQueryType}, which determines whether the constraint should have at least one match or none
144 * at all.
145 * @return The actual instance to enable builder pattern like usage.
146 */
147 public ConstraintsObjective withHardConstraint(String name,
148 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hardConstraint,
149 ModelQueryType type) {
150 hardConstraints.add(new QueryConstraint(name, hardConstraint, type));
151 return this;
152 }
153
154 /**
155 * Adds a new hard constraint with the default {@link ModelQueryType#MUST_HAVE_MATCH}.
156 *
157 * @param name
158 * A name for the hard constraint.
159 * @param softConstraint
160 * A VIATRA Query pattern specification.
161 * @return The actual instance to enable builder pattern like usage.
162 */
163 public ConstraintsObjective withHardConstraint(String name,
164 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hardConstraint) {
165 hardConstraints.add(new QueryConstraint(name, hardConstraint, ModelQueryType.MUST_HAVE_MATCH));
166 return this;
167 }
168
169 /**
170 * Adds a new hard constraint with the name of the query specification's fully qualified name and the default
171 * {@link ModelQueryType#MUST_HAVE_MATCH}.
172 *
173 * @param softConstraint
174 * A VIATRA Query pattern specification.
175 * @return The actual instance to enable builder pattern like usage.
176 */
177 public ConstraintsObjective withHardConstraint(
178 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hardConstraint) {
179 return withHardConstraint(hardConstraint.getFullyQualifiedName(), hardConstraint,
180 ModelQueryType.MUST_HAVE_MATCH);
181 }
182
183 /**
184 * Adds a new hard constraint with the name of the query specification's fully qualified name.
185 *
186 * @param softConstraint
187 * A VIATRA Query pattern specification.
188 * @param type
189 * {@link ModelQueryType}, which determines whether the constraint should have at least one match or none
190 * at all.
191 * @return The actual instance to enable builder pattern like usage.
192 */
193 public ConstraintsObjective withHardConstraint(
194 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hardConstraint,
195 ModelQueryType type) {
196 return withHardConstraint(hardConstraint.getFullyQualifiedName(), hardConstraint, type);
197 }
198
199 @Override
200 public Double getFitness(ThreadContext context) {
201
202 if (softConstraints.isEmpty()) {
203 return 0d;
204 }
205
206 double result = 0;
207
208 for (int i = 0; i < softConstraints.size(); i++) {
209 int countMatches = softMatchers.get(i).countMatches();
210 result += countMatches * softConstraints.get(i).weight;
211 softMatches.set(i, Integer.valueOf(countMatches));
212 }
213
214 return result;
215 }
216
217 @Override
218 public void init(ThreadContext context) {
219
220 super.init(context);
221
222 softMatches = new ArrayList<Integer>(softConstraints.size());
223 softMatchers = new ArrayList<ViatraQueryMatcher<? extends IPatternMatch>>(softConstraints.size());
224 hardMatches = new ArrayList<Integer>(hardConstraints.size());
225 hardMatchers = new ArrayList<ViatraQueryMatcher<? extends IPatternMatch>>(hardConstraints.size());
226 for (int i = 0; i < softConstraints.size(); i++) {
227 softMatches.add(0);
228 }
229 for (int i = 0; i < hardConstraints.size(); i++) {
230 hardMatches.add(0);
231 }
232
233 try {
234 ViatraQueryEngine queryEngine = context.getQueryEngine();
235
236 for (QueryConstraint qc : softConstraints) {
237 softMatchers.add(qc.query.getMatcher(queryEngine));
238 }
239
240 for (QueryConstraint qc : hardConstraints) {
241 hardMatchers.add(qc.query.getMatcher(queryEngine));
242 }
243
244 } catch (ViatraQueryException e) {
245 throw new DSEException("Couldn't initialize the VIATRA Query matcher, see inner exception", e);
246 }
247 }
248
249 @Override
250 public IObjective createNew() {
251 new ArrayList<Double>(softConstraints.size());
252 ConstraintsObjective result = new ConstraintsObjective(name, softConstraints, hardConstraints);
253 if (isThereFitnessConstraint) {
254 result.withHardConstraintOnFitness(fitnessConstraint, fitnessConstraintComparator);
255 }
256 return result.withComparator(comparator).withLevel(level);
257 }
258
259 @Override
260 public boolean isHardObjective() {
261 return !hardConstraints.isEmpty() || super.isHardObjective();
262 }
263
264 @Override
265 public boolean satisifiesHardObjective(Double fitness) {
266
267 boolean result = true;
268
269 for (int i = 0; i < hardConstraints.size(); i++) {
270 ModelQueryType type = hardConstraints.get(i).type;
271 int countMatches = hardMatchers.get(i).countMatches();
272 hardMatches.set(i, Integer.valueOf(countMatches));
273 if ((type.equals(ModelQueryType.MUST_HAVE_MATCH) && countMatches <= 0)
274 || (type.equals(ModelQueryType.NO_MATCH) && countMatches > 0)) {
275 result = false;
276 }
277 }
278
279 result = super.satisifiesHardObjective(fitness) ? result : false;
280
281 return result;
282 }
283
284 public List<QueryConstraint> getSoftConstraints() {
285 return softConstraints;
286 }
287
288 public List<QueryConstraint> getHardConstraints() {
289 return hardConstraints;
290 }
291
292 public String getSoftName(int index) {
293 return softConstraints.get(index).name;
294 }
295
296 public String getHardName(int index) {
297 return hardConstraints.get(index).name;
298 }
299
300 public List<Integer> getSoftMatches() {
301 return softMatches;
302 }
303
304 public List<Integer> getHardMatches() {
305 return hardMatches;
306 }
307
308 public List<String> getSoftNames() {
309 List<String> softNames = new ArrayList<>(softConstraints.size());
310 for (QueryConstraint qc : softConstraints) {
311 softNames.add(qc.name);
312 }
313 return softNames;
314 }
315
316}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/DepthHardObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/DepthHardObjective.java
new file mode 100644
index 00000000..b21da397
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/DepthHardObjective.java
@@ -0,0 +1,89 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import org.eclipse.viatra.dse.base.ThreadContext;
12import org.eclipse.viatra.dse.objectives.IObjective;
13
14/**
15 * This hard objective is fulfilled if the trajectory is in the specified interval (inclusive).
16 *
17 * @author Andras Szabolcs Nagy
18 *
19 */
20public class DepthHardObjective extends BaseObjective {
21
22 private static final String DEFAULT_NAME = "DepthHardObjective";
23 protected int minDepth;
24 protected int maxDepth;
25 private ThreadContext context;
26
27 public DepthHardObjective() {
28 this(DEFAULT_NAME, 0, Integer.MAX_VALUE);
29 }
30
31 public DepthHardObjective(String name) {
32 this(name, 0, Integer.MAX_VALUE);
33 }
34
35 public DepthHardObjective(int minDepth) {
36 this(DEFAULT_NAME, minDepth, Integer.MAX_VALUE);
37 }
38
39 public DepthHardObjective(String name, int minDepth) {
40 this(name, minDepth, Integer.MAX_VALUE);
41 }
42
43 public DepthHardObjective(int minDepth, int maxDepth) {
44 this(DEFAULT_NAME, minDepth, maxDepth);
45 }
46
47 public DepthHardObjective(String name, int minDepth, int maxDepth) {
48 super(name);
49 this.minDepth = minDepth;
50 this.maxDepth = maxDepth;
51 }
52
53 public DepthHardObjective withMinDepth(int minDepth) {
54 this.minDepth = minDepth;
55 return this;
56 }
57
58 public DepthHardObjective withMaxDepth(int maxDepth) {
59 this.maxDepth = maxDepth;
60 return this;
61 }
62
63 @Override
64 public void init(ThreadContext context) {
65 super.init(context);
66 this.context = context;
67 }
68
69 @Override
70 public Double getFitness(ThreadContext context) {
71 return 0d;
72 }
73
74 @Override
75 public boolean isHardObjective() {
76 return true;
77 }
78
79 @Override
80 public boolean satisifiesHardObjective(Double fitness) {
81 return minDepth <= context.getDepth() && context.getDepth() <= maxDepth;
82 }
83
84 @Override
85 public IObjective createNew() {
86 return new DepthHardObjective(name, minDepth, maxDepth);
87 }
88
89}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueriesGlobalConstraint.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueriesGlobalConstraint.java
new file mode 100644
index 00000000..7616b4a2
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueriesGlobalConstraint.java
@@ -0,0 +1,116 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import java.util.ArrayList;
12import java.util.List;
13import java.util.Objects;
14
15import org.eclipse.viatra.dse.api.DSEException;
16import org.eclipse.viatra.dse.base.ThreadContext;
17import org.eclipse.viatra.dse.objectives.IGlobalConstraint;
18import org.eclipse.viatra.query.runtime.api.IPatternMatch;
19import org.eclipse.viatra.query.runtime.api.IQuerySpecification;
20import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
21import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher;
22import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
23
24/**
25 * This global constraint collects a list of VIATRA Query pattern and checks if any of them has a match on along a trajectory.
26 * If any of the patterns has a match then it is unsatisfied and the exploration should backtrack.
27 *
28 * @author Andras Szabolcs Nagy
29 *
30 */
31public class ModelQueriesGlobalConstraint implements IGlobalConstraint {
32
33 public static final String GLOBAL_CONSTRAINT = "GlobalConstraint";
34 protected String name;
35 protected List<IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> constraints;
36 protected List<ViatraQueryMatcher<? extends IPatternMatch>> matchers = new ArrayList<ViatraQueryMatcher<? extends IPatternMatch>>();
37 protected ModelQueryType type = ModelQueryType.NO_MATCH;
38
39 public ModelQueriesGlobalConstraint(String name,
40 List<IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> constraints) {
41 Objects.requireNonNull(name, "Name of the global constraint cannot be null.");
42 Objects.requireNonNull(constraints, "The list of constraints cannot be null.");
43
44 this.name = name;
45 this.constraints = constraints;
46 }
47
48 public ModelQueriesGlobalConstraint(
49 List<IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> constraints) {
50 this(GLOBAL_CONSTRAINT, constraints);
51 }
52
53 public ModelQueriesGlobalConstraint(String name) {
54 this(name, new ArrayList<IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>>());
55 }
56
57 public ModelQueriesGlobalConstraint() {
58 this(GLOBAL_CONSTRAINT,
59 new ArrayList<IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>>());
60 }
61
62 /**
63 * Adds a new VIATRA Query pattern.
64 *
65 * @param constraint
66 * A VIATRA Query pattern.
67 * @return The actual instance to enable builder pattern like usage.
68 */
69 public ModelQueriesGlobalConstraint withConstraint(
70 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> constraint) {
71 constraints.add(constraint);
72 return this;
73 }
74
75 public ModelQueriesGlobalConstraint withType(ModelQueryType type) {
76 this.type = type;
77 return this;
78 }
79
80 @Override
81 public String getName() {
82 return name;
83 }
84
85 @Override
86 public boolean checkGlobalConstraint(ThreadContext context) {
87 for (ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) {
88 if ((type.equals(ModelQueryType.NO_MATCH) && matcher.countMatches() > 0)
89 || (type.equals(ModelQueryType.MUST_HAVE_MATCH) && matcher.countMatches() == 0)) {
90 return false;
91 }
92 }
93 return true;
94 }
95
96 @Override
97 public void init(ThreadContext context) {
98 try {
99 ViatraQueryEngine queryEngine = context.getQueryEngine();
100
101 for (IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification : constraints) {
102 ViatraQueryMatcher<? extends IPatternMatch> matcher = querySpecification.getMatcher(queryEngine);
103 matchers.add(matcher);
104 }
105
106 } catch (ViatraQueryException e) {
107 throw new DSEException("Couldn't get the VIATRA Query matcher, see inner exception", e);
108 }
109 }
110
111 @Override
112 public IGlobalConstraint createNew() {
113 return new ModelQueriesGlobalConstraint(name, constraints);
114 }
115
116}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueryType.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueryType.java
new file mode 100644
index 00000000..76390352
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueryType.java
@@ -0,0 +1,14 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11public enum ModelQueryType {
12 MUST_HAVE_MATCH,
13 NO_MATCH
14}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NeverSatisfiedDummyHardObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NeverSatisfiedDummyHardObjective.java
new file mode 100644
index 00000000..27cf139c
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NeverSatisfiedDummyHardObjective.java
@@ -0,0 +1,52 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import org.eclipse.viatra.dse.base.ThreadContext;
12import org.eclipse.viatra.dse.objectives.IObjective;
13
14/**
15 * This hard objective is never fulfilled. Use it if all states should be regarded as an invalid solution.
16 *
17 * @author Andras Szabolcs Nagy
18 *
19 */
20public class NeverSatisfiedDummyHardObjective extends BaseObjective {
21
22 private static final String DEFAULT_NAME = "NeverSatisfiedDummyHardObjective";
23
24 public NeverSatisfiedDummyHardObjective() {
25 super(DEFAULT_NAME);
26 }
27
28 public NeverSatisfiedDummyHardObjective(String name) {
29 super(name);
30 }
31
32 @Override
33 public Double getFitness(ThreadContext context) {
34 return 0d;
35 }
36
37 @Override
38 public boolean isHardObjective() {
39 return true;
40 }
41
42 @Override
43 public boolean satisifiesHardObjective(Double fitness) {
44 return false;
45 }
46
47 @Override
48 public IObjective createNew() {
49 return this;
50 }
51
52}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NoRuleActivationsHardObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NoRuleActivationsHardObjective.java
new file mode 100644
index 00000000..756d94ec
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NoRuleActivationsHardObjective.java
@@ -0,0 +1,59 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import org.eclipse.viatra.dse.base.ThreadContext;
12import org.eclipse.viatra.dse.objectives.IObjective;
13
14/**
15 * This hard objective is satisfied if there are no rule activations from the current state (returning 1 in this case).
16 *
17 * @author Andras Szabolcs Nagy
18 *
19 */
20public class NoRuleActivationsHardObjective extends BaseObjective {
21
22 protected static final String DEFAULT_NAME = "NoMoreActivationHardObjective";
23 private ThreadContext context;
24
25 public NoRuleActivationsHardObjective(String name) {
26 super(name);
27 }
28
29 public NoRuleActivationsHardObjective() {
30 this(DEFAULT_NAME);
31 }
32
33 @Override
34 public Double getFitness(ThreadContext context) {
35 return 0d;
36 }
37
38 @Override
39 public void init(ThreadContext context) {
40 super.init(context);
41 this.context = context;
42 }
43
44 @Override
45 public IObjective createNew() {
46 return new NoRuleActivationsHardObjective(name);
47 }
48
49 @Override
50 public boolean isHardObjective() {
51 return true;
52 }
53
54 @Override
55 public boolean satisifiesHardObjective(Double fitness) {
56 return context.getConflictSet().getNextActivations().isEmpty();
57 }
58
59}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/TrajectoryCostSoftObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/TrajectoryCostSoftObjective.java
new file mode 100644
index 00000000..25ff45ae
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/TrajectoryCostSoftObjective.java
@@ -0,0 +1,148 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import java.util.HashMap;
12import java.util.List;
13import java.util.Map;
14import java.util.Map.Entry;
15import java.util.Objects;
16
17import org.eclipse.viatra.dse.base.DesignSpaceManager;
18import org.eclipse.viatra.dse.base.ThreadContext;
19import org.eclipse.viatra.dse.designspace.api.TrajectoryInfo;
20import org.eclipse.viatra.dse.objectives.ActivationFitnessProcessor;
21import org.eclipse.viatra.dse.objectives.Comparators;
22import org.eclipse.viatra.dse.objectives.IObjective;
23import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
24import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
25
26/**
27 * This soft objective calculates a fitness value based on the length of the trajectory. Costs to the rules can be
28 * assigned.
29 *
30 * @author Andras Szabolcs Nagy
31 *
32 */
33public class TrajectoryCostSoftObjective extends BaseObjective {
34
35 public static final String DEFAULT_NAME = "TrajectoryCostObjective";
36 protected Map<BatchTransformationRule<?, ?>, Double> fixCosts;
37 protected Map<BatchTransformationRule<?, ?>, ActivationFitnessProcessor> activationCostProcessors;
38 protected double trajectoryLengthWeight = 0.0;
39 protected boolean calculateTrajectoryLengthWeight;
40
41 public TrajectoryCostSoftObjective(String name) {
42 super(name);
43 comparator = Comparators.LOWER_IS_BETTER;
44 }
45
46 public TrajectoryCostSoftObjective() {
47 this(DEFAULT_NAME);
48 }
49
50 /**
51 * Sets the cost of a rule.
52 *
53 * @param rule
54 * @param cost
55 * @return The actual instance to enable builder pattern like usage.
56 */
57 public TrajectoryCostSoftObjective withRuleCost(BatchTransformationRule<?, ?> rule, double cost) {
58 Objects.requireNonNull(rule);
59 if (fixCosts == null) {
60 fixCosts = new HashMap<BatchTransformationRule<?, ?>, Double>();
61 }
62 Preconditions.checkArgument(!fixCosts.containsKey(rule));
63 fixCosts.put(rule, cost);
64 return this;
65 }
66
67 /**
68 * Sets an activation processor for a rule.
69 *
70 * @param rule
71 * @param activationCostProcessor
72 * @return The actual instance to enable builder pattern like usage.
73 */
74 public TrajectoryCostSoftObjective withActivationCost(BatchTransformationRule<?, ?> rule,
75 ActivationFitnessProcessor activationCostProcessor) {
76 Objects.requireNonNull(rule);
77 Objects.requireNonNull(activationCostProcessor);
78 if (activationCostProcessors == null) {
79 activationCostProcessors = new HashMap<BatchTransformationRule<?, ?>, ActivationFitnessProcessor>();
80 }
81 Preconditions.checkArgument(!activationCostProcessors.containsKey(rule));
82 activationCostProcessors.put(rule, activationCostProcessor);
83 return this;
84 }
85
86 /**
87 * The length of the trajectory multiplied with given parameter will be added to the fitness value.
88 *
89 * @param trajectoryLengthWeight
90 * The weight of a transformation rule application.
91 * @return The actual instance to enable builder pattern like usage.
92 */
93 public TrajectoryCostSoftObjective withTrajectoryLengthWeight(double trajectoryLengthWeight) {
94 this.trajectoryLengthWeight = trajectoryLengthWeight;
95 this.calculateTrajectoryLengthWeight = true;
96 return this;
97 }
98
99 @Override
100 public Double getFitness(ThreadContext context) {
101
102 DesignSpaceManager dsm = context.getDesignSpaceManager();
103 TrajectoryInfo trajectoryInfo = dsm.getTrajectoryInfo();
104 List<Object> trajectory = trajectoryInfo.getTrajectory();
105 List<BatchTransformationRule<?, ?>> rules = trajectoryInfo.getRules();
106
107 double result = 0;
108
109 for (int i = 0; i < trajectory.size(); i++) {
110 BatchTransformationRule<?, ?> rule = rules.get(i);
111
112 Double cost = fixCosts.get(rule);
113 if (cost != null) {
114 result += cost;
115 }
116
117 Map<String, Double> costs = trajectoryInfo.getMeasuredCosts().get(i);
118 if (costs != null) {
119 cost = costs.get(name);
120 if (cost != null) {
121 result += cost;
122 }
123 }
124 }
125
126 if (calculateTrajectoryLengthWeight) {
127 result += trajectory.size() * trajectoryLengthWeight;
128 }
129
130 return result;
131 }
132
133 @Override
134 public void init(ThreadContext context) {
135 super.init(context);
136 DesignSpaceManager dsm = context.getDesignSpaceManager();
137 if (activationCostProcessors != null) {
138 for (Entry<BatchTransformationRule<?, ?>, ActivationFitnessProcessor> entry : activationCostProcessors.entrySet()) {
139 dsm.registerActivationCostProcessor(name, entry.getKey(), entry.getValue());
140 }
141 }
142 }
143
144 @Override
145 public IObjective createNew() {
146 return this;
147 }
148}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionFoundHandler.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionFoundHandler.java
new file mode 100644
index 00000000..8d74e856
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionFoundHandler.java
@@ -0,0 +1,40 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11import org.eclipse.viatra.dse.api.SolutionTrajectory;
12import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
13import org.eclipse.viatra.dse.base.ThreadContext;
14import org.eclipse.viatra.dse.solutionstore.SolutionStore.ISolutionSaver;
15
16/**
17 * Contains callback methods which are called when a solution is found by the exploration {@link IStrategy}.
18 *
19 * @author Andras Szabolcs Nagy
20 *
21 */
22public interface ISolutionFoundHandler {
23
24 /**
25 * Called when a solution is saved by the {@link ISolutionSaver}. Later, this solution can be omitted from the final
26 * set of solutions.
27 *
28 * @param context
29 * @param trajectory
30 */
31 void solutionFound(ThreadContext context, SolutionTrajectory trajectory);
32
33 /**
34 * Called when the exploration found a solution but it was not saved because of certain conditions.
35 *
36 * @param context
37 * @param trajectory
38 */
39 void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory);
40} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionNameProvider.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionNameProvider.java
new file mode 100644
index 00000000..36e6b5b7
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionNameProvider.java
@@ -0,0 +1,18 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11/**
12 * Provides file name when a model is searialzed.
13 * @author Andras Szabolcs Nagy
14 *
15 */
16public interface ISolutionNameProvider {
17 String getName();
18} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/IdBasedSolutionNameProvider.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/IdBasedSolutionNameProvider.java
new file mode 100644
index 00000000..43460015
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/IdBasedSolutionNameProvider.java
@@ -0,0 +1,37 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11/**
12 * Provides file name with a String <code>[prefix][id].[extension]</code> pattern.
13 * @author Andras Szabolcs Nagy
14 *
15 */
16public class IdBasedSolutionNameProvider implements ISolutionNameProvider {
17
18 private int id = 1;
19 private String prefix;
20 private String extension;
21
22 public IdBasedSolutionNameProvider(String prefix, String extension) {
23 this.extension = extension;
24 this.prefix = prefix;
25
26 }
27
28 @Override
29 public String getName() {
30 StringBuilder sb = new StringBuilder(prefix);
31 sb.append(id++);
32 sb.append('.');
33 sb.append(extension);
34 return sb.toString();
35 }
36
37} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/LogSolutionHandler.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/LogSolutionHandler.java
new file mode 100644
index 00000000..118f0c75
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/LogSolutionHandler.java
@@ -0,0 +1,28 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11import org.apache.log4j.Logger;
12import org.eclipse.viatra.dse.api.SolutionTrajectory;
13import org.eclipse.viatra.dse.base.ThreadContext;
14
15public class LogSolutionHandler implements ISolutionFoundHandler {
16
17 Logger logger = Logger.getLogger(LogSolutionHandler.class);
18
19 @Override
20 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
21 logger.info("Solution registered: " + trajectory.toPrettyString());
22 }
23
24 @Override
25 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
26 logger.debug("Not good enough solution: " + trajectory.toPrettyString());
27 }
28} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ModelSaverSolutionFoundHandler.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ModelSaverSolutionFoundHandler.java
new file mode 100644
index 00000000..bbbe60de
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ModelSaverSolutionFoundHandler.java
@@ -0,0 +1,55 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11import java.util.HashSet;
12
13import org.eclipse.emf.common.notify.Notifier;
14import org.eclipse.viatra.dse.api.SolutionTrajectory;
15import org.eclipse.viatra.dse.base.ThreadContext;
16import org.eclipse.viatra.dse.util.EMFHelper;
17
18public class ModelSaverSolutionFoundHandler implements ISolutionFoundHandler {
19
20 private HashSet<Object> savedSolutions = new HashSet<Object>();
21 private ISolutionNameProvider solutionNameProvider;
22
23 public ModelSaverSolutionFoundHandler() {
24 solutionNameProvider = new IdBasedSolutionNameProvider("solution", "xmi");
25 }
26
27 public ModelSaverSolutionFoundHandler(String extension) {
28 solutionNameProvider = new IdBasedSolutionNameProvider("solution", extension);
29 }
30
31 public ModelSaverSolutionFoundHandler(String prefix, String extension) {
32 solutionNameProvider = new IdBasedSolutionNameProvider(prefix, extension);
33 }
34
35 public ModelSaverSolutionFoundHandler(ISolutionNameProvider solutionNameProvider) {
36 this.solutionNameProvider = solutionNameProvider;
37 }
38
39 @Override
40 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
41 }
42
43 @Override
44 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
45 Object stateCode = trajectory.getSolution().getStateCode();
46
47 if (savedSolutions.contains(stateCode)) {
48 return;
49 }
50
51 savedSolutions.add(stateCode);
52 Notifier clonedModel = EMFHelper.clone(context.getModel());
53 EMFHelper.saveModel(clonedModel, solutionNameProvider.getName());
54 }
55} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/SolutionStore.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/SolutionStore.java
new file mode 100644
index 00000000..578ae277
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/SolutionStore.java
@@ -0,0 +1,311 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11import java.util.ArrayList;
12import java.util.Collection;
13import java.util.HashMap;
14import java.util.List;
15import java.util.Map;
16import java.util.Map.Entry;
17import java.util.concurrent.atomic.AtomicBoolean;
18import java.util.concurrent.atomic.AtomicInteger;
19
20import org.apache.log4j.Level;
21import org.apache.log4j.Logger;
22import org.eclipse.emf.common.notify.Notifier;
23import org.eclipse.viatra.dse.api.DSEException;
24import org.eclipse.viatra.dse.api.Solution;
25import org.eclipse.viatra.dse.api.SolutionTrajectory;
26import org.eclipse.viatra.dse.base.DesignSpaceManager;
27import org.eclipse.viatra.dse.base.ThreadContext;
28import org.eclipse.viatra.dse.objectives.Fitness;
29import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
30import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
31import org.eclipse.viatra.dse.util.EMFHelper;
32import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
33
34/**
35 *
36 * @author Andras Szabolcs Nagy
37 *
38 */
39public class SolutionStore {
40
41 public interface ISolutionSaver {
42 void setSolutionsCollection(Map<Object, Solution> solutions);
43 boolean saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory);
44 }
45
46 public interface IEnoughSolutions extends ISolutionFoundHandler {
47 boolean enoughSolutions();
48 }
49
50 public static class ANumberOfEnoughSolutions implements IEnoughSolutions {
51
52 private final AtomicInteger foundSolutions;
53 private final AtomicBoolean foundEnoughSolutions;
54
55 public ANumberOfEnoughSolutions(int number) {
56 foundSolutions = new AtomicInteger(number);
57 foundEnoughSolutions = new AtomicBoolean(false);
58 }
59
60 @Override
61 public boolean enoughSolutions() {
62 return foundEnoughSolutions.get();
63 }
64
65 @Override
66 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
67 int solutionsToFind = foundSolutions.decrementAndGet();
68 if (solutionsToFind == 0) {
69 foundEnoughSolutions.set(true);
70 }
71 }
72
73 @Override
74 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
75 }
76 }
77
78 public static class SimpleSolutionSaver implements ISolutionSaver {
79
80 private Map<Object, Solution> solutions;
81
82 @Override
83 public void setSolutionsCollection(Map<Object, Solution> solutions) {
84 this.solutions = solutions;
85 }
86
87 @Override
88 public boolean saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
89 Solution solution = solutions.get(id);
90 if (solution != null) {
91 if (solution.getTrajectories().contains(solutionTrajectory)) {
92 return false;
93 } else {
94 solution.addTrajectory(solutionTrajectory);
95 solutionTrajectory.setSolution(solution);
96 }
97 } else {
98 solution = new Solution(id, solutionTrajectory);
99 solutions.put(id, solution);
100 solutionTrajectory.setSolution(solution);
101 }
102 return true;
103 }
104 }
105
106 public static class BestSolutionSaver implements ISolutionSaver {
107
108 private Map<Object, Solution> solutions;
109 private Map<SolutionTrajectory, Fitness> trajectories = new HashMap<>();
110
111 @Override
112 public void setSolutionsCollection(Map<Object, Solution> solutions) {
113 this.solutions = solutions;
114 }
115
116 @Override
117 public boolean saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
118
119 Fitness lastFitness = context.getLastFitness();
120 ObjectiveComparatorHelper comparatorHelper = context.getObjectiveComparatorHelper();
121
122 List<SolutionTrajectory> dominatedTrajectories = new ArrayList<>();
123
124 for (Entry<SolutionTrajectory, Fitness> entry : trajectories.entrySet()) {
125 int isLastFitnessBetter = comparatorHelper.compare(lastFitness, entry.getValue());
126 if (isLastFitnessBetter < 0) {
127 return false;
128 }
129 if (isLastFitnessBetter > 0) {
130 dominatedTrajectories.add(entry.getKey());
131 }
132 }
133
134 boolean solutionSaved = false;
135
136 Solution solution = solutions.get(id);
137 if (solution != null) {
138 if (!solution.getTrajectories().contains(solutionTrajectory)) {
139 solution.addTrajectory(solutionTrajectory);
140 solutionTrajectory.setSolution(solution);
141 solutionSaved = true;
142 trajectories.put(solutionTrajectory, lastFitness);
143 }
144 } else {
145 solution = new Solution(id, solutionTrajectory);
146 solutions.put(id, solution);
147 solutionTrajectory.setSolution(solution);
148 solutionSaved = true;
149 trajectories.put(solutionTrajectory, lastFitness);
150 }
151
152 for (SolutionTrajectory st : dominatedTrajectories) {
153 trajectories.remove(st);
154 Solution s = st.getSolution();
155 if (!s.getTrajectories().remove(st)) {
156 throw new DSEException("Should not happen.");
157 }
158 if (s.getTrajectories().isEmpty()) {
159 Object stateCode = s.getStateCode();
160 solutions.remove(stateCode);
161 }
162 }
163
164 return solutionSaved;
165 }
166
167 }
168
169 protected boolean acceptOnlyGoalSolutions = true;
170 protected final Map<Object, Solution> solutions = new HashMap<Object, Solution>();
171 protected ISolutionSaver solutionSaver = new SimpleSolutionSaver();
172 protected List<ISolutionFoundHandler> solutionFoundHandlers = new ArrayList<ISolutionFoundHandler>(1);
173
174 protected final IEnoughSolutions enoughSolutions;
175
176 public SolutionStore() {
177 this(new IEnoughSolutions() {
178 @Override
179 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
180 }
181
182 @Override
183 public boolean enoughSolutions() {
184 return false;
185 }
186
187 @Override
188 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
189 }
190 });
191 }
192
193 public SolutionStore(int numOfSolutionsToFind) {
194 this(new ANumberOfEnoughSolutions(numOfSolutionsToFind));
195 }
196
197 public SolutionStore(IEnoughSolutions enoughSolutionsImpl) {
198 enoughSolutions = enoughSolutionsImpl;
199 }
200
201 public synchronized void newSolution(ThreadContext context) {
202 solutionSaver.setSolutionsCollection(solutions);
203 Fitness fitness = context.getLastFitness();
204 DesignSpaceManager dsm = context.getDesignSpaceManager();
205 Object id = dsm.getCurrentState();
206 IStateCoderFactory stateCoderFactory = context.getGlobalContext().getStateCoderFactory();
207 SolutionTrajectory solutionTrajectory = dsm.getTrajectoryInfo().createSolutionTrajectory(stateCoderFactory, context.getDesignSpaceManager());
208 solutionTrajectory.setFitness(fitness);
209
210 if (acceptOnlyGoalSolutions && !fitness.isSatisifiesHardObjectives()) {
211 unsavedSolutionCallbacks(context, solutionTrajectory);
212 return;
213 }
214
215 boolean solutionSaved = solutionSaver.saveSolution(context, id, solutionTrajectory);
216
217 if (solutionSaved) {
218 enoughSolutions.solutionFound(context, solutionTrajectory);
219
220 savedSolutionCallbacks(context, solutionTrajectory);
221
222 if (enoughSolutions.enoughSolutions()) {
223 context.getGlobalContext().stopAllThreads();
224 }
225 } else {
226 unsavedSolutionCallbacks(context, solutionTrajectory);
227 }
228 }
229
230 private void unsavedSolutionCallbacks(ThreadContext context, SolutionTrajectory solutionTrajectory) {
231 for (ISolutionFoundHandler handler : solutionFoundHandlers) {
232 handler.solutionTriedToSave(context, solutionTrajectory);
233 }
234 }
235
236 private void savedSolutionCallbacks(ThreadContext context, SolutionTrajectory solutionTrajectory) {
237 for (ISolutionFoundHandler handler : solutionFoundHandlers) {
238 handler.solutionFound(context, solutionTrajectory);
239 }
240 }
241
242 public synchronized Collection<Solution> getSolutions() {
243 return solutions.values();
244 }
245
246 public synchronized void registerSolutionFoundHandler(ISolutionFoundHandler handler) {
247 if (solutionFoundHandlers == null) {
248 solutionFoundHandlers = new ArrayList<ISolutionFoundHandler>(1);
249 }
250 solutionFoundHandlers.add(handler);
251 }
252
253 public SolutionStore logSolutionsWhenFound() {
254 registerSolutionFoundHandler(new LogSolutionHandler());
255 Logger.getLogger(LogSolutionHandler.class).setLevel(Level.INFO);
256 return this;
257 }
258
259 public SolutionStore saveModelWhenFound() {
260 registerSolutionFoundHandler(new ModelSaverSolutionFoundHandler());
261 return this;
262 }
263
264 public SolutionStore saveModelWhenFound(String extension) {
265 registerSolutionFoundHandler(new ModelSaverSolutionFoundHandler(extension));
266 return this;
267 }
268
269 public SolutionStore saveModelWhenFound(String prefix, String extension) {
270 registerSolutionFoundHandler(new ModelSaverSolutionFoundHandler(prefix, extension));
271 return this;
272 }
273
274 public SolutionStore saveModelWhenFound(ISolutionNameProvider solutionNameProvider) {
275 registerSolutionFoundHandler(new ModelSaverSolutionFoundHandler(solutionNameProvider));
276 return this;
277 }
278
279 public SolutionStore acceptGoalSolutionsOnly() {
280 acceptOnlyGoalSolutions = true;
281 return this;
282 }
283
284 public SolutionStore acceptAnySolutions() {
285 acceptOnlyGoalSolutions = false;
286 return this;
287 }
288
289 public SolutionStore withSolutionSaver(ISolutionSaver solutionSaver) {
290 this.solutionSaver = solutionSaver;
291 return this;
292 }
293
294 public SolutionStore storeBestSolutionsOnly() {
295 this.solutionSaver = new BestSolutionSaver();
296 return this;
297 }
298
299 public void saveModels(Notifier model, ISolutionNameProvider solutionNameProvider) {
300 try {
301 for (Solution solution : solutions.values()) {
302 SolutionTrajectory trajectory = solution.getArbitraryTrajectory();
303 trajectory.doTransformationUndoable(model);
304 EMFHelper.saveModel(model, solutionNameProvider.getName());
305 trajectory.undoTransformation();
306 }
307 } catch (ViatraQueryException e) {
308 Logger.getLogger(SolutionStore.class).error("Exception happened during model saving.", e);
309 }
310 }
311}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoder.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoder.java
new file mode 100644
index 00000000..f163f1a5
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoder.java
@@ -0,0 +1,82 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecode;
10
11import org.eclipse.emf.common.notify.Notifier;
12import org.eclipse.viatra.query.runtime.api.IPatternMatch;
13
14/**
15 * <p>
16 * To be able to efficiently explore a design space, a state that has been explored before through an other trajectory
17 * needs to be recognized and ignored accordingly.
18 * </p>
19 *
20 * <p>
21 * This is done by generating a pseudo-unique value (object) that is only depended on the relevant parts of the model's
22 * internal state, that is, the values of two states can only be equal if the states themselves can be considered equal.
23 * </p>
24 *
25 * <p>
26 * The processing engine however assumes, that any two states that share this pseudo-unique value has the same
27 * characteristics, meaning they have the same amount and type of outgoing transitions available, and firing the
28 * appropriate transitions from both states also result in states that share their pseudo-unique identifier. If this
29 * condition is not satisfied, the exploration process's result will be non-deterministic, and in consequence, solutions
30 * can be lost.
31 * </p>
32 *
33 * <p>
34 * In addition to providing pseudo-unique identifiers to model states, the state coder must provide pseud-unique
35 * identifiers to the outgoing transitions as well, but they only need to be unique on the scope of the particular
36 * state, not globally. Global addressing thus can be achieved by considering the pseudo-unique identifier of the state
37 * and the pseudo-unique identifier of the transition together if needed.
38 * </p>
39 *
40 * <p>
41 * Both identifiers can be arbitrary objects, and equality is checked by calling {@link Object#equals(Object)} on the
42 * two identifiers.
43 * </p>
44 *
45 * <p>
46 * For any particular implementation an {@link IStateCoderFactory} implementation must also be supplied that handles the
47 * creation of {@link IStateCoder} instances.
48 * </p>
49 *
50 * <p>
51 * Usually it is unnecessary to represent everything from the model in a state code, only the parts which are modified
52 * by the transformation rules.
53 * </p>
54 *
55 * @author Miklos Foldenyi, Andras Szabolcs Nagy
56 *
57 */
58public interface IStateCoder {
59
60 /**
61 * Initializes the state coder on the given model.
62 *
63 * @param notifier
64 */
65 void init(Notifier notifier);
66
67 /**
68 * Returns a pseudo-unique identifier that describes the underlying model's current internal state.
69 *
70 * @return an arbitrary {@link Object} that can be used as the identifier.
71 */
72 Object createStateCode();
73
74 /**
75 * Returns a pseudo-unique identifier that describes the given {@link IPatternMatch} in the context of the
76 * underlying model's current internal state.
77 *
78 * @return an arbitrary {@link Object} that can be used as the identifier in the given state.
79 */
80 Object createActivationCode(IPatternMatch match);
81
82}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoderFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoderFactory.java
new file mode 100644
index 00000000..cf8bdf8d
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoderFactory.java
@@ -0,0 +1,29 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecode;
10
11/**
12 * Interface for a factory class that creates instances of {@link IStateCoder} objects. This is required because state
13 * coders have to be created on-demand if the design space exploration process decides that a new thread is to be
14 * spawned. Since each thread requires it's own working model instance and a state coder is linked to the underlying
15 * model, a new {@link IStateCoder} needs to be created per processing thread.
16 *
17 * @author Miklos Foldenyi, Andras Szabolcs Nagy
18 *
19 */
20public interface IStateCoderFactory {
21
22 /**
23 * Creates a new {@link IStateCoder} instance specific to this {@link IStateCoderFactory}.
24 *
25 * @return the new {@link IStateCoder} instance specific to this working model.
26 */
27 IStateCoder createStateCoder();
28
29}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProvider.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProvider.java
new file mode 100644
index 00000000..afcba7b6
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProvider.java
@@ -0,0 +1,45 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11import java.util.Collection;
12
13import org.eclipse.emf.common.notify.Notifier;
14import org.eclipse.emf.ecore.EClass;
15import org.eclipse.emf.ecore.EObject;
16
17/**
18 * Implementation of this interface is responsible to provide {@link EObject}s of a given {@link EClass} for
19 * {@link TheStateCoder}
20 *
21 * @author Andras Szabolcs Nagy
22 *
23 */
24public interface IObjectsProvider {
25
26 /**
27 * Initialize the {@link IObjectsProvider} on a given model and {@link StatecodingDependencyGraph}.
28 *
29 * @param notifier
30 * The root of the model.
31 * @param statecodingDependencyGraph
32 * The state coding dependency graph.
33 */
34 void init(Notifier notifier, StatecodingDependencyGraph statecodingDependencyGraph);
35
36 /**
37 * Returns the instances of an {@link EClass} in a model.
38 *
39 * @param eClass
40 * The class of the objects.
41 * @return The collection of the instances.
42 */
43 Collection<EObject> getEObjects(EClass eClass);
44
45}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProviderFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProviderFactory.java
new file mode 100644
index 00000000..931eb1a2
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProviderFactory.java
@@ -0,0 +1,25 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11/**
12 * Interface for creating {@link IObjectsProvider} instances.
13 *
14 * @author Andras Szabolcs Nagy
15 */
16public interface IObjectsProviderFactory {
17
18 /**
19 * Creates an {@link IObjectsProvider} implementation.
20 *
21 * @return The newly created {@link IObjectsProvider}.
22 */
23 IObjectsProvider createObjectsProvider();
24
25}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProvider.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProvider.java
new file mode 100644
index 00000000..e38d45d3
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProvider.java
@@ -0,0 +1,60 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11import java.util.Collection;
12import java.util.HashSet;
13import java.util.Set;
14
15import org.apache.log4j.Logger;
16import org.eclipse.emf.common.notify.Notifier;
17import org.eclipse.emf.ecore.EClass;
18import org.eclipse.emf.ecore.EObject;
19import org.eclipse.viatra.dse.api.DSEException;
20import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
21import org.eclipse.viatra.query.runtime.base.api.IndexingLevel;
22import org.eclipse.viatra.query.runtime.base.api.NavigationHelper;
23import org.eclipse.viatra.query.runtime.emf.EMFScope;
24import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
25
26public class IncrementalObjectProvider implements IObjectsProvider {
27
28 private Logger logger = Logger.getLogger(getClass());
29 private NavigationHelper baseIndex;
30
31 @Override
32 public void init(Notifier notifier, StatecodingDependencyGraph statecodingDependencyGraph) {
33
34 try {
35 EMFScope scope = new EMFScope(notifier);
36 ViatraQueryEngine queryEngine = ViatraQueryEngine.on(scope);
37
38 Set<EClass> classes = new HashSet<EClass>();
39// Set<EReference> references = new HashSet<EReference>();
40 for (StatecodingNode node : statecodingDependencyGraph.getNodes()) {
41 classes.add(node.getClazz());
42// for (StatecodingDependency dependency : node.getStatecodingDependencies()) {
43// // TODO inverse reference
44// references.add(dependency.eReference);
45// }
46 }
47 baseIndex = EMFScope.extractUnderlyingEMFIndex(queryEngine);
48 baseIndex.registerEClasses(classes, IndexingLevel.FULL);
49 } catch (ViatraQueryException e) {
50 logger.error("Failed to initialize VIATRA Query engine on the given notifier", e);
51 throw new DSEException("Failed to initialize VIATRA Query engine on the given notifier");
52 }
53 }
54
55 @Override
56 public Collection<EObject> getEObjects(EClass eClass) {
57 return baseIndex.getAllInstances(eClass);
58 }
59
60}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProviderFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProviderFactory.java
new file mode 100644
index 00000000..97011436
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProviderFactory.java
@@ -0,0 +1,18 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11public class IncrementalObjectProviderFactory implements IObjectsProviderFactory {
12
13 @Override
14 public IncrementalObjectProvider createObjectsProvider() {
15 return new IncrementalObjectProvider();
16 }
17
18}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependency.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependency.java
new file mode 100644
index 00000000..67b1982d
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependency.java
@@ -0,0 +1,33 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11import org.eclipse.emf.ecore.EReference;
12
13public class StatecodingDependency {
14
15 protected EReference eReference;
16 protected StatecodingNode node;
17 protected boolean isContained;
18 protected StatecodingDependencyType type;
19
20 public StatecodingDependency(EReference eReference, StatecodingNode node, boolean isContained,
21 StatecodingDependencyType type) {
22 super();
23 this.eReference = eReference;
24 this.node = node;
25 this.isContained = isContained;
26 this.type = type;
27 }
28
29 public StatecodingDependency(EReference eReference, StatecodingNode node) {
30 this(eReference, node, false, StatecodingDependencyType.NORMAL);
31 }
32
33} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyGraph.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyGraph.java
new file mode 100644
index 00000000..6f7255a3
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyGraph.java
@@ -0,0 +1,44 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11import java.util.ArrayList;
12import java.util.List;
13
14import org.eclipse.emf.ecore.EClass;
15
16public class StatecodingDependencyGraph {
17
18 private List<StatecodingNode> nodes = new ArrayList<StatecodingNode>();
19
20 public StatecodingNode createNode(EClass clazz) {
21 StatecodingNode node = new StatecodingNode(clazz);
22 node.setGraph(this);
23 addNode(node);
24 return node;
25 }
26
27 public void addNode(StatecodingNode node) {
28 nodes.add(node);
29 }
30
31 public StatecodingNode getNodeByClass(EClass eClass) {
32 for (StatecodingNode node : nodes) {
33 if (node.getClazz().equals(eClass)) {
34 return node;
35 }
36 }
37 return null;
38 }
39
40 public List<StatecodingNode> getNodes() {
41 return nodes;
42 }
43
44}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyType.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyType.java
new file mode 100644
index 00000000..bdd4677d
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyType.java
@@ -0,0 +1,15 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11public enum StatecodingDependencyType {
12
13 NORMAL,
14 INVERSE
15}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNode.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNode.java
new file mode 100644
index 00000000..91fc28cf
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNode.java
@@ -0,0 +1,100 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11import java.util.ArrayList;
12import java.util.Comparator;
13import java.util.List;
14import java.util.Set;
15import java.util.TreeSet;
16
17import org.eclipse.emf.ecore.EAttribute;
18import org.eclipse.emf.ecore.EClass;
19import org.eclipse.emf.ecore.EReference;
20
21public class StatecodingNode {
22
23 private StatecodingDependencyGraph graph;
24
25 private final EClass clazz;
26 private Set<EAttribute> attributes = new TreeSet<EAttribute>(Comparator.comparing(EAttribute::getName));
27 private List<StatecodingDependency> dependencies = new ArrayList<StatecodingDependency>();
28 private boolean stateCodeIsId = false;
29 private StatecodingNodeType statecodingNodeType = StatecodingNodeType.CREATE_AND_DELETE;
30
31 public StatecodingNode(EClass clazz) {
32 this.clazz = clazz;
33 }
34
35 public StatecodingNode withAttribute(EAttribute attribute) {
36 attributes.add(attribute);
37 return this;
38 }
39
40 public StatecodingNode withType(StatecodingNodeType type) {
41 statecodingNodeType = type;
42 return this;
43 }
44
45 public StatecodingNode withUniqueness() {
46 stateCodeIsId = true;
47 return this;
48 }
49
50 public StatecodingNode withDependency(EReference reference, StatecodingNode node) {
51 dependencies.add(new StatecodingDependency(reference, node));
52 return this;
53 }
54
55 public StatecodingNode withInverseDependency(EReference reference, StatecodingNode node) {
56 dependencies.add(new StatecodingDependency(reference, node, false, StatecodingDependencyType.INVERSE));
57 return this;
58 }
59
60 public void addDependency(StatecodingDependency statecodingDependency) {
61 dependencies.add(statecodingDependency);
62 }
63
64 public EClass getClazz() {
65 return clazz;
66 }
67
68 public boolean isStateCodeIsId() {
69 return stateCodeIsId;
70 }
71
72 public void setStateCodeIsId(boolean stateCodeIsId) {
73 this.stateCodeIsId = stateCodeIsId;
74 }
75
76 public StatecodingNodeType getStatecodingNodeType() {
77 return statecodingNodeType;
78 }
79
80 public void setStatecodingNodeType(StatecodingNodeType statecodingNodeType) {
81 this.statecodingNodeType = statecodingNodeType;
82 }
83
84 public Set<EAttribute> getAttributes() {
85 return attributes;
86 }
87
88 public List<StatecodingDependency> getStatecodingDependencies() {
89 return dependencies;
90 }
91
92 public StatecodingDependencyGraph getGraph() {
93 return graph;
94 }
95
96 public void setGraph(StatecodingDependencyGraph graph) {
97 this.graph = graph;
98 }
99
100}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNodeType.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNodeType.java
new file mode 100644
index 00000000..c902a7a6
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNodeType.java
@@ -0,0 +1,17 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11public enum StatecodingNodeType {
12
13 FIXED,
14 ONLY_CREATE,
15 ONLY_DELETE,
16 CREATE_AND_DELETE
17}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoder.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoder.java
new file mode 100644
index 00000000..4601ff08
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoder.java
@@ -0,0 +1,215 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11import java.util.Arrays;
12import java.util.Collection;
13import java.util.List;
14import java.util.Set;
15
16import org.eclipse.emf.common.notify.Notifier;
17import org.eclipse.emf.common.util.EList;
18import org.eclipse.emf.ecore.EAttribute;
19import org.eclipse.emf.ecore.EObject;
20import org.eclipse.viatra.dse.api.DSEException;
21import org.eclipse.viatra.dse.statecode.IStateCoder;
22import org.eclipse.viatra.query.runtime.api.IPatternMatch;
23
24public class TheStateCoder implements IStateCoder {
25
26 private StatecodingDependencyGraph sdg;
27 private IObjectsProvider objectProvider;
28
29 public TheStateCoder(StatecodingDependencyGraph sdg, IObjectsProvider objectProvider) {
30 this.sdg = sdg;
31 this.objectProvider = objectProvider;
32 }
33
34 @Override
35 public void init(Notifier notifier) {
36 // TODO checks
37 // TODO node sorting based on traversal - in factory
38
39 // this.notifier = notifier;
40 // try {
41 // EMFScope scope = new EMFScope(notifier);
42 // queryEngine = ViatraQueryEngine.on(scope);
43 // } catch (ViatraQueryException e1) {
44 // logger.error("Failed to initialize VIATRA Query engine on the given notifier", e1);
45 // throw new DSEException("Failed to initialize VIATRA Query engine on the given notifier");
46 // }
47
48 objectProvider.init(notifier, sdg);
49 }
50
51 @Override
52 public String createStateCode() {
53
54 StringBuilder sb = new StringBuilder();
55
56 // TODO sort
57 for (StatecodingNode node : sdg.getNodes()) {
58 sb.append(node.getClazz().getName());
59 sb.append(':');
60 sb.append(addStateCode(node));
61 sb.append('|');
62 }
63 sb.deleteCharAt(sb.length() - 1);
64
65 return sb.toString();
66
67 }
68
69 @Override
70 public Object createActivationCode(IPatternMatch match) {
71 // TODO root object
72 // TODO parameterless?
73
74 int i = 0;
75 StringBuilder sb = new StringBuilder();
76 Object object;
77 do {
78 object = match.get(i++);
79 if (object != null) {
80 if (object instanceof EObject) {
81 EObject eObject = (EObject) object;
82 sb.append(addStateCode(sdg.getNodeByClass(eObject.eClass()), eObject));
83 } else {
84 // TODO toString or not to toString
85 }
86 }
87 } while (object != null);
88
89 return sb.toString();
90 }
91
92 public String addStateCode(StatecodingNode node, EObject eObject) {
93 StringBuilder sb = new StringBuilder();
94
95 Set<EAttribute> attributes = node.getAttributes();
96 if (!attributes.isEmpty()) {
97 for (EAttribute eAttribute : attributes) {
98 // attributes are sorted
99 // TODO handle collection
100 sb.append(eObject.eGet(eAttribute));
101 sb.append(';');
102 }
103 sb.deleteCharAt(sb.length() - 1);
104 }
105
106 List<StatecodingDependency> dependencies = node.getStatecodingDependencies();
107 int dependenciesSize = dependencies.size();
108 if (dependenciesSize > 0) {
109 String[] codeParts = new String[dependenciesSize];
110 int i = 0;
111 for (StatecodingDependency dependency : dependencies) {
112 String code = addStateCodeFromDependency(dependency, eObject);
113 codeParts[i++] = code;
114 }
115 Arrays.sort(codeParts);
116
117 sb.append("(");
118 sb.append(codeParts[0]);
119 for (i = 1; i < codeParts.length; i++) {
120 sb.append(';');
121 sb.append(codeParts[i]);
122 }
123 sb.append(")");
124 }
125 return sb.toString();
126 }
127
128 public String addStateCode(StatecodingNode node) {
129 Collection<EObject> eObjects = objectProvider.getEObjects(node.getClazz());
130 int size = eObjects.size();
131
132 if (size > 0) {
133 String[] codeParts = new String[size];
134 int i = 0;
135 for (EObject eObject : eObjects) {
136 String code = addStateCode(node, eObject);
137 codeParts[i++] = code;
138 }
139 Arrays.sort(codeParts);
140
141 StringBuilder sb = new StringBuilder();
142 sb.append(codeParts[0]);
143 for (i = 1; i < codeParts.length; i++) {
144 sb.append(';');
145 sb.append(codeParts[i]);
146 }
147 return sb.toString();
148 }
149
150 return "";
151 }
152
153 public String addStateCodeFromDependency(StatecodingDependency sd, EObject eObject) {
154
155 if (sd.type.equals(StatecodingDependencyType.NORMAL)) {
156
157 Object eReferred = eObject.eGet(sd.eReference);
158 if (eReferred == null) {
159 return "";
160 } else if (eReferred instanceof EList<?>) {
161 EList<?> refferedList = (EList<?>) eReferred;
162 // TODO test
163 if (!refferedList.isEmpty()) {
164
165 String[] codeParts = new String[refferedList.size()];
166 int i = 0;
167 for (Object referredEObject : refferedList) {
168 String code = addStateCode(sd.node, (EObject) referredEObject);
169 codeParts[i++] = code;
170 }
171 Arrays.sort(codeParts);
172
173 StringBuilder sb = new StringBuilder();
174 sb.append('[');
175 sb.append(codeParts[0]);
176 for (i = 1; i < codeParts.length; i++) {
177 sb.append(';');
178 sb.append(codeParts[i]);
179 }
180 sb.append(']');
181 return sb.toString();
182
183 }
184 } else if (eReferred instanceof EObject) {
185 return addStateCode(sd.node, (EObject) eReferred);
186 } else {
187 throw new DSEException("The EObject " + eObject.toString() + " does not have a feature "
188 + eReferred.toString() + ".");
189 }
190
191 } else {
192 for (EObject dependentEObject : objectProvider.getEObjects(sd.node.getClazz())) {
193 Object eReferred = dependentEObject.eGet(sd.eReference);
194 if (eReferred == null) {
195 continue;
196 } else if (eReferred instanceof EList<?>) {
197 // TODO this is slow, use VIATRA Query
198 for (Object referredEObject : ((EList<?>) eReferred)) {
199 if (referredEObject.equals(eObject)) {
200 return addStateCode(sd.node, (EObject) dependentEObject);
201 }
202 }
203 } else if (eReferred.equals(eObject)) {
204 // Probably never happens?
205 return addStateCode(sd.node, (EObject) dependentEObject);
206 } else {
207 throw new DSEException("The EObject " + eObject.toString() + " does not have a feature "
208 + eReferred.toString() + ".");
209 }
210 }
211 }
212
213 return "";
214 }
215}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoderFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoderFactory.java
new file mode 100644
index 00000000..eeb6e48f
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoderFactory.java
@@ -0,0 +1,40 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11import org.eclipse.viatra.dse.statecode.IStateCoder;
12import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
13
14public class TheStateCoderFactory implements IStateCoderFactory {
15
16 private StatecodingDependencyGraph sdg;
17 private IObjectsProviderFactory objectProviderFactory;
18
19 public TheStateCoderFactory(StatecodingDependencyGraph sdg) {
20 this(sdg, new IncrementalObjectProviderFactory());
21 }
22
23 public TheStateCoderFactory(StatecodingDependencyGraph sdg, IObjectsProviderFactory objectProviderFactory) {
24 this.sdg = sdg;
25 this.objectProviderFactory = objectProviderFactory;
26
27 // TODO cyclic dependency? - exception
28
29 // TODO make plan for traversal
30
31 // TODO If the type is FIXED and all dependency is FIXED then do not create state code for it (them)
32 // This is not true :( e.g. matchmaking - they are fixed, but the references must be encoded
33 }
34
35 @Override
36 public IStateCoder createStateCoder() {
37 return new TheStateCoder(sdg, objectProviderFactory.createObjectsProvider());
38 }
39
40}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder.java
new file mode 100644
index 00000000..0f0759ae
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder.java
@@ -0,0 +1,250 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding.simple;
10
11import java.util.Arrays;
12import java.util.Collection;
13import java.util.HashMap;
14import java.util.HashSet;
15import java.util.List;
16import java.util.Map;
17import java.util.Set;
18
19import org.eclipse.emf.common.notify.Notifier;
20import org.eclipse.emf.ecore.EAttribute;
21import org.eclipse.emf.ecore.EClass;
22import org.eclipse.emf.ecore.EObject;
23import org.eclipse.emf.ecore.EReference;
24import org.eclipse.emf.ecore.EStructuralFeature;
25import org.eclipse.emf.ecore.EStructuralFeature.Setting;
26import org.eclipse.viatra.dse.api.DSEException;
27import org.eclipse.viatra.dse.statecode.IStateCoder;
28import org.eclipse.viatra.dse.util.EMFHelper.MetaModelElements;
29import org.eclipse.viatra.dse.util.ValueComparableEObjectStringMap;
30import org.eclipse.viatra.query.runtime.api.IPatternMatch;
31import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
32import org.eclipse.viatra.query.runtime.base.api.FeatureListener;
33import org.eclipse.viatra.query.runtime.base.api.IndexingLevel;
34import org.eclipse.viatra.query.runtime.base.api.InstanceListener;
35import org.eclipse.viatra.query.runtime.base.api.NavigationHelper;
36import org.eclipse.viatra.query.runtime.emf.EMFBaseIndexWrapper;
37import org.eclipse.viatra.query.runtime.emf.EMFScope;
38import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
39
40/**
41 *
42 * @author Andras Szabolcs Nagy
43 *
44 */
45public class SimpleStateCoder implements IStateCoder {
46
47 private Set<EClass> classes;
48 private Set<EStructuralFeature> features;
49 private NavigationHelper navigationHelper;
50
51 private Map<EClass, Map<EObject, String>> objectCodes;
52 private int maxDepth;
53
54 private Set<EObject> changedOrNewEObjects = new HashSet<EObject>();
55 private Set<EObject> deletedClasses = new HashSet<EObject>();
56
57 public SimpleStateCoder(MetaModelElements metaModelElements) {
58 this.maxDepth = 1;
59
60 classes = metaModelElements.classes;
61 features = new HashSet<EStructuralFeature>(metaModelElements.attributes);
62 features.addAll(metaModelElements.references);
63 }
64
65 @Override
66 public void init(Notifier notifier) {
67 try {
68 EMFScope scope = new EMFScope(notifier);
69 ViatraQueryEngine queryEngine = ViatraQueryEngine.on(scope);
70 EMFBaseIndexWrapper baseIndex = (EMFBaseIndexWrapper) queryEngine.getBaseIndex();
71 navigationHelper = baseIndex.getNavigationHelper();
72 navigationHelper.registerObservedTypes(classes, null, features, IndexingLevel.FULL);
73 } catch (ViatraQueryException e) {
74 throw new DSEException(e);
75 }
76
77 objectCodes = new HashMap<EClass, Map<EObject, String>>();
78 for (EClass eClass : classes) {
79 Map<EObject, String> codes = new ValueComparableEObjectStringMap();
80
81 objectCodes.put(eClass, codes);
82
83 for (EObject eObject : navigationHelper.getDirectInstances(eClass)) {
84 codes.put(eObject, createObjectCodeWithDepth(eObject, maxDepth));
85 }
86 }
87
88 navigationHelper.addFeatureListener(features, new FeatureListener() {
89
90 @Override
91 public void featureInserted(EObject host, EStructuralFeature feature, Object value) {
92 changedOrNewEObjects.add(host);
93 }
94
95 @Override
96 public void featureDeleted(EObject host, EStructuralFeature feature, Object value) {
97 changedOrNewEObjects.add(host);
98 if (value instanceof EObject) {
99 changedOrNewEObjects.add((EObject) value);
100 }
101 }
102 });
103
104 navigationHelper.addInstanceListener(classes, new InstanceListener() {
105
106 @Override
107 public void instanceInserted(EClass clazz, EObject instance) {
108 changedOrNewEObjects.add(instance);
109 }
110
111 @Override
112 public void instanceDeleted(EClass clazz, EObject instance) {
113 deletedClasses.add(instance);
114 }
115 });
116 }
117
118 private String createObjectCodeWithDepth(EObject eObject, int depth) {
119
120 StringBuilder sb = new StringBuilder();
121
122 Collection<EAttribute> attributes = eObject.eClass().getEAllAttributes();
123 for (EAttribute eAttribute : attributes) {
124 Object value = eObject.eGet(eAttribute);
125 sb.append(value);
126 sb.append(',');
127 }
128 if (!attributes.isEmpty()) {
129 sb.deleteCharAt(sb.length() - 1);
130 }
131 if (depth > 0) {
132 sb.append('-');
133 Collection<EReference> eReferences = eObject.eClass().getEAllReferences();
134 for (EReference eReference : eReferences) {
135 Object value = eObject.eGet(eReference);
136 if (value == null) {
137 sb.append("null,");
138 } else if (value instanceof EObject) {
139 sb.append(createObjectCodeWithDepth((EObject) value, depth - 1));
140 sb.append(',');
141 } else {
142 List<EObject> referencedEObjects = (List<EObject>) value;
143 if (!referencedEObjects.isEmpty()) {
144
145 String[] codes = new String[referencedEObjects.size()];
146 int index = 0;
147 for (EObject referencedEObject : referencedEObjects) {
148 codes[index++] = createObjectCodeWithDepth(referencedEObject, depth - 1);
149 }
150 Arrays.sort(codes);
151 sb.append('(');
152 for (String code : codes) {
153 sb.append(code);
154 }
155 sb.append("),");
156 }
157 }
158 }
159 sb.deleteCharAt(sb.length() - 1);
160 }
161 return sb.toString();
162 }
163
164 @Override
165 public Object createStateCode() {
166
167 refreshObjectCodes();
168
169 StringBuilder sb = new StringBuilder();
170
171 for (EClass eClass : classes) {
172
173 Set<EObject> instances = navigationHelper.getDirectInstances(eClass);
174
175 if (!instances.isEmpty()) {
176
177 sb.append(eClass.getName());
178 sb.append(':');
179
180 String[] codesToSort = new String[instances.size()];
181 int index = 0;
182 Map<EObject, String> codes = objectCodes.get(eClass);
183 for (EObject eObject : instances) {
184 codesToSort[index++] = codes.get(eObject);
185 }
186 Arrays.sort(codesToSort);
187 for (String string : codesToSort) {
188 sb.append(string);
189 sb.append(';');
190 }
191 sb.deleteCharAt(sb.length() - 1);
192 sb.append('|');
193 }
194 }
195 if (sb.length() != 0) {
196 sb.deleteCharAt(sb.length() - 1);
197 }
198 return sb.toString();
199 }
200
201 private void refreshObjectCodes() {
202 for (EObject eObject : deletedClasses) {
203 EClass eClass = eObject.eClass();
204 objectCodes.get(eClass).remove(eObject);
205 }
206 deletedClasses.clear();
207
208 Set<EObject> objectsToRecode = new HashSet<EObject>();
209 for (EObject eObject : changedOrNewEObjects) {
210 objectsToRecode.add(eObject);
211 for (Setting setting : navigationHelper.getInverseReferences(eObject)) {
212 objectsToRecode.add(setting.getEObject());
213 }
214 }
215
216 for (EObject eObject : objectsToRecode) {
217 EClass eClass = eObject.eClass();
218 objectCodes.get(eClass).put(eObject, createObjectCodeWithDepth(eObject, maxDepth));
219 }
220 changedOrNewEObjects.clear();
221 }
222
223 @Override
224 public Object createActivationCode(IPatternMatch match) {
225
226 StringBuilder sb = new StringBuilder();
227 String[] tokens = match.specification().getFullyQualifiedName().split("\\.");
228 sb.append(tokens[tokens.length - 1]);
229 sb.append(':');
230 Object param;
231 for (int i = 0; (param = match.get(i)) != null; i++) {
232 EObject eObject = (EObject) param;
233
234 Collection<EAttribute> attributes = eObject.eClass().getEAllAttributes();
235 for (EAttribute eAttribute : attributes) {
236 Object value = eObject.eGet(eAttribute);
237 sb.append(value);
238 sb.append(',');
239 }
240 if (!attributes.isEmpty()) {
241 sb.deleteCharAt(sb.length() - 1);
242 }
243
244 sb.append('|');
245 }
246 sb.deleteCharAt(sb.length() - 1);
247 return sb.toString().intern();
248 }
249
250}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoderFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoderFactory.java
new file mode 100644
index 00000000..d776e8a8
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoderFactory.java
@@ -0,0 +1,38 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding.simple;
10
11import java.util.Collection;
12import java.util.HashSet;
13
14import org.eclipse.emf.ecore.EPackage;
15import org.eclipse.viatra.dse.statecode.IStateCoder;
16import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
17import org.eclipse.viatra.dse.util.EMFHelper;
18import org.eclipse.viatra.dse.util.EMFHelper.MetaModelElements;
19
20/**
21 *
22 * @author Andras Szabolcs Nagy
23 *
24 */
25public class SimpleStateCoderFactory implements IStateCoderFactory {
26
27 private MetaModelElements metaModelElements;
28
29 public SimpleStateCoderFactory(Collection<EPackage> metaModelPackages) {
30 metaModelElements = EMFHelper.getAllMetaModelElements(new HashSet<EPackage>(metaModelPackages));
31 }
32
33 @Override
34 public IStateCoder createStateCoder() {
35 return new SimpleStateCoder(metaModelElements);
36 }
37
38}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/EMFHelper.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/EMFHelper.java
new file mode 100644
index 00000000..14b3acfb
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/EMFHelper.java
@@ -0,0 +1,424 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.util;
10
11import java.io.IOException;
12import java.util.Collections;
13import java.util.Comparator;
14import java.util.HashMap;
15import java.util.HashSet;
16import java.util.List;
17import java.util.Map;
18import java.util.Objects;
19import java.util.Set;
20import java.util.TreeSet;
21
22import org.apache.log4j.Logger;
23import org.eclipse.emf.common.command.BasicCommandStack;
24import org.eclipse.emf.common.notify.Notifier;
25import org.eclipse.emf.common.util.EList;
26import org.eclipse.emf.common.util.URI;
27import org.eclipse.emf.ecore.EAttribute;
28import org.eclipse.emf.ecore.EClass;
29import org.eclipse.emf.ecore.EClassifier;
30import org.eclipse.emf.ecore.ENamedElement;
31import org.eclipse.emf.ecore.EObject;
32import org.eclipse.emf.ecore.EPackage;
33import org.eclipse.emf.ecore.EReference;
34import org.eclipse.emf.ecore.resource.Resource;
35import org.eclipse.emf.ecore.resource.ResourceSet;
36import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
37import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
38import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
39import org.eclipse.emf.edit.command.AddCommand;
40import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
41import org.eclipse.emf.edit.domain.EditingDomain;
42import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
43
44/**
45 * This class contains static helper methods.
46 * @author Andras Szabolcs Nagy
47 */
48public final class EMFHelper {
49
50 private static final Logger logger = Logger.getLogger(EMFHelper.class);
51
52 private EMFHelper() {
53 }
54
55 public static class EmfHelperException extends RuntimeException {
56 private static final long serialVersionUID = 7635796550669616626L;
57
58 public EmfHelperException(String string) {
59 super(string);
60 }
61 public EmfHelperException(String string, Throwable e) {
62 super(string, e);
63 }
64 }
65
66 /**
67 * Gets the {@link EditingDomain} of either an {@link EObject}, {@link Resource} or {@link ResourceSet}.
68 * @param notifier The {@link Notifier}.
69 * @return The EditingDomain.
70 */
71 public static EditingDomain getEditingDomain(Notifier notifier) {
72 Objects.requireNonNull(notifier);
73 if (notifier instanceof EObject) {
74 EObject eObject = (EObject) notifier;
75 return AdapterFactoryEditingDomain.getEditingDomainFor(eObject);
76 } else if (notifier instanceof Resource) {
77 Resource resource = (Resource) notifier;
78 EList<EObject> contents = resource.getContents();
79 if (contents.isEmpty()) {
80 return null;
81 }
82 return AdapterFactoryEditingDomain.getEditingDomainFor(contents.get(0));
83 } else if (notifier instanceof ResourceSet) {
84 ResourceSet resourceSet = (ResourceSet) notifier;
85 if (resourceSet.getResources().isEmpty()) {
86 return null;
87 }
88 return getEditingDomain(resourceSet.getResources().get(0));
89 }
90
91 return null;
92 }
93
94 /**
95 * Creates (or gets if already exists) an {@link EditingDomain} over the given {@link Notifier},
96 * either an {@link EObject}, {@link Resource} or {@link ResourceSet}.
97 * @param notifier The {@link Notifier}.
98 * @return The EditingDomain.
99 */
100 public static EditingDomain createEditingDomain(Notifier notifier) {
101
102 EditingDomain domain = getEditingDomain(notifier);
103 if (domain != null) {
104 return domain;
105 }
106
107 registerExtensionForXmiSerializer("dummyext");
108
109 if (notifier instanceof EObject) {
110 EObject eObject = (EObject) notifier;
111
112 domain = new AdapterFactoryEditingDomain(null, new BasicCommandStack());
113 Resource resource = domain.getResourceSet().createResource(URI.createFileURI("dummy.dummyext"));
114 domain.getCommandStack().execute(new AddCommand(domain, resource.getContents(), eObject));
115
116 return domain;
117
118 } else if (notifier instanceof Resource) {
119 Resource resource = (Resource) notifier;
120
121 ResourceSet resourceSet = resource.getResourceSet();
122 if (resourceSet != null) {
123 return new AdapterFactoryEditingDomain(null, new BasicCommandStack(), resourceSet);
124 } else {
125 domain = new AdapterFactoryEditingDomain(null, new BasicCommandStack(), (ResourceSet) null);
126 resourceSet = domain.getResourceSet();
127 domain.getCommandStack().execute(new AddCommand(domain, resourceSet.getResources(), resource));
128 return domain;
129 }
130
131 } else if (notifier instanceof ResourceSet) {
132 return new AdapterFactoryEditingDomain(null, new BasicCommandStack(), (ResourceSet) notifier);
133 } else {
134 throw new EmfHelperException("Not supported argument type.");
135 }
136 }
137
138 /**
139 * Saves the EMF model (EObject or Resource) into the given file. An {@link XMIResourceFactoryImpl} will be
140 * registered if not already.
141 *
142 * Doesn't throw exception but logs an error if the save was unsuccessful.
143 *
144 * @param model Can be an {@link EObject} or a {@link Resource}.
145 * @param fileName
146 */
147 public static void saveModel(Notifier model, String fileName) {
148
149 Objects.requireNonNull(model);
150 Preconditions.checkArgument(fileName != null && !fileName.isEmpty(), "File name is null or empty.");
151
152 int extensionIndex = fileName.lastIndexOf('.');
153
154 Preconditions.checkState(extensionIndex > -1 && extensionIndex != fileName.length() - 1, "Bad file extension.");
155
156 String ext = fileName.substring(extensionIndex + 1);
157
158 registerExtensionForXmiSerializer(ext);
159
160 URI uri = URI.createFileURI(fileName);
161 Resource resource;
162
163 if (model instanceof ResourceSet) {
164 throw new EmfHelperException("Unsupported type: ResourceSet");
165 } else if (model instanceof Resource) {
166 resource = (Resource) model;
167 } else if (model instanceof EObject) {
168 EObject root = (EObject) model;
169 ResourceSet resSet = new ResourceSetImpl();
170 resource = resSet.createResource(uri);
171 resource.getContents().add(root);
172 } else {
173 throw new EmfHelperException("Unkown type: " + model.getClass());
174 }
175
176 resource.setURI(uri);
177 saveResource(resource);
178 }
179
180 private static void saveResource(Resource resource) {
181 try {
182 resource.save(Collections.emptyMap());
183 } catch (IOException e) {
184 logger.error(e);
185 }
186 }
187
188 /**
189 * Loads a model as a {@link Resource}. In headless mode, don't forget to call XYZPackage.eINSTANCE.
190 */
191 public static Resource loadModel(String fileName) throws IOException {
192 Preconditions.checkArgument(fileName != null && !fileName.isEmpty(), "File name is null or empty.");
193 int extensionIndex = fileName.lastIndexOf('.');
194 Preconditions.checkState(extensionIndex > -1 && extensionIndex != fileName.length() - 1, "Bad file extension.");
195
196 String ext = fileName.substring(extensionIndex + 1);
197 registerExtensionForXmiSerializer(ext);
198
199 ResourceSetImpl rSet = new ResourceSetImpl();
200 URI fileUri = URI.createFileURI(fileName);
201 Resource resource = rSet.createResource(fileUri);
202
203 resource.load(null);
204 return resource;
205 }
206
207 /**
208 * Retrieves the root EObject from a Resource or ResourceSet.
209 * <ul>
210 * <li>Returns null if there is no content.</li>
211 * <li>Returns the notifier itself if it is an EObject.</li>
212 * <li>Logs a warn if there are multiple roots.</li>
213 * </ul>
214 *
215 * @param notifier
216 * @return The root EObject or null.
217 */
218 public static EObject getRootEObject(Notifier notifier) {
219 if (notifier instanceof EObject) {
220 return (EObject) notifier;
221 } else if (notifier instanceof Resource) {
222 Resource resource = (Resource) notifier;
223 List<EObject> contents = resource.getContents();
224 if (contents.size() > 1) {
225 logger.warn("Resource has more than one root.");
226 }
227 if (contents.isEmpty()) {
228 return null;
229 } else {
230 return contents.get(0);
231 }
232 } else if (notifier instanceof ResourceSet) {
233 ResourceSet resourceSet = (ResourceSet) notifier;
234 List<Resource> resources = resourceSet.getResources();
235 if (resources.size() > 1) {
236 logger.warn("ResourceSet has more than one resources.");
237 }
238 if (resources.isEmpty()) {
239 return null;
240 } else {
241 return getRootEObject(resources.get(0));
242 }
243 } else {
244 throw new EmfHelperException("Unkown type: " + notifier.getClass());
245 }
246 }
247
248 /**
249 * Registers an {@link XMIResourceFactoryImpl} for the given extension.
250 * @param ext The extension as a String.
251 */
252 public static void registerExtensionForXmiSerializer(String ext) {
253 Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
254 Map<String, Object> m = reg.getExtensionToFactoryMap();
255 m.computeIfAbsent(ext, e -> new XMIResourceFactoryImpl());
256 }
257
258 /**
259 * Clones the given model. Either an {@link EObject}, {@link Resource} or {@link ResourceSet}.
260 * @param notifier The root container of the model.
261 * @return The cloned model.
262 */
263 public static Notifier clone(Notifier notifier) {
264 Copier copier = new Copier();
265 Notifier clonedModel = clone(notifier, copier, null);
266 copier.copyReferences();
267 return clonedModel;
268 }
269
270 private static Notifier clone(Notifier notifier, Copier copier, ResourceSet resourceSetToCloneTo) {
271 Objects.requireNonNull(copier);
272
273 if (notifier instanceof EObject) {
274 EObject eObject = (EObject) notifier;
275 return copier.copy(eObject);
276 } else if (notifier instanceof Resource) {
277 Resource resource = (Resource) notifier;
278 ResourceSet rSetTemp = resourceSetToCloneTo;
279 if (resourceSetToCloneTo == null) {
280 rSetTemp = new ResourceSetImpl();
281 }
282 Resource clonedResource = rSetTemp.createResource(URI.createFileURI("dummy.dummyext"));
283
284 for (EObject eObject : resource.getContents()) {
285 EObject clonedEObject = copier.copy(eObject);
286 clonedResource.getContents().add(clonedEObject);
287 }
288
289 return clonedResource;
290 } else if (notifier instanceof ResourceSet) {
291 ResourceSet resourceSet = (ResourceSet) notifier;
292 ResourceSetImpl clonedResourceSet = new ResourceSetImpl();
293
294 for (Resource resource : resourceSet.getResources()) {
295 clone(resource, copier, clonedResourceSet);
296 }
297
298 return clonedResourceSet;
299 } else {
300 throw new EmfHelperException("Not supported argument type.");
301 }
302 }
303
304 public static class ENamedElementComparator implements Comparator<ENamedElement> {
305 @Override
306 public int compare(ENamedElement eClass1, ENamedElement eClass2) {
307 return eClass1.getName().compareTo(eClass2.getName());
308 }
309 }
310
311 /**
312 * This class is used to store
313 * <ul>
314 * <li>{@link EClass}es,</li>
315 * <li>{@link EAttribute}s,</li>
316 * <li>{@link EReference}s,</li>
317 * <li>EAttributes by EClasses,</li>
318 * <li>EReferences by EClasses</li>
319 * </ul>
320 * for a given set of {@link EPackage}s.
321 *
322 */
323 public static class MetaModelElements {
324 public Set<EPackage> metaModelPackages;
325 public Set<EClass> classes;
326 public Set<EAttribute> attributes;
327 public Set<EReference> references;
328 public Map<EClass, Set<EAttribute>> attributesOfClass;
329 public Map<EClass, Set<EReference>> referencesOfClass;
330 }
331
332 /**
333 * Traverses the full metamodel on the given {@link EPackage}s and returns all the classes, attributes and
334 * references it contains.
335 *
336 * @param metaModelPackages
337 * The set of {@link EPackage}s.
338 * @return A {@link MetaModelElements} instance containing the metamodel elements.
339 */
340 public static MetaModelElements getAllMetaModelElements(Set<EPackage> metaModelPackages) {
341 return getMetaModelElements(metaModelPackages, true, true, true);
342 }
343
344 /**
345 * Return a {@link MetaModelElements} instance populated with its {@link MetaModelElements#classes}.
346 *
347 * @param metaModelPackages
348 * The set of {@link EPackage}s.
349 * @return AA {@link MetaModelElements} instance.
350 */
351 public static MetaModelElements getClasses(Set<EPackage> metaModelPackages) {
352 return getMetaModelElements(metaModelPackages, true, false, false);
353 }
354
355 /**
356 * Return a {@link MetaModelElements} instance populated with its {@link MetaModelElements#references} and
357 * {@link MetaModelElements#referencesOfClass}.
358 *
359 * @param metaModelPackages
360 * The set of {@link EPackage}s.
361 * @return AA {@link MetaModelElements} instance.
362 */
363 public static MetaModelElements getReferences(Set<EPackage> metaModelPackages) {
364 return getMetaModelElements(metaModelPackages, false, true, false);
365 }
366
367 /**
368 * Return a {@link MetaModelElements} instance populated with its {@link MetaModelElements#attributes} and
369 * {@link MetaModelElements#attributesOfClass}.
370 *
371 * @param metaModelPackages
372 * The set of {@link EPackage}s.
373 * @return AA {@link MetaModelElements} instance.
374 */
375 public static MetaModelElements getAttrbiutes(Set<EPackage> metaModelPackages) {
376 return getMetaModelElements(metaModelPackages, false, false, true);
377 }
378
379 private static MetaModelElements getMetaModelElements(Set<EPackage> metaModelPackages, boolean getClasses,
380 boolean getReferences, boolean getAttrbiutes) {
381
382 Comparator<ENamedElement> comparator = new ENamedElementComparator();
383
384 MetaModelElements result = new MetaModelElements();
385 result.metaModelPackages = metaModelPackages;
386 if (getClasses) {
387 result.classes = new TreeSet<EClass>(comparator);
388 }
389 if (getReferences) {
390 result.references = new HashSet<EReference>();
391 result.referencesOfClass = new HashMap<EClass, Set<EReference>>();
392 }
393 if (getAttrbiutes) {
394 result.attributes = new HashSet<EAttribute>();
395 result.attributesOfClass = new HashMap<EClass, Set<EAttribute>>();
396 }
397 for (EPackage ePackage : metaModelPackages) {
398 for (EClassifier eClassifier : ePackage.getEClassifiers()) {
399 if (eClassifier instanceof EClass) {
400 EClass eClass = ((EClass) eClassifier);
401 if (getClasses) {
402 result.classes.add(eClass);
403 }
404 if (getReferences) {
405 result.referencesOfClass.put(eClass, new TreeSet<EReference>(comparator));
406 for (EReference eReference : eClass.getEAllReferences()) {
407 result.references.add(eReference);
408 result.referencesOfClass.get(eClass).add(eReference);
409 }
410 }
411 if (getAttrbiutes) {
412 result.attributesOfClass.put(eClass, new TreeSet<EAttribute>(comparator));
413 for (EAttribute eAttribute : eClass.getEAllAttributes()) {
414 result.attributes.add(eAttribute);
415 result.attributesOfClass.get(eClass).add(eAttribute);
416 }
417 }
418 }
419 }
420 }
421 return result;
422 }
423
424}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/Hasher.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/Hasher.java
new file mode 100644
index 00000000..0c5d7eba
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/Hasher.java
@@ -0,0 +1,86 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.util;
10
11import java.math.BigInteger;
12import java.security.MessageDigest;
13import java.security.NoSuchAlgorithmException;
14
15import org.eclipse.viatra.dse.api.DSEException;
16
17/**
18 * Utility class that encapsulates a {@link MessageDigest} instance to aid calculating hash values more easily, and to
19 * reuse a {@link MessageDigest} instance.
20 *
21 */
22public final class Hasher {
23 private MessageDigest md;
24
25 private static final int HEX = 16;
26
27 private Hasher(MessageDigest md) {
28 this.md = md;
29 }
30
31 /**
32 * Calculates and returns a hash value.
33 *
34 * @param data
35 * the data to be hashed in a {@link String}.
36 * @return the hash value in some {@link String} representation.
37 */
38 public String hash(String data) {
39 md.update(data.getBytes(), 0, data.length());
40 return new String(md.digest());
41 }
42
43 @SuppressWarnings("unused")
44 private String alternateHashBest(String data) {
45 md.update(data.getBytes(), 0, data.length());
46 return new String(md.digest());
47 }
48
49 @SuppressWarnings("unused")
50 private String alternateHashSecondBest(String data) {
51 md.update(data.getBytes(), 0, data.length());
52 return new BigInteger(1, md.digest()).toString(HEX);
53 }
54
55 @SuppressWarnings("unused")
56 private String alternateHashThirdBest(String data) {
57 md.update(data.getBytes(), 0, data.length());
58 byte[] array = md.digest();
59 StringBuilder sb = new StringBuilder();
60 for (int i = 0; i < array.length; i++) {
61 sb.append(Integer.toHexString((int) array[i]));
62 }
63 return sb.toString();
64 }
65
66 /**
67 * Returns a {@link Hasher} with an internal {@link MessageDigest} that is based on the protocol named
68 * {@code protocoll}.
69 *
70 * @param protocoll
71 * the name of the hash algorythm.
72 * @return the initialized {@link Hasher}
73 *
74 * @throws DSEException
75 * on initialization failure.
76 */
77 public static Hasher getHasher(String protocoll) {
78 try {
79 return new Hasher(MessageDigest.getInstance(protocoll));
80 } catch (NoSuchAlgorithmException e) {
81 throw new DSEException(e);
82 }
83 }
84
85 public static final String SHA1_PROTOCOLL = "SHA-1";
86}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/ValueComparableEObjectStringMap.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/ValueComparableEObjectStringMap.java
new file mode 100644
index 00000000..49af05d1
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/ValueComparableEObjectStringMap.java
@@ -0,0 +1,63 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.util;
10
11import java.util.Comparator;
12import java.util.HashMap;
13import java.util.Map;
14import java.util.TreeMap;
15
16import org.eclipse.emf.ecore.EObject;
17
18import com.google.common.base.Functions;
19import com.google.common.collect.Ordering;
20
21/**
22 *
23 * This custom {@link TreeMap} implementation enables to store {@link EObject}-{@link String} pairs sorted by values
24 * (strings). It works as expected if the map is modified in any way, hence the map will still be sorted by values on
25 * the new set of entries.
26 *
27 * It is allowed to have two entries with the same EObject key (and also with same values).
28 *
29 * The short coming of the class is that EObjects are compared to each other by their
30 * {@link System#identityHashCode(Object)}, which may lead to unexpected errors.
31 *
32 * @author Andras Szabolcs Nagy
33 *
34 */
35public class ValueComparableEObjectStringMap extends TreeMap<EObject, String> {
36
37 private static final class EObjectComparator implements Comparator<EObject> {
38 @Override
39 public int compare(EObject o1, EObject o2) {
40 return Integer.valueOf(System.identityHashCode(o1)).compareTo(Integer.valueOf(System.identityHashCode(o2)));
41 }
42 }
43
44 private final Map<EObject, String> innerMap;
45
46 public ValueComparableEObjectStringMap() {
47 this(new HashMap<EObject, String>());
48 }
49
50 private ValueComparableEObjectStringMap(Map<EObject, String> innerMap) {
51 super(Ordering.natural().onResultOf(Functions.forMap(innerMap)).compound(new EObjectComparator()));
52 this.innerMap = innerMap;
53 }
54
55 @Override
56 public String put(EObject keyEObject, String stringValue) {
57 if (innerMap.containsKey(keyEObject)) {
58 remove(keyEObject);
59 }
60 innerMap.put(keyEObject, stringValue);
61 return super.put(keyEObject, stringValue);
62 }
63}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/DesignSpaceVisualizerOptions.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/DesignSpaceVisualizerOptions.java
new file mode 100644
index 00000000..bb8000d5
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/DesignSpaceVisualizerOptions.java
@@ -0,0 +1,56 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.visualizer;
10
11public class DesignSpaceVisualizerOptions {
12
13 public boolean showExplorationTrace = true;
14 public boolean showStateCodes = true;
15 public boolean showTransitionCodes = true;
16
17 public DesignSpaceVisualizerOptions withOutExploraionTrace() {
18 showExplorationTrace = false;
19 return this;
20 }
21
22 public DesignSpaceVisualizerOptions withOutstateCodes() {
23 showStateCodes = false;
24 return this;
25 }
26
27 public DesignSpaceVisualizerOptions withOutTransitionCodes() {
28 showTransitionCodes = false;
29 return this;
30 }
31
32 public boolean isShowExplorationTrace() {
33 return showExplorationTrace;
34 }
35
36 public void setShowExplorationTrace(boolean showExplorationTrace) {
37 this.showExplorationTrace = showExplorationTrace;
38 }
39
40 public boolean isShowStateCodes() {
41 return showStateCodes;
42 }
43
44 public void setShowStateCodes(boolean showStateCodes) {
45 this.showStateCodes = showStateCodes;
46 }
47
48 public boolean isShowTransitionCodes() {
49 return showTransitionCodes;
50 }
51
52 public void setShowTransitionCodes(boolean showTransitionCodes) {
53 this.showTransitionCodes = showTransitionCodes;
54 }
55
56}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IDesignSpaceVisualizer.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IDesignSpaceVisualizer.java
new file mode 100644
index 00000000..da598b91
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IDesignSpaceVisualizer.java
@@ -0,0 +1,39 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.visualizer;
10
11import org.eclipse.viatra.dse.api.DesignSpaceExplorer;
12import org.eclipse.viatra.dse.base.ThreadContext;
13
14/**
15 *
16 * An implementation of this interface is notified about the traversal of the design space from every traversing thread,
17 * if registered to the {@link DesignSpaceExplorer}. Its purpose is to able to visualize the design space (a directed
18 * graph with IDs of the nodes and transitions) and to able to visualize the order of the exploration (the trace of a
19 * thread).
20 *
21 * @author Andras Szabolcs Nagy
22 *
23 */
24public interface IDesignSpaceVisualizer extends IExploreEventHandler {
25
26 /**
27 * Initializes the instance with a starting thread's context. Can be called multiple times and concurrently.
28 *
29 * @see DesignSpaceVisualizerOptions
30 * @param context
31 */
32 void init(ThreadContext context);
33
34 /**
35 * Saves the captured data.
36 */
37 void save();
38
39}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IExploreEventHandler.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IExploreEventHandler.java
new file mode 100644
index 00000000..9f902f31
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IExploreEventHandler.java
@@ -0,0 +1,40 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.visualizer;
10
11import org.eclipse.viatra.dse.base.DesignSpaceManager;
12
13/**
14 * An implementation of this interface is notified about every move in the design space (firing a rule activation or
15 * undoing it) of a single thread, if registered to the corresponding {@link DesignSpaceManager}. Its methods are called
16 * synchronously, therefore the implementation can have an impact on the performance. Also note, if the same instance is
17 * registered to multiple threads ({@link DesignSpaceManager}), it has to be thread safe.
18 *
19 * @author Andras Szabolcs Nagy
20 *
21 */
22public interface IExploreEventHandler {
23
24 /**
25 * Called by the {@link DesignSpaceManager}, after a rule activation (transition) is fired. Multiple calls with the
26 * same transition can occur.
27 *
28 * @param transition The fired transition.
29 */
30 void transitionFired(Object transition);
31
32 /**
33 * Called by the {@link DesignSpaceManager}, after undoing the previously fired rule activation (transition).
34 * Multiple calls with the same transition can occur.
35 *
36 * @param transition The undone transition.
37 */
38 void undo(Object transition);
39
40}