diff options
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver')
10 files changed, 365 insertions, 78 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend index edcca676..701eb054 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend | |||
@@ -16,8 +16,9 @@ import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator | |||
16 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser | 16 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser |
17 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | 17 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation |
18 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage | 18 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage |
19 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.AbstractNeighbourhoodBasedStateCoderFactory | ||
19 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory | 20 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory |
20 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedStateCoderFactory | 21 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.PairwiseNeighbourhoodBasedStateCoderFactory |
21 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BestFirstStrategyForModelGeneration | 22 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BestFirstStrategyForModelGeneration |
22 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityChecker | 23 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityChecker |
23 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.LoggerSolutionFoundHandler | 24 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.LoggerSolutionFoundHandler |
@@ -49,7 +50,7 @@ class ViatraReasoner extends LogicReasoner { | |||
49 | ReasonerWorkspace workspace) throws LogicReasonerException { | 50 | ReasonerWorkspace workspace) throws LogicReasonerException { |
50 | val viatraConfig = configuration.asConfig | 51 | val viatraConfig = configuration.asConfig |
51 | 52 | ||
52 | if (viatraConfig.debugConfiguration.logging) { | 53 | if (viatraConfig.documentationLevel == DocumentationLevel.FULL) { |
53 | DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.VERBOSE_FULL) | 54 | DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.VERBOSE_FULL) |
54 | } else { | 55 | } else { |
55 | DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.WARN) | 56 | DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.WARN) |
@@ -139,7 +140,7 @@ class ViatraReasoner extends LogicReasoner { | |||
139 | dse.setInitialModel(emptySolution, false) | 140 | dse.setInitialModel(emptySolution, false) |
140 | 141 | ||
141 | val IStateCoderFactory statecoder = if (viatraConfig.stateCoderStrategy == StateCoderStrategy.Neighbourhood) { | 142 | val IStateCoderFactory statecoder = if (viatraConfig.stateCoderStrategy == StateCoderStrategy.Neighbourhood) { |
142 | new NeighbourhoodBasedStateCoderFactory | 143 | new PairwiseNeighbourhoodBasedStateCoderFactory |
143 | } else { | 144 | } else { |
144 | new IdentifierBasedStateCoderFactory | 145 | new IdentifierBasedStateCoderFactory |
145 | } | 146 | } |
@@ -239,7 +240,7 @@ class ViatraReasoner extends LogicReasoner { | |||
239 | } | 240 | } |
240 | } | 241 | } |
241 | 242 | ||
242 | private def dispatch long runtime(NeighbourhoodBasedStateCoderFactory sc) { | 243 | private def dispatch long runtime(AbstractNeighbourhoodBasedStateCoderFactory sc) { |
243 | sc.sumStatecoderRuntime | 244 | sc.sumStatecoderRuntime |
244 | } | 245 | } |
245 | 246 | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend index e6aee20c..99decdd9 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend | |||
@@ -64,8 +64,7 @@ class DiversityDescriptor { | |||
64 | } | 64 | } |
65 | 65 | ||
66 | class DebugConfiguration { | 66 | class DebugConfiguration { |
67 | public var logging = false | 67 | public var PartialInterpretationVisualiser partialInterpretatioVisualiser = null |
68 | public var PartialInterpretationVisualiser partialInterpretatioVisualiser = null; | ||
69 | public var partalInterpretationVisualisationFrequency = 1 | 68 | public var partalInterpretationVisualisationFrequency = 1 |
70 | } | 69 | } |
71 | 70 | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java index 077fea21..144e7484 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java | |||
@@ -20,8 +20,8 @@ import java.util.List; | |||
20 | import java.util.PriorityQueue; | 20 | import java.util.PriorityQueue; |
21 | import java.util.Random; | 21 | import java.util.Random; |
22 | 22 | ||
23 | import org.apache.log4j.Level; | ||
24 | import org.apache.log4j.Logger; | 23 | import org.apache.log4j.Logger; |
24 | import org.eclipse.emf.ecore.EObject; | ||
25 | import org.eclipse.emf.ecore.util.EcoreUtil; | 25 | import org.eclipse.emf.ecore.util.EcoreUtil; |
26 | import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; | 26 | import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; |
27 | import org.eclipse.viatra.dse.base.ThreadContext; | 27 | import org.eclipse.viatra.dse.base.ThreadContext; |
@@ -254,6 +254,7 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
254 | activationIds = new ArrayList<Object>(context.getUntraversedActivationIds()); | 254 | activationIds = new ArrayList<Object>(context.getUntraversedActivationIds()); |
255 | Collections.shuffle(activationIds); | 255 | Collections.shuffle(activationIds); |
256 | } catch (NullPointerException e) { | 256 | } catch (NullPointerException e) { |
257 | logger.warn("Unexpected state code: " + context.getDesignSpaceManager().getCurrentState()); | ||
257 | numberOfStatecoderFail++; | 258 | numberOfStatecoderFail++; |
258 | activationIds = Collections.emptyList(); | 259 | activationIds = Collections.emptyList(); |
259 | } | 260 | } |
@@ -295,7 +296,10 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
295 | int id = ++numberOfPrintedModel; | 296 | int id = ++numberOfPrintedModel; |
296 | if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) { | 297 | if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) { |
297 | PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); | 298 | PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); |
298 | visualisation.writeToFile(workspace, String.format("state%09d.png", id)); | 299 | logger.debug("Visualizing state: " + id + " (" + context.getDesignSpaceManager().getCurrentState() + ")"); |
300 | String name = String.format("state%09d", id); | ||
301 | visualisation.writeToFile(workspace, name + ".png"); | ||
302 | workspace.writeModel((EObject) context.getModel(), name + ".xmi"); | ||
299 | } | 303 | } |
300 | } | 304 | } |
301 | } | 305 | } |
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend index 241bef2a..cd911ab5 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend | |||
@@ -1,60 +1,10 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | 1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization |
2 | 2 | ||
3 | import java.util.Comparator | ||
4 | import org.eclipse.viatra.dse.base.ThreadContext | 3 | import org.eclipse.viatra.dse.base.ThreadContext |
5 | import org.eclipse.xtend.lib.annotations.Accessors | ||
6 | import org.eclipse.xtend.lib.annotations.Data | ||
7 | |||
8 | abstract class ObjectiveThreshold { | ||
9 | public static val NO_THRESHOLD = new hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold { | ||
10 | override isHard() { | ||
11 | false | ||
12 | } | ||
13 | |||
14 | override satisfiesThreshold(double cost, Comparator<Double> comparator) { | ||
15 | true | ||
16 | } | ||
17 | } | ||
18 | |||
19 | private new() { | ||
20 | } | ||
21 | |||
22 | def boolean isHard() { | ||
23 | true | ||
24 | } | ||
25 | |||
26 | def boolean satisfiesThreshold(double cost, Comparator<Double> comparator) | ||
27 | |||
28 | @Data | ||
29 | static class Exclusive extends ObjectiveThreshold { | ||
30 | val double threshold | ||
31 | |||
32 | override satisfiesThreshold(double cost, Comparator<Double> comparator) { | ||
33 | comparator.compare(threshold, cost) > 0 | ||
34 | } | ||
35 | } | ||
36 | |||
37 | @Data | ||
38 | static class Inclusive extends ObjectiveThreshold { | ||
39 | val double threshold | ||
40 | |||
41 | override satisfiesThreshold(double cost, Comparator<Double> comparator) { | ||
42 | comparator.compare(threshold, cost) >= 0 | ||
43 | } | ||
44 | } | ||
45 | } | ||
46 | |||
47 | abstract class AbstractThreeValuedObjective implements IThreeValuedObjective { | ||
48 | @Accessors val String name | ||
49 | @Accessors ObjectiveKind kind | ||
50 | @Accessors ObjectiveThreshold threshold | ||
51 | @Accessors int level | ||
52 | 4 | ||
5 | abstract class AbstractThreeValuedObjective extends DirectionalThresholdObjective implements IThreeValuedObjective { | ||
53 | protected new(String name, ObjectiveKind kind, ObjectiveThreshold threshold, int level) { | 6 | protected new(String name, ObjectiveKind kind, ObjectiveThreshold threshold, int level) { |
54 | this.name = name | 7 | super(name, kind, threshold, level) |
55 | this.kind = kind | ||
56 | this.threshold = threshold | ||
57 | this.level = level | ||
58 | } | 8 | } |
59 | 9 | ||
60 | abstract def double getLowestPossibleFitness(ThreadContext threadContext) | 10 | abstract def double getLowestPossibleFitness(ThreadContext threadContext) |
@@ -82,21 +32,4 @@ abstract class AbstractThreeValuedObjective implements IThreeValuedObjective { | |||
82 | throw new IllegalStateException("Unknown three valued objective kind: " + kind) | 32 | throw new IllegalStateException("Unknown three valued objective kind: " + kind) |
83 | } | 33 | } |
84 | } | 34 | } |
85 | |||
86 | override isHardObjective() { | ||
87 | threshold.hard | ||
88 | } | ||
89 | |||
90 | override satisifiesHardObjective(Double fitness) { | ||
91 | threshold.satisfiesThreshold(fitness, comparator) | ||
92 | } | ||
93 | |||
94 | override getComparator() { | ||
95 | kind.comparator | ||
96 | } | ||
97 | |||
98 | override setComparator(Comparator<Double> comparator) { | ||
99 | kind = ObjectiveKind.fromComparator(comparator) | ||
100 | } | ||
101 | |||
102 | } | 35 | } |
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend new file mode 100644 index 00000000..0aa442f5 --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend | |||
@@ -0,0 +1,62 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import java.util.Collection | ||
5 | import org.eclipse.viatra.dse.base.ThreadContext | ||
6 | |||
7 | class CompositeDirectionalThresholdObjective extends DirectionalThresholdObjective { | ||
8 | val Collection<DirectionalThresholdObjective> objectives | ||
9 | |||
10 | new(String name, Collection<DirectionalThresholdObjective> objectives) { | ||
11 | this(name, objectives, getKind(objectives), getThreshold(objectives), getLevel(objectives)) | ||
12 | } | ||
13 | |||
14 | new(String name, DirectionalThresholdObjective... objectives) { | ||
15 | this(name, objectives as Collection<DirectionalThresholdObjective>) | ||
16 | } | ||
17 | |||
18 | protected new(String name, Iterable<DirectionalThresholdObjective> objectives, ObjectiveKind kind, | ||
19 | ObjectiveThreshold threshold, int level) { | ||
20 | super(name, kind, threshold, level) | ||
21 | this.objectives = ImmutableList.copyOf(objectives) | ||
22 | } | ||
23 | |||
24 | override createNew() { | ||
25 | new CompositeDirectionalThresholdObjective(name, objectives.map[createNew as DirectionalThresholdObjective], | ||
26 | kind, threshold, level) | ||
27 | } | ||
28 | |||
29 | override init(ThreadContext context) { | ||
30 | for (objective : objectives) { | ||
31 | objective.init(context) | ||
32 | } | ||
33 | } | ||
34 | |||
35 | override protected getRawFitness(ThreadContext context) { | ||
36 | var double fitness = 0 | ||
37 | for (objective : objectives) { | ||
38 | fitness += objective.getFitness(context) | ||
39 | } | ||
40 | fitness | ||
41 | } | ||
42 | |||
43 | private static def getKind(Collection<DirectionalThresholdObjective> objectives) { | ||
44 | val kinds = objectives.map[kind].toSet | ||
45 | if (kinds.size != 1) { | ||
46 | throw new IllegalArgumentException("Passed objectives must have the same kind") | ||
47 | } | ||
48 | kinds.head | ||
49 | } | ||
50 | |||
51 | private static def getThreshold(Collection<DirectionalThresholdObjective> objectives) { | ||
52 | objectives.map[threshold].reduce[a, b|a.merge(b)] | ||
53 | } | ||
54 | |||
55 | private static def int getLevel(Collection<DirectionalThresholdObjective> objectives) { | ||
56 | val levels = objectives.map[level].toSet | ||
57 | if (levels.size != 1) { | ||
58 | throw new IllegalArgumentException("Passed objectives must have the same level") | ||
59 | } | ||
60 | levels.head | ||
61 | } | ||
62 | } | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend new file mode 100644 index 00000000..376e3d1a --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend | |||
@@ -0,0 +1,164 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import java.util.Comparator | ||
4 | import org.eclipse.viatra.dse.base.ThreadContext | ||
5 | import org.eclipse.viatra.dse.objectives.IObjective | ||
6 | import org.eclipse.xtend.lib.annotations.Accessors | ||
7 | import org.eclipse.xtend.lib.annotations.Data | ||
8 | import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor | ||
9 | |||
10 | abstract class ObjectiveThreshold { | ||
11 | public static val NO_THRESHOLD = new ObjectiveThreshold { | ||
12 | override isHard() { | ||
13 | false | ||
14 | } | ||
15 | |||
16 | override satisfiesThreshold(double cost, Comparator<Double> comparator) { | ||
17 | true | ||
18 | } | ||
19 | |||
20 | override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) { | ||
21 | cost | ||
22 | } | ||
23 | |||
24 | override ObjectiveThreshold merge(ObjectiveThreshold other) { | ||
25 | if (other == NO_THRESHOLD) { | ||
26 | NO_THRESHOLD | ||
27 | } else { | ||
28 | throw new IllegalArgumentException("Merged thresholds must have the same type") | ||
29 | } | ||
30 | } | ||
31 | } | ||
32 | |||
33 | private new() { | ||
34 | } | ||
35 | |||
36 | def boolean isHard() { | ||
37 | true | ||
38 | } | ||
39 | |||
40 | def boolean satisfiesThreshold(double cost, ObjectiveKind kind) { | ||
41 | satisfiesThreshold(cost, kind.comparator) | ||
42 | } | ||
43 | |||
44 | def boolean satisfiesThreshold(double cost, Comparator<Double> comparator) | ||
45 | |||
46 | def double postProcessCost(double cost, ObjectiveKind kind) { | ||
47 | if (satisfiesThreshold(cost, kind)) { | ||
48 | postProcessSatisfactoryCost(cost, kind) | ||
49 | } else { | ||
50 | cost | ||
51 | } | ||
52 | } | ||
53 | |||
54 | protected def double postProcessSatisfactoryCost(double cost, ObjectiveKind kind) | ||
55 | |||
56 | def ObjectiveThreshold merge(ObjectiveThreshold other) | ||
57 | |||
58 | @Data | ||
59 | static class Exclusive extends ObjectiveThreshold { | ||
60 | static val EPSILON = 0.1 | ||
61 | |||
62 | val double threshold | ||
63 | val boolean clampToThreshold | ||
64 | |||
65 | @FinalFieldsConstructor | ||
66 | new() { | ||
67 | } | ||
68 | |||
69 | new(double threshold) { | ||
70 | this(threshold, true) | ||
71 | } | ||
72 | |||
73 | override satisfiesThreshold(double cost, Comparator<Double> comparator) { | ||
74 | comparator.compare(threshold, cost) < 0 | ||
75 | } | ||
76 | |||
77 | override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) { | ||
78 | if (clampToThreshold) { | ||
79 | threshold + Math.signum(kind.satisfiedValue) * EPSILON | ||
80 | } else { | ||
81 | cost | ||
82 | } | ||
83 | } | ||
84 | |||
85 | override ObjectiveThreshold merge(ObjectiveThreshold other) { | ||
86 | if (other instanceof Exclusive) { | ||
87 | new Exclusive(threshold + other.threshold) | ||
88 | } else { | ||
89 | throw new IllegalArgumentException("Merged thresholds must have the same type") | ||
90 | } | ||
91 | } | ||
92 | } | ||
93 | |||
94 | @Data | ||
95 | static class Inclusive extends ObjectiveThreshold { | ||
96 | val double threshold | ||
97 | val boolean clampToThreshold | ||
98 | |||
99 | @FinalFieldsConstructor | ||
100 | new() { | ||
101 | } | ||
102 | |||
103 | new(double threshold) { | ||
104 | this(threshold, true) | ||
105 | } | ||
106 | |||
107 | override satisfiesThreshold(double cost, Comparator<Double> comparator) { | ||
108 | comparator.compare(threshold, cost) <= 0 | ||
109 | } | ||
110 | |||
111 | override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) { | ||
112 | if (clampToThreshold) { | ||
113 | threshold | ||
114 | } else { | ||
115 | cost | ||
116 | } | ||
117 | } | ||
118 | |||
119 | override ObjectiveThreshold merge(ObjectiveThreshold other) { | ||
120 | if (other instanceof Inclusive) { | ||
121 | new Inclusive(threshold + other.threshold) | ||
122 | } else { | ||
123 | throw new IllegalArgumentException("Merged thresholds must have the same type") | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | |||
129 | abstract class DirectionalThresholdObjective implements IObjective { | ||
130 | @Accessors val String name | ||
131 | @Accessors ObjectiveKind kind | ||
132 | @Accessors ObjectiveThreshold threshold | ||
133 | @Accessors int level | ||
134 | |||
135 | protected new(String name, ObjectiveKind kind, ObjectiveThreshold threshold, int level) { | ||
136 | this.name = name | ||
137 | this.kind = kind | ||
138 | this.threshold = threshold | ||
139 | this.level = level | ||
140 | } | ||
141 | |||
142 | override isHardObjective() { | ||
143 | threshold.hard | ||
144 | } | ||
145 | |||
146 | override satisifiesHardObjective(Double fitness) { | ||
147 | threshold.satisfiesThreshold(fitness, comparator) | ||
148 | } | ||
149 | |||
150 | override getComparator() { | ||
151 | kind.comparator | ||
152 | } | ||
153 | |||
154 | override setComparator(Comparator<Double> comparator) { | ||
155 | kind = ObjectiveKind.fromComparator(comparator) | ||
156 | } | ||
157 | |||
158 | override getFitness(ThreadContext context) { | ||
159 | val fitness = getRawFitness(context) | ||
160 | threshold.postProcessCost(fitness, kind) | ||
161 | } | ||
162 | |||
163 | protected def double getRawFitness(ThreadContext context) | ||
164 | } | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend new file mode 100644 index 00000000..a0c6a2c1 --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend | |||
@@ -0,0 +1,52 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import java.util.Collection | ||
5 | import org.eclipse.viatra.dse.base.ThreadContext | ||
6 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
7 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification | ||
8 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
9 | import org.eclipse.xtend.lib.annotations.Data | ||
10 | |||
11 | @Data | ||
12 | class MatchCostElement { | ||
13 | val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification | ||
14 | val double weight | ||
15 | } | ||
16 | |||
17 | class MatchCostObjective extends DirectionalThresholdObjective { | ||
18 | val Collection<MatchCostElement> costElements | ||
19 | Collection<CostElementMatcher> matchers | ||
20 | |||
21 | new(String name, Collection<MatchCostElement> costElements, ObjectiveKind kind, ObjectiveThreshold threshold, | ||
22 | int level) { | ||
23 | super(name, kind, threshold, level) | ||
24 | this.costElements = costElements | ||
25 | } | ||
26 | |||
27 | override createNew() { | ||
28 | new MatchCostObjective(name, costElements, kind, threshold, level) | ||
29 | } | ||
30 | |||
31 | override init(ThreadContext context) { | ||
32 | val queryEngine = context.queryEngine | ||
33 | matchers = ImmutableList.copyOf(costElements.map [ | ||
34 | val matcher = querySpecification.getMatcher(queryEngine) | ||
35 | new CostElementMatcher(matcher, weight) | ||
36 | ]) | ||
37 | } | ||
38 | |||
39 | override protected getRawFitness(ThreadContext context) { | ||
40 | var double cost = 0 | ||
41 | for (it : matchers) { | ||
42 | cost += weight * matcher.countMatches | ||
43 | } | ||
44 | cost | ||
45 | } | ||
46 | |||
47 | @Data | ||
48 | private static class CostElementMatcher { | ||
49 | val ViatraQueryMatcher<? extends IPatternMatch> matcher | ||
50 | val double weight | ||
51 | } | ||
52 | } | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java index f65428fe..cbbaaafd 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java | |||
@@ -12,6 +12,16 @@ public enum ObjectiveKind { | |||
12 | return Comparators.LOWER_IS_BETTER; | 12 | return Comparators.LOWER_IS_BETTER; |
13 | } | 13 | } |
14 | 14 | ||
15 | @Override | ||
16 | public double getInvalidValue() { | ||
17 | return Double.POSITIVE_INFINITY; | ||
18 | } | ||
19 | |||
20 | @Override | ||
21 | public double getSatisfiedValue() { | ||
22 | return Double.NEGATIVE_INFINITY; | ||
23 | } | ||
24 | |||
15 | }, | 25 | }, |
16 | HIGHER_IS_BETTER { | 26 | HIGHER_IS_BETTER { |
17 | 27 | ||
@@ -20,10 +30,24 @@ public enum ObjectiveKind { | |||
20 | return Comparators.HIGHER_IS_BETTER; | 30 | return Comparators.HIGHER_IS_BETTER; |
21 | } | 31 | } |
22 | 32 | ||
33 | @Override | ||
34 | public double getInvalidValue() { | ||
35 | return Double.NEGATIVE_INFINITY; | ||
36 | } | ||
37 | |||
38 | @Override | ||
39 | public double getSatisfiedValue() { | ||
40 | return Double.POSITIVE_INFINITY; | ||
41 | } | ||
42 | |||
23 | }; | 43 | }; |
24 | 44 | ||
25 | public abstract Comparator<Double> getComparator(); | 45 | public abstract Comparator<Double> getComparator(); |
26 | 46 | ||
47 | public abstract double getInvalidValue(); | ||
48 | |||
49 | public abstract double getSatisfiedValue(); | ||
50 | |||
27 | public static ObjectiveKind fromComparator(Comparator<Double> comparator) { | 51 | public static ObjectiveKind fromComparator(Comparator<Double> comparator) { |
28 | if (Comparators.LOWER_IS_BETTER.equals(comparator)) { | 52 | if (Comparators.LOWER_IS_BETTER.equals(comparator)) { |
29 | return ObjectiveKind.LOWER_IS_BETTER; | 53 | return ObjectiveKind.LOWER_IS_BETTER; |
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend new file mode 100644 index 00000000..d355f5be --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend | |||
@@ -0,0 +1,48 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import org.eclipse.viatra.dse.base.ThreadContext | ||
4 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
5 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification | ||
6 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
7 | |||
8 | class QueryBasedObjective extends DirectionalThresholdObjective { | ||
9 | val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification | ||
10 | ViatraQueryMatcher<? extends IPatternMatch> matcher | ||
11 | |||
12 | new(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification, | ||
13 | ObjectiveKind kind, ObjectiveThreshold threshold, int level) { | ||
14 | super(querySpecification.simpleName + " objective", kind, threshold, level) | ||
15 | if (querySpecification.parameters.size != 1) { | ||
16 | throw new IllegalArgumentException("Objective query must have a single parameter") | ||
17 | } | ||
18 | this.querySpecification = querySpecification | ||
19 | } | ||
20 | |||
21 | override createNew() { | ||
22 | new QueryBasedObjective(querySpecification, kind, threshold, level) | ||
23 | } | ||
24 | |||
25 | override init(ThreadContext context) { | ||
26 | matcher = querySpecification.getMatcher(context.queryEngine) | ||
27 | } | ||
28 | |||
29 | override protected getRawFitness(ThreadContext context) { | ||
30 | val iterator = matcher.allMatches.iterator | ||
31 | if (!iterator.hasNext) { | ||
32 | return invalidValue | ||
33 | } | ||
34 | val value = iterator.next.get(0) | ||
35 | if (iterator.hasNext) { | ||
36 | throw new IllegalStateException("Multiple matches for objective query") | ||
37 | } | ||
38 | if (value instanceof Number) { | ||
39 | value.doubleValue | ||
40 | } else { | ||
41 | throw new IllegalStateException("Objective value is not an instance of Number") | ||
42 | } | ||
43 | } | ||
44 | |||
45 | private def getInvalidValue() { | ||
46 | kind.invalidValue | ||
47 | } | ||
48 | } | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend index e2585c83..0a6fd55b 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend | |||
@@ -42,7 +42,7 @@ class ThreeValuedCostObjective extends AbstractThreeValuedObjective { | |||
42 | ]) | 42 | ]) |
43 | } | 43 | } |
44 | 44 | ||
45 | override getFitness(ThreadContext context) { | 45 | override getRawFitness(ThreadContext context) { |
46 | var int cost = 0 | 46 | var int cost = 0 |
47 | for (matcher : matchers) { | 47 | for (matcher : matchers) { |
48 | cost += matcher.weight * matcher.currentMatcher.countMatches | 48 | cost += matcher.weight * matcher.currentMatcher.countMatches |