aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver
diff options
context:
space:
mode:
authorLibravatar 20001LastOrder <boqi.chen@mail.mcgill.ca>2020-11-04 01:16:22 -0500
committerLibravatar 20001LastOrder <boqi.chen@mail.mcgill.ca>2020-11-04 01:16:22 -0500
commit93243cb3faf1ccd733081fcf380559ac03c9ad35 (patch)
tree421f9f174eb77c387b5acaa05f01e64a62cab3a7 /Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver
parentadd realistic solver (diff)
parentOptimizing generator with linear objective functions (diff)
downloadVIATRA-Generator-93243cb3faf1ccd733081fcf380559ac03c9ad35.tar.gz
VIATRA-Generator-93243cb3faf1ccd733081fcf380559ac03c9ad35.tar.zst
VIATRA-Generator-93243cb3faf1ccd733081fcf380559ac03c9ad35.zip
merge with current master, comment numerical solver related logging
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver')
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodBasedGlobalConstraint.xtend21
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodProvider.xtend201
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend315
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend70
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BasicScopeGlobalConstraint.xtend103
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java191
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend184
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DseUtils.xtend66
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java69
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/InconsistentScopeGlobalConstraint.xtend25
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/LoggerSolutionFoundHandler.xtend24
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend107
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend19
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend5
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PunishSizeObjective.xtend52
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend6
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionCopier.xtend82
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend6
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend120
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend27
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend15
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend54
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend250
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend43
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend35
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend62
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostElementMatchers.xtend137
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostObjectiveHint.xtend68
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend164
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IObjectiveBoundsProvider.xtend8
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IThreeValuedObjective.xtend10
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend52
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java60
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend48
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend80
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjectiveProvider.xtend205
36 files changed, 2500 insertions, 484 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodBasedGlobalConstraint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodBasedGlobalConstraint.xtend
index 28cf986d..691e0645 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodBasedGlobalConstraint.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodBasedGlobalConstraint.xtend
@@ -1,11 +1,10 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner
2 2
3import org.eclipse.viatra.dse.objectives.IGlobalConstraint 3import org.eclipse.viatra.dse.objectives.IGlobalConstraint
4import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod 4
5 5abstract class ModelGenerationMethodBasedGlobalConstraint implements IGlobalConstraint {
6abstract class ModelGenerationMethodBasedGlobalConstraint implements IGlobalConstraint { 6 val protected ModelGenerationMethod method
7 val protected ModelGenerationMethod method 7 new(ModelGenerationMethod method) {
8 new(ModelGenerationMethod method) { 8 this.method = method
9 this.method = method 9 }
10 } 10}
11} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodProvider.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodProvider.xtend
new file mode 100644
index 00000000..25137eba
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodProvider.xtend
@@ -0,0 +1,201 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner
2
3import com.google.common.collect.ImmutableMap
4import com.google.common.collect.ImmutableSet
5import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel
6import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
7import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.TransfomedViatraQuery
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics
9import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.CachingSimplePolyhedronScopePropagatorStrategy
10import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.CbcPolyhedronSolver
11import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeConstraintHint
12import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.MultiplicityGoalConstraintCalculator
13import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedronExtensionOperator
14import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedronScopePropagator
15import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.RelationConstraintCalculator
16import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagator
17import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy
18import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.TypeHierarchyScopePropagator
19import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.Z3PolyhedronSolver
20import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns
21import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.ModalPatternQueries
22import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.PatternProvider
23import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules.GoalConstraintProvider
24import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules.RefinementRuleProvider
25import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
26import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityChecker
27import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ViatraReasonerSolutionSaver
28import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ThreeValuedCostObjectiveProvider
29import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace
30import java.util.Collection
31import java.util.List
32import java.util.Map
33import java.util.Set
34import org.eclipse.viatra.dse.objectives.IObjective
35import org.eclipse.viatra.query.runtime.api.GenericQueryGroup
36import org.eclipse.viatra.query.runtime.api.IPatternMatch
37import org.eclipse.viatra.query.runtime.api.IQuerySpecification
38import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
39import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
40import org.eclipse.viatra.query.runtime.emf.EMFScope
41import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint
42import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
43import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule
44import org.eclipse.xtend.lib.annotations.Data
45import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ExtendedPolyhedronScopePropagatorStrategy
46
47@Data class ModelGenerationMethod {
48 ModelGenerationStatistics statistics
49
50 Collection<? extends BatchTransformationRule<?, ?>> objectRefinementRules
51 Collection<? extends BatchTransformationRule<?, ?>> relationRefinementRules
52
53 List<MultiplicityGoalConstraintCalculator> unfinishedMultiplicities
54
55 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWF
56
57 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidWF
58
59 Map<PConstraint, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> mustUnitPropagationPreconditions
60 Map<PConstraint, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> currentUnitPropagationPreconditions
61
62 Map<String, ModalPatternQueries> modalRelationQueries
63
64 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> allPatterns
65
66 Collection<IObjective> costObjectives
67 boolean optimizationProblem
68 ViatraReasonerSolutionSaver solutionSaver
69}
70
71class ModelGenerationMethodProvider {
72 val PatternProvider patternProvider = new PatternProvider
73 val RefinementRuleProvider refinementRuleProvider = new RefinementRuleProvider
74 val GoalConstraintProvider goalConstraintProvider = new GoalConstraintProvider
75 val relationConstraintCalculator = new RelationConstraintCalculator
76
77 def ModelGenerationMethod createModelGenerationMethod(
78 LogicProblem logicProblem,
79 PartialInterpretation emptySolution,
80 ReasonerWorkspace workspace,
81 ViatraReasonerConfiguration config
82 ) {
83 val statistics = new ModelGenerationStatistics
84 val debugLevel = config.documentationLevel
85 val writeFiles = (debugLevel === DocumentationLevel.NORMAL || debugLevel === DocumentationLevel.FULL)
86
87 val Set<PQuery> existingQueries = logicProblem.relations.map[annotations].flatten.filter(TransfomedViatraQuery).
88 map[it.patternPQuery as PQuery].toSet
89
90 val relationConstraints = relationConstraintCalculator.calculateRelationConstraints(logicProblem)
91 val queries = patternProvider.generateQueries(logicProblem, emptySolution, statistics, existingQueries,
92 workspace, config.typeInferenceMethod, config.scopePropagatorStrategy, relationConstraints, config.hints,
93 config.unitPropagationPatternGenerators, writeFiles)
94
95 val unfinishedMultiplicities = goalConstraintProvider.getUnfinishedMultiplicityQueries(logicProblem, queries,
96 config.calculateObjectCreationCosts)
97 val unfinishedWF = queries.getUnfinishedWFQueries.values
98 val modalRelationQueriesBuilder = ImmutableMap.builder
99 for (entry : queries.modalRelationQueries.entrySet) {
100 val annotation = entry.key.annotations.filter(TransfomedViatraQuery).head
101 if (annotation !== null) {
102 modalRelationQueriesBuilder.put(annotation.patternFullyQualifiedName, entry.value)
103 }
104 }
105 val modalRelationQueries = modalRelationQueriesBuilder.build
106 val invalidWF = queries.getInvalidWFQueries.values
107 val mustUnitPropagationPreconditions = queries.getMustUnitPropagationPreconditionPatterns
108 val currentUnitPropagationPreconditions = queries.getCurrentUnitPropagationPreconditionPatterns
109 val queriesToPrepare = ImmutableSet.builder.addAll(queries.refineObjectQueries.values).addAll(
110 queries.refineTypeQueries.values).addAll(queries.refineRelationQueries.values).addAll(
111 queries.mustRelationPropagationQueries.values).addAll(queries.multiplicityConstraintQueries.values.flatMap [
112 allQueries
113 ]).addAll(queries.unfinishedWFQueries.values).addAll(queries.invalidWFQueries.values).addAll(
114 queries.mustUnitPropagationPreconditionPatterns.values).addAll(
115 queries.currentUnitPropagationPreconditionPatterns.values).add(queries.hasElementInContainmentQuery).build
116 val queryEngine = ViatraQueryEngine.on(new EMFScope(emptySolution))
117 GenericQueryGroup.of(queriesToPrepare).prepare(queryEngine)
118
119 val objectiveProvider = new ThreeValuedCostObjectiveProvider(queryEngine, emptySolution, modalRelationQueries)
120 val transformedObjectives = objectiveProvider.getCostObjectives(config.costObjectives)
121
122 val solutionSaver = new ViatraReasonerSolutionSaver(transformedObjectives.leveledExtremalObjectives,
123 config.solutionScope.numberOfRequiredSolutions, DiversityChecker.of(config.diversityRequirement))
124
125 val allHints = ImmutableSet.builder
126 allHints.addAll(config.hints)
127 for (hint : transformedObjectives.hints) {
128 hint.boundsProvider = solutionSaver
129 allHints.add(hint)
130 }
131
132 val scopePropagator = createScopePropagator(config.scopePropagatorStrategy, emptySolution, allHints.build,
133 transformedObjectives.extensionOperators, queries, statistics)
134 scopePropagator.propagateAllScopeConstraints
135 val unitRulePropagator = refinementRuleProvider.createUnitPrulePropagator(logicProblem, emptySolution, queries,
136 scopePropagator, statistics)
137 val objectRefinementRules = refinementRuleProvider.createObjectRefinementRules(logicProblem, emptySolution,
138 queries, unitRulePropagator, config.nameNewElements, statistics)
139 val relationRefinementRules = refinementRuleProvider.createRelationRefinementRules(queries, unitRulePropagator,
140 statistics)
141
142 return new ModelGenerationMethod(
143 statistics,
144 objectRefinementRules.values,
145 relationRefinementRules.values,
146 unfinishedMultiplicities,
147 unfinishedWF,
148 invalidWF,
149 mustUnitPropagationPreconditions,
150 currentUnitPropagationPreconditions,
151 modalRelationQueries,
152 queries.allQueries,
153 transformedObjectives.objectives,
154 transformedObjectives.optimizationProblem,
155 solutionSaver
156 )
157 }
158
159 private def createScopePropagator(ScopePropagatorStrategy scopePropagatorStrategy,
160 PartialInterpretation emptySolution, Collection<LinearTypeConstraintHint> hints,
161 Collection<PolyhedronExtensionOperator> extensionOperators, GeneratedPatterns queries,
162 ModelGenerationStatistics statistics) {
163 if (!hints.empty && !(scopePropagatorStrategy instanceof ScopePropagatorStrategy.Polyhedral)) {
164 throw new IllegalArgumentException("Only the Polyhedral scope propagator strategy can use hints.")
165 }
166 switch (scopePropagatorStrategy) {
167 case ScopePropagatorStrategy.None,
168 case ScopePropagatorStrategy.Basic:
169 new ScopePropagator(emptySolution, statistics)
170 case ScopePropagatorStrategy.BasicTypeHierarchy:
171 new TypeHierarchyScopePropagator(emptySolution, statistics)
172 ScopePropagatorStrategy.Polyhedral: {
173 val types = queries.refineObjectQueries.keySet.map[newType].toSet
174 val allPatternsByName = queries.allQueries.toMap[fullyQualifiedName]
175 val solver = switch (scopePropagatorStrategy.solver) {
176 case Z3Integer:
177 new Z3PolyhedronSolver(false, scopePropagatorStrategy.timeoutSeconds)
178 case Z3Real:
179 new Z3PolyhedronSolver(true, scopePropagatorStrategy.timeoutSeconds)
180 case Cbc:
181 new CbcPolyhedronSolver(false, scopePropagatorStrategy.timeoutSeconds, true)
182 case Clp:
183 new CbcPolyhedronSolver(true, scopePropagatorStrategy.timeoutSeconds, true)
184 default:
185 throw new IllegalArgumentException("Unknown polyhedron solver: " +
186 scopePropagatorStrategy.solver)
187 }
188 val strategy = if (extensionOperators.empty) {
189 new CachingSimplePolyhedronScopePropagatorStrategy(solver, statistics)
190 } else {
191 new ExtendedPolyhedronScopePropagatorStrategy(solver, extensionOperators, statistics)
192 }
193 new PolyhedronScopePropagator(emptySolution, statistics, types, queries.multiplicityConstraintQueries,
194 queries.hasElementInContainmentQuery, allPatternsByName, hints, strategy,
195 scopePropagatorStrategy.requiresUpperBoundIndexing, scopePropagatorStrategy.updateHeuristic)
196 }
197 default:
198 throw new IllegalArgumentException("Unknown scope propagator strategy: " + scopePropagatorStrategy)
199 }
200 }
201}
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 af7b071a..a6fa627d 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
@@ -9,246 +9,349 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
9import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicproblemPackage 9import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicproblemPackage
10import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicresultFactory 10import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicresultFactory
11import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult 11import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult
12import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethodProvider
13import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator 12import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator
13import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy
14import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser 14import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser
15import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 15import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
16import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage 16import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage
17import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.AbstractNeighbourhoodBasedStateCoderFactory
17import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory 18import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory
18import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedStateCoderFactory 19import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedHashStateCoderFactory
19import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BestFirstStrategyForModelGeneration 20import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.PairwiseNeighbourhoodBasedStateCoderFactory
21import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BasicScopeGlobalConstraint
22import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.HillClimbingOnRealisticMetricStrategyForModelGeneration
23import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.InconsistentScopeGlobalConstraint
24import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.LoggerSolutionFoundHandler
20import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ModelGenerationCompositeObjective 25import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ModelGenerationCompositeObjective
26import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.NumericSolver
21import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PartialModelAsLogicInterpretation 27import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PartialModelAsLogicInterpretation
28import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PunishSizeObjective
22import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ScopeObjective 29import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ScopeObjective
30import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.SurelyViolatedObjectiveGlobalConstraint
23import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.UnfinishedMultiplicityObjective 31import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.UnfinishedMultiplicityObjective
24import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.UnfinishedWFObjective
25import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.WF2ObjectiveConverter 32import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.WF2ObjectiveConverter
33import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveKind
26import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace 34import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace
27import java.util.List 35import java.util.List
28import java.util.Map 36import java.util.Map
29import org.eclipse.emf.ecore.EObject 37import org.eclipse.emf.ecore.EObject
38import org.eclipse.emf.ecore.util.EcoreUtil
30import org.eclipse.viatra.dse.api.DesignSpaceExplorer 39import org.eclipse.viatra.dse.api.DesignSpaceExplorer
31import org.eclipse.viatra.dse.api.DesignSpaceExplorer.DseLoggingLevel 40import org.eclipse.viatra.dse.api.DesignSpaceExplorer.DseLoggingLevel
32import org.eclipse.viatra.dse.solutionstore.SolutionStore 41import org.eclipse.viatra.dse.solutionstore.SolutionStore
33import org.eclipse.viatra.dse.statecode.IStateCoderFactory 42import org.eclipse.viatra.dse.statecode.IStateCoderFactory
34import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.SolutionStoreWithDiversityDescriptor
35import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityGranularity
36import org.eclipse.emf.ecore.util.EcoreUtil
37import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.HillClimbingOnRealisticMetricStrategyForModelGeneration
38 43
39class ViatraReasoner extends LogicReasoner{ 44class ViatraReasoner extends LogicReasoner {
40 val PartialInterpretationInitialiser initialiser = new PartialInterpretationInitialiser() 45 val PartialInterpretationInitialiser initialiser = new PartialInterpretationInitialiser()
41 val ModelGenerationMethodProvider modelGenerationMethodProvider = new ModelGenerationMethodProvider 46 val ModelGenerationMethodProvider modelGenerationMethodProvider = new ModelGenerationMethodProvider
42 val extension LogicresultFactory factory = LogicresultFactory.eINSTANCE 47 val extension LogicresultFactory factory = LogicresultFactory.eINSTANCE
43 val WF2ObjectiveConverter wf2ObjectiveConverter = new WF2ObjectiveConverter 48 val WF2ObjectiveConverter wf2ObjectiveConverter = new WF2ObjectiveConverter
44 49
45 50 override solve(LogicProblem problem, LogicSolverConfiguration configuration,
46 override solve(LogicProblem problem, LogicSolverConfiguration configuration, ReasonerWorkspace workspace) throws LogicReasonerException { 51 ReasonerWorkspace workspace) throws LogicReasonerException {
47 val viatraConfig = configuration.asConfig 52 val viatraConfig = configuration.asConfig
48 53
49 if(viatraConfig.debugCongiguration.logging) { 54 if (viatraConfig.documentationLevel == DocumentationLevel.FULL) {
50 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.VERBOSE_FULL) 55 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.VERBOSE_FULL)
51 } else { 56 } else {
52 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.WARN) 57 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.WARN)
53 } 58 }
54 59
55 val DesignSpaceExplorer dse = new DesignSpaceExplorer(); 60 val DesignSpaceExplorer dse = new DesignSpaceExplorer();
56 61
57 dse.addMetaModelPackage(LogiclanguagePackage.eINSTANCE) 62 dse.addMetaModelPackage(LogiclanguagePackage.eINSTANCE)
58 dse.addMetaModelPackage(LogicproblemPackage.eINSTANCE) 63 dse.addMetaModelPackage(LogicproblemPackage.eINSTANCE)
59 dse.addMetaModelPackage(PartialinterpretationPackage.eINSTANCE) 64 dse.addMetaModelPackage(PartialinterpretationPackage.eINSTANCE)
60 65
61 val transformationStartTime = System.nanoTime 66 val transformationStartTime = System.nanoTime
62 67 val emptySolution = initialiser.initialisePartialInterpretation(problem, viatraConfig.typeScopes).output
63 68 if ((viatraConfig.documentationLevel == DocumentationLevel::FULL ||
64 val emptySolution = initialiser.initialisePartialInterpretation(problem,viatraConfig.typeScopes).output 69 viatraConfig.documentationLevel == DocumentationLevel::NORMAL) && workspace !== null) {
65 if((viatraConfig.documentationLevel == DocumentationLevel::FULL || viatraConfig.documentationLevel == DocumentationLevel::NORMAL) && workspace !== null) { 70 workspace.writeModel(emptySolution, "init.partialmodel")
66 workspace.writeModel(emptySolution,"init.partialmodel") 71 }
67 } 72
68 emptySolution.problemConainer = problem 73 emptySolution.problemConainer = problem
69 val emptySolutionCopy = EcoreUtil.copy(emptySolution) 74 val emptySolutionCopy = EcoreUtil.copy(emptySolution)
70 75
71 val ScopePropagator scopePropagator = new ScopePropagator(emptySolution) 76 val ScopePropagator scopePropagator = new ScopePropagator(emptySolution)
72 scopePropagator.propagateAllScopeConstraints 77 scopePropagator.propagateAllScopeConstraints
73 78
79 var BasicScopeGlobalConstraint basicScopeGlobalConstraint = null
80 if (viatraConfig.scopePropagatorStrategy == ScopePropagatorStrategy.None) {
81 basicScopeGlobalConstraint = new BasicScopeGlobalConstraint(emptySolution)
82 emptySolution.scopes.clear
83 }
84
74 val method = modelGenerationMethodProvider.createModelGenerationMethod( 85 val method = modelGenerationMethodProvider.createModelGenerationMethod(
75 problem, 86 problem,
76 emptySolution, 87 emptySolution,
77 workspace, 88 workspace,
78 viatraConfig.nameNewElements, 89 viatraConfig
79 viatraConfig.typeInferenceMethod,
80 scopePropagator,
81 viatraConfig.documentationLevel,
82 viatraConfig.calculateObjectCreationCosts
83 ) 90 )
84 //println("parsed") 91
85 92 val compositeObjective = new ModelGenerationCompositeObjective(
86 dse.addObjective(new ModelGenerationCompositeObjective( 93 basicScopeGlobalConstraint ?: new ScopeObjective,
87 new ScopeObjective,
88 method.unfinishedMultiplicities.map[new UnfinishedMultiplicityObjective(it)], 94 method.unfinishedMultiplicities.map[new UnfinishedMultiplicityObjective(it)],
89 new UnfinishedWFObjective(method.unfinishedWF), 95 wf2ObjectiveConverter.createCompletenessObjective(method.unfinishedWF),
90 viatraConfig 96 viatraConfig
91 )) 97 )
98 dse.addObjective(compositeObjective)
99 if (viatraConfig.punishSize != PunishSizeStrategy.NONE) {
100 val punishSizeStrategy = switch (viatraConfig.punishSize) {
101 case SMALLER_IS_BETTER: ObjectiveKind.LOWER_IS_BETTER
102 case LARGER_IS_BETTER: ObjectiveKind.HIGHER_IS_BETTER
103 default: throw new IllegalArgumentException("Unknown PunishSizeStrategy: " + viatraConfig.punishSize)
104 }
105 val punishObjective = new PunishSizeObjective(punishSizeStrategy, compositeObjective.level + 1)
106 dse.addObjective(punishObjective)
107 }
108
109 for (costObjective : method.costObjectives) {
110 dse.addObjective(costObjective)
111 }
112 val numberOfRequiredSolutions = configuration.solutionScope.numberOfRequiredSolutions
113 val solutionStore = if (method.optimizationProblem) {
114 new SolutionStore()
115 } else {
116 new SolutionStore(numberOfRequiredSolutions)
117 }
118 solutionStore.registerSolutionFoundHandler(new LoggerSolutionFoundHandler(viatraConfig))
119 val numericSolver = new NumericSolver(method, viatraConfig.runIntermediateNumericalConsistencyChecks, false)
120 val solutionSaver = method.solutionSaver
121 solutionSaver.numericSolver = numericSolver
122 val solutionCopier = solutionSaver.solutionCopier
123 val diversityChecker = solutionSaver.diversityChecker
124 solutionStore.withSolutionSaver(solutionSaver)
125 dse.solutionStore = solutionStore
92 126
93 dse.addGlobalConstraint(wf2ObjectiveConverter.createInvalidationObjective(method.invalidWF)) 127 dse.addGlobalConstraint(wf2ObjectiveConverter.createInvalidationGlobalConstraint(method.invalidWF))
94 for(additionalConstraint : viatraConfig.searchSpaceConstraints.additionalGlobalConstraints) { 128 dse.addGlobalConstraint(new SurelyViolatedObjectiveGlobalConstraint(solutionSaver))
129 dse.addGlobalConstraint(new InconsistentScopeGlobalConstraint)
130 if (basicScopeGlobalConstraint !== null) {
131 dse.addGlobalConstraint(basicScopeGlobalConstraint)
132 }
133 for (additionalConstraint : viatraConfig.searchSpaceConstraints.additionalGlobalConstraints) {
95 dse.addGlobalConstraint(additionalConstraint.apply(method)) 134 dse.addGlobalConstraint(additionalConstraint.apply(method))
96 } 135 }
97 136
98 dse.setInitialModel(emptySolution,false) 137 dse.setInitialModel(emptySolution, false)
99 138
100 val IStateCoderFactory statecoder = if(viatraConfig.stateCoderStrategy == StateCoderStrategy.Neighbourhood) { 139 val IStateCoderFactory statecoder = switch (viatraConfig.stateCoderStrategy) {
101 new NeighbourhoodBasedStateCoderFactory 140 case Neighbourhood:
102 } else { 141 new NeighbourhoodBasedHashStateCoderFactory
103 new IdentifierBasedStateCoderFactory 142 case PairwiseNeighbourhood:
143 new PairwiseNeighbourhoodBasedStateCoderFactory
144 default:
145 new IdentifierBasedStateCoderFactory
104 } 146 }
105 dse.stateCoderFactory = statecoder 147 dse.stateCoderFactory = statecoder
106 148
107 dse.maxNumberOfThreads = 1 149 dse.maxNumberOfThreads = 1
108 150
109 val solutionStore = new SolutionStore(configuration.solutionScope.numberOfRequiredSolution) 151 for (rule : method.relationRefinementRules) {
110 dse.solutionStore = solutionStore
111
112 for(rule : method.relationRefinementRules) {
113 dse.addTransformationRule(rule) 152 dse.addTransformationRule(rule)
114 } 153 }
115 for(rule : method.objectRefinementRules) { 154 for (rule : method.objectRefinementRules) {
116 dse.addTransformationRule(rule) 155 dse.addTransformationRule(rule)
117 } 156 }
118 157
119 val strategy = new HillClimbingOnRealisticMetricStrategyForModelGeneration(workspace,viatraConfig,method) 158 val strategy = new HillClimbingOnRealisticMetricStrategyForModelGeneration(workspace,viatraConfig,method)
120 viatraConfig.progressMonitor.workedForwardTransformation 159 viatraConfig.progressMonitor.workedForwardTransformation
121 val transformationFinished = System.nanoTime 160 val transformationFinished = System.nanoTime
122 val transformationTime = transformationFinished - transformationStartTime 161 val transformationTime = transformationFinished - transformationStartTime
123
124 val solverStartTime = System.nanoTime 162 val solverStartTime = System.nanoTime
125 163
126 var boolean stoppedByTimeout 164 var boolean stoppedByTimeout
127 var boolean stoppedByException 165 try {
128 try{ 166 stoppedByTimeout = dse.startExplorationWithTimeout(strategy, configuration.runtimeLimit * 1000);
129 stoppedByTimeout = dse.startExplorationWithTimeout(strategy,configuration.runtimeLimit*1000);
130 stoppedByException = false
131 } catch (NullPointerException npe) { 167 } catch (NullPointerException npe) {
132 stoppedByTimeout = false 168 stoppedByTimeout = false
133 stoppedByException = true
134 } 169 }
135 val solverTime = System.nanoTime - solverStartTime 170 val solverTime = System.nanoTime - solverStartTime
136 viatraConfig.progressMonitor.workedSearchFinished 171 viatraConfig.progressMonitor.workedSearchFinished
137 172
138 //additionalMatches = strategy.solutionStoreWithCopy.additionalMatches 173 // additionalMatches = strategy.solutionStoreWithCopy.additionalMatches
139 val statistics = createStatistics => [ 174 val statistics = createStatistics => [
140 //it.solverTime = viatraConfig.runtimeLimit 175 // it.solverTime = viatraConfig.runtimeLimit
141 it.solverTime = (solverTime/1000000) as int 176 it.solverTime = (solverTime / 1000000) as int
142 it.transformationTime = (transformationTime/1000000) as int 177 it.transformationTime = (transformationTime / 1000000) as int
143 for(x : 0..<strategy.solutionStoreWithCopy.allRuntimes.size) { 178 for (pair : solutionCopier.getAllCopierRuntimes(true).indexed) {
144 it.entries += createIntStatisticEntry => [ 179 it.entries += createIntStatisticEntry => [
145 it.name = '''Solution«x+1»FoundAt''' 180 it.name = '''Solution«pair.key»FoundAt'''
146 it.value = (strategy.solutionStoreWithCopy.allRuntimes.get(x)/1000000) as int 181 it.value = (pair.value / 1000000) as int
147 ] 182 ]
148 } 183 }
149 for(x: 0..<strategy.times.size) { 184 for (x : 0 ..< strategy.times.size) {
150 it.entries += createStringStatisticEntry => [ 185 it.entries += createStringStatisticEntry => [
151 it.name = '''Solution«x+1»DetailedStatistics''' 186 it.name = '''Solution«x+1»DetailedStatistics'''
152 it.value = strategy.times.get(x) 187 it.value = strategy.times.get(x)
153 ] 188 ]
154 } 189 }
155 it.entries += createIntStatisticEntry => [ 190 it.entries += createIntStatisticEntry => [
156 it.name = "ExplorationInitializationTime" it.value = ((strategy.explorationStarted-transformationFinished)/1000000) as int 191 it.name = "ExplorationInitializationTime"
192 it.value = ((strategy.explorationStarted - transformationFinished) / 1000000) as int
193 ]
194 it.entries += createIntStatisticEntry => [
195 it.name = "TransformationExecutionTime"
196 it.value = (method.statistics.transformationExecutionTime / 1000000) as int
197 ]
198 it.entries += createIntStatisticEntry => [
199 it.name = "ScopePropagationTime"
200 it.value = (method.statistics.scopePropagationTime / 1000000) as int
201 ]
202 it.entries += createIntStatisticEntry => [
203 it.name = "MustRelationPropagationTime"
204 it.value = (method.statistics.mustRelationPropagationTime / 1000000) as int
205 ]
206 it.entries += createIntStatisticEntry => [
207 it.name = "TypeAnalysisTime"
208 it.value = (method.statistics.preliminaryTypeAnalisisTime / 1000000) as int
209 ]
210 it.entries += createIntStatisticEntry => [
211 it.name = "StateCoderTime"
212 it.value = (statecoder.runtime / 1000000) as int
157 ] 213 ]
158 it.entries += createIntStatisticEntry => [ 214 it.entries += createIntStatisticEntry => [
159 it.name = "TransformationExecutionTime" it.value = (method.statistics.transformationExecutionTime/1000000) as int 215 it.name = "StateCoderFailCount"
216 it.value = strategy.numberOfStatecoderFail
160 ] 217 ]
161 it.entries += createIntStatisticEntry => [ 218 it.entries += createIntStatisticEntry => [
162 it.name = "TypeAnalysisTime" it.value = (method.statistics.PreliminaryTypeAnalisisTime/1000000) as int 219 it.name = "SolutionCopyTime"
220 it.value = (solutionCopier.getTotalCopierRuntime / 1000000) as int
163 ] 221 ]
164 it.entries += createIntStatisticEntry => [ 222 it.entries += createIntStatisticEntry => [
165 it.name = "StateCoderTime" it.value = (statecoder.runtime/1000000) as int 223 it.name = "States"
224 it.value = dse.numberOfStates as int
166 ] 225 ]
167 it.entries += createIntStatisticEntry => [ 226 it.entries += createIntStatisticEntry => [
168 it.name = "StateCoderFailCount" it.value = strategy.numberOfStatecoderFail 227 it.name = "ForwardTime"
228 it.value = (strategy.forwardTime / 1000000) as int
169 ] 229 ]
170 it.entries += createIntStatisticEntry => [ 230 it.entries += createIntStatisticEntry => [
171 it.name = "SolutionCopyTime" it.value = (strategy.solutionStoreWithCopy.sumRuntime/1000000) as int 231 it.name = "BacktrackingTime"
232 it.value = (strategy.backtrackingTime / 1000000) as int
172 ] 233 ]
173 it.entries += createIntStatisticEntry => [ 234 it.entries += createIntStatisticEntry => [
174 it.name = "ActivationSelectionTime" it.value = (strategy.activationSelector.runtime/1000000) as int 235 it.name = "GlobalConstraintEvaluationTime"
236 it.value = (strategy.globalConstraintEvaluationTime / 1000000) as int
175 ] 237 ]
176 it.entries += createIntStatisticEntry => [ 238 it.entries += createIntStatisticEntry => [
177 it.name = "NumericalSolverSumTime" it.value = (strategy.numericSolver.runtime/1000000) as int 239 it.name = "FitnessCalculationTime"
240 it.value = (strategy.fitnessCalculationTime / 1000000) as int
178 ] 241 ]
179 it.entries += createIntStatisticEntry => [ 242 it.entries += createIntStatisticEntry => [
180 it.name = "NumericalSolverProblemFormingTime" it.value = (strategy.numericSolver.solverFormingProblem/1000000) as int 243 it.name = "SolutionCopyTime"
244 it.value = (solutionSaver.totalCopierRuntime / 1000000) as int
181 ] 245 ]
182 it.entries += createIntStatisticEntry => [ 246 it.entries += createIntStatisticEntry => [
183 it.name = "NumericalSolverSolvingTime" it.value = (strategy.numericSolver.solverSolvingProblem/1000000) as int 247 it.name = "ActivationSelectionTime"
248 it.value = (strategy.activationSelector.runtime / 1000000) as int
184 ] 249 ]
185 it.entries += createIntStatisticEntry => [ 250 it.entries += createIntStatisticEntry => [
186 it.name = "NumericalSolverInterpretingSolution" it.value = (strategy.numericSolver.solverSolution/1000000) as int 251 it.name = "Decisions"
252 it.value = method.statistics.decisionsTried
187 ] 253 ]
188 it.entries += createIntStatisticEntry => [ 254 it.entries += createIntStatisticEntry => [
189 it.name = "NumericalSolverCachingTime" it.value = (strategy.numericSolver.cachingTime/1000000) as int 255 it.name = "Transformations"
256 it.value = method.statistics.transformationInvocations
190 ] 257 ]
191 it.entries += createIntStatisticEntry => [ 258 it.entries += createIntStatisticEntry => [
192 it.name = "NumericalSolverCallNumber" it.value = strategy.numericSolver.numberOfSolverCalls 259 it.name = "ScopePropagations"
260 it.value = method.statistics.scopePropagatorInvocations
193 ] 261 ]
194 it.entries += createIntStatisticEntry => [ 262 it.entries += createIntStatisticEntry => [
195 it.name = "NumericalSolverCachedAnswerNumber" it.value = strategy.numericSolver.numberOfCachedSolverCalls 263 it.name = "ScopePropagationsSolverCalls"
264 it.value = method.statistics.scopePropagatorSolverInvocations
196 ] 265 ]
197 if(strategy.solutionStoreWithDiversityDescriptor.isActive) { 266// it.entries += createIntStatisticEntry => [
267// it.name = "NumericalSolverSumTime"
268// it.value = (strategy.numericSolver.runtime / 1000000) as int
269// ]
270// it.entries += createIntStatisticEntry => [
271// it.name = "NumericalSolverProblemFormingTime"
272// it.value = (strategy.numericSolver.solverFormingProblem / 1000000) as int
273// ]
274// it.entries += createIntStatisticEntry => [
275// it.name = "NumericalSolverSolvingTime"
276// it.value = (strategy.numericSolver.solverSolvingProblem / 1000000) as int
277// ]
278// it.entries += createIntStatisticEntry => [
279// it.name = "NumericalSolverInterpretingSolution"
280// it.value = (strategy.numericSolver.solverSolution / 1000000) as int
281// ]
282// it.entries += createIntStatisticEntry => [
283// it.name = "NumericalSolverCachingTime"
284// it.value = (strategy.numericSolver.cachingTime / 1000000) as int
285// ]
286// it.entries += createIntStatisticEntry => [
287// it.name = "NumericalSolverCallNumber"
288// it.value = strategy.numericSolver.numberOfSolverCalls
289// ]
290// it.entries += createIntStatisticEntry => [
291// it.name = "NumericalSolverCachedAnswerNumber"
292// it.value = strategy.numericSolver.numberOfCachedSolverCalls
293// ]
294 if (diversityChecker.active) {
198 it.entries += createIntStatisticEntry => [ 295 it.entries += createIntStatisticEntry => [
199 it.name = "SolutionDiversityCheckTime" it.value = (strategy.solutionStoreWithDiversityDescriptor.sumRuntime/1000000) as int 296 it.name = "SolutionDiversityCheckTime"
297 it.value = (diversityChecker.totalRuntime / 1000000) as int
200 ] 298 ]
201 it.entries += createRealStatisticEntry => [ 299 it.entries += createRealStatisticEntry => [
202 it.name = "SolutionDiversitySuccessRate" it.value = strategy.solutionStoreWithDiversityDescriptor.successRate 300 it.name = "SolutionDiversitySuccessRate"
301 it.value = diversityChecker.successRate
203 ] 302 ]
204 } 303 }
205 ] 304 ]
206 305
207 viatraConfig.progressMonitor.workedBackwardTransformationFinished 306 viatraConfig.progressMonitor.workedBackwardTransformationFinished
208 307
209 if(stoppedByTimeout) { 308 if (stoppedByTimeout) {
210 return createInsuficientResourcesResult=>[ 309 return createInsuficientResourcesResult => [
211 it.problem = problem 310 it.problem = problem
212 it.resourceName="time" 311 it.resourceName = "time"
213 it.representation += strategy.solutionStoreWithCopy.solutions 312 it.representation += solutionCopier.getPartialInterpretations(true)
214 it.statistics = statistics 313 it.statistics = statistics
215 ] 314 ]
216 } else { 315 } else {
217 if(solutionStore.solutions.empty) { 316 if (solutionStore.solutions.empty) {
218 return createInconsistencyResult => [ 317 return createInconsistencyResult => [
219 it.problem = problem 318 it.problem = problem
220 it.representation += strategy.solutionStoreWithCopy.solutions 319 it.representation += solutionCopier.getPartialInterpretations(true)
221 it.statistics = statistics 320 it.statistics = statistics
222 ] 321 ]
223 } else { 322 } else {
224 return createModelResult => [ 323 return createModelResult => [
225 it.problem = problem 324 it.problem = problem
226 it.trace = strategy.solutionStoreWithCopy.copyTraces 325 it.trace = solutionCopier.getTraces(true)
227 it.representation += strategy.solutionStoreWithCopy.solutions 326 it.representation += solutionCopier.getPartialInterpretations(true)
228 it.statistics = statistics 327 it.statistics = statistics
229 ] 328 ]
230 } 329 }
231 } 330 }
232 } 331 }
233 332
234 private def dispatch long runtime(NeighbourhoodBasedStateCoderFactory sc) { 333 private def dispatch long runtime(AbstractNeighbourhoodBasedStateCoderFactory sc) {
235 sc.sumStatecoderRuntime 334 sc.sumStatecoderRuntime
236 } 335 }
237 336
238 private def dispatch long runtime(IdentifierBasedStateCoderFactory sc) { 337 private def dispatch long runtime(IdentifierBasedStateCoderFactory sc) {
239 sc.sumStatecoderRuntime 338 sc.sumStatecoderRuntime
240 } 339 }
241 340
242 override getInterpretations(ModelResult modelResult) { 341 override getInterpretations(ModelResult modelResult) {
243 val indexes = 0..<modelResult.representation.size 342 val indexes = 0 ..< modelResult.representation.size
244 val traces = modelResult.trace as List<Map<EObject, EObject>>; 343 val traces = modelResult.trace as List<Map<EObject, EObject>>;
245 val res = indexes.map[i | new PartialModelAsLogicInterpretation(modelResult.representation.get(i) as PartialInterpretation,traces.get(i))].toList 344 val res = indexes.map [ i |
345 new PartialModelAsLogicInterpretation(modelResult.representation.get(i) as PartialInterpretation,
346 traces.get(i))
347 ].toList
246 return res 348 return res
247 } 349 }
248 350
249 private def ViatraReasonerConfiguration asConfig(LogicSolverConfiguration configuration) { 351 private def ViatraReasonerConfiguration asConfig(LogicSolverConfiguration configuration) {
250 if(configuration instanceof ViatraReasonerConfiguration) { 352 if (configuration instanceof ViatraReasonerConfiguration) {
251 return configuration 353 return configuration
252 } else throw new IllegalArgumentException('''Wrong configuration. Expected: «ViatraReasonerConfiguration.name», but got: «configuration.class.name»"''') 354 } else
355 throw new IllegalArgumentException('''Wrong configuration. Expected: «ViatraReasonerConfiguration.name», but got: «configuration.class.name»"''')
253 } 356 }
254} 357}
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 96bf014d..e73a52b6 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
@@ -4,21 +4,37 @@ import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner
4import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicSolverConfiguration 4import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicSolverConfiguration
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration 5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration 6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration
7import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeInferenceMethod 7import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeInferenceMethod
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeConstraintHint
9import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedralScopePropagatorConstraints
10import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedralScopePropagatorSolver
11import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy
12import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.UnitPropagationPatternGenerator
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser 13import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser
14import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostObjectiveHint
15import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveKind
16import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold
10import java.util.LinkedList 17import java.util.LinkedList
11import java.util.List 18import java.util.List
12import java.util.Set 19import java.util.Set
13import org.eclipse.xtext.xbase.lib.Functions.Function1 20import org.eclipse.xtext.xbase.lib.Functions.Function1
14 21
15public enum StateCoderStrategy { 22enum StateCoderStrategy {
16 Neighbourhood, NeighbourhoodWithEquivalence, IDBased, DefinedByDiversity 23 Neighbourhood,
24 PairwiseNeighbourhood,
25 NeighbourhoodWithEquivalence,
26 IDBased,
27 DefinedByDiversity
17} 28}
18 29
19class ViatraReasonerConfiguration extends LogicSolverConfiguration{ 30enum PunishSizeStrategy {
20 //public var Iterable<PQuery> existingQueries 31 NONE,
21 32 SMALLER_IS_BETTER,
33 LARGER_IS_BETTER
34}
35
36class ViatraReasonerConfiguration extends LogicSolverConfiguration {
37 // public var Iterable<PQuery> existingQueries
22 public var nameNewElements = false 38 public var nameNewElements = false
23 public var StateCoderStrategy stateCoderStrategy = StateCoderStrategy.Neighbourhood 39 public var StateCoderStrategy stateCoderStrategy = StateCoderStrategy.Neighbourhood
24 public var TypeInferenceMethod typeInferenceMethod = TypeInferenceMethod.PreliminaryAnalysis 40 public var TypeInferenceMethod typeInferenceMethod = TypeInferenceMethod.PreliminaryAnalysis
@@ -26,7 +42,7 @@ class ViatraReasonerConfiguration extends LogicSolverConfiguration{
26 * Once per 1/randomBacktrackChance the search selects a random state. 42 * Once per 1/randomBacktrackChance the search selects a random state.
27 */ 43 */
28 public var int randomBacktrackChance = 20; 44 public var int randomBacktrackChance = 20;
29 45
30 /** 46 /**
31 * Describes the required diversity between the solutions. 47 * Describes the required diversity between the solutions.
32 * Null means that the solutions have to have different state codes only. 48 * Null means that the solutions have to have different state codes only.
@@ -40,7 +56,7 @@ class ViatraReasonerConfiguration extends LogicSolverConfiguration{
40 /** 56 /**
41 * Configuration for debugging support. 57 * Configuration for debugging support.
42 */ 58 */
43 public var DebugConfiguration debugCongiguration = new DebugConfiguration 59 public var DebugConfiguration debugConfiguration = new DebugConfiguration
44 /** 60 /**
45 * Configuration for cutting search space. 61 * Configuration for cutting search space.
46 */ 62 */
@@ -48,12 +64,11 @@ class ViatraReasonerConfiguration extends LogicSolverConfiguration{
48 64
49 public var runIntermediateNumericalConsistencyChecks = true 65 public var runIntermediateNumericalConsistencyChecks = true
50 66
51 public var punishSize = true 67 public var punishSize = PunishSizeStrategy.NONE
52 public var scopeWeight = 1 68 public var scopeWeight = 1
53 public var conaintmentWeight = 2 69 public var conaintmentWeight = 2
54 public var nonContainmentWeight = 1 70 public var nonContainmentWeight = 1
55 public var unfinishedWFWeight = 1 71 public var unfinishedWFWeight = 1
56
57 public var calculateObjectCreationCosts = false 72 public var calculateObjectCreationCosts = false
58 73
59 public var RealisticGuidance realisticGuidance = RealisticGuidance.Composite; 74 public var RealisticGuidance realisticGuidance = RealisticGuidance.Composite;
@@ -63,9 +78,18 @@ class ViatraReasonerConfiguration extends LogicSolverConfiguration{
63 public var allowMustViolations = false; 78 public var allowMustViolations = false;
64 79
65 public var String domain = ''; 80 public var String domain = '';
81 public var ScopePropagatorStrategy scopePropagatorStrategy = new ScopePropagatorStrategy.Polyhedral(
82 PolyhedralScopePropagatorConstraints.Relational, PolyhedralScopePropagatorSolver.Clp)
83// public var ScopePropagatorStrategy scopePropagatorStrategy = ScopePropagatorStrategy.BasicTypeHierarchy
84
85 public var List<LinearTypeConstraintHint> hints = newArrayList
86
87 public var List<CostObjectiveConfiguration> costObjectives = newArrayList
88
89 public var List<UnitPropagationPatternGenerator> unitPropagationPatternGenerators = newArrayList
66} 90}
67 91
68public class DiversityDescriptor { 92class DiversityDescriptor {
69 public var ensureDiversity = false 93 public var ensureDiversity = false
70 public static val FixPointRange = -1 94 public static val FixPointRange = -1
71 public var int range = FixPointRange 95 public var int range = FixPointRange
@@ -75,19 +99,18 @@ public class DiversityDescriptor {
75 public var Set<RelationDeclaration> relevantRelations = null 99 public var Set<RelationDeclaration> relevantRelations = null
76} 100}
77 101
78public class DebugConfiguration { 102class DebugConfiguration {
79 public var logging = false 103 public var PartialInterpretationVisualiser partialInterpretatioVisualiser = null
80 public var PartialInterpretationVisualiser partialInterpretatioVisualiser = null;
81 public var partalInterpretationVisualisationFrequency = 1 104 public var partalInterpretationVisualisationFrequency = 1
82} 105}
83 106
84public class InternalConsistencyCheckerConfiguration { 107class InternalConsistencyCheckerConfiguration {
85 public var LogicReasoner internalIncosnsitencyDetector = null 108 public var LogicReasoner internalIncosnsitencyDetector = null
86 public var LogicSolverConfiguration internalInconsistencDetectorConfiguration = null 109 public var LogicSolverConfiguration internalInconsistencDetectorConfiguration = null
87 public var incternalConsistencyCheckingFrequency = 1 110 public var incternalConsistencyCheckingFrequency = 1
88} 111}
89 112
90public class SearchSpaceConstraint { 113class SearchSpaceConstraint {
91 public static val UNLIMITED_MAXDEPTH = Integer.MAX_VALUE 114 public static val UNLIMITED_MAXDEPTH = Integer.MAX_VALUE
92 public var int maxDepth = UNLIMITED_MAXDEPTH 115 public var int maxDepth = UNLIMITED_MAXDEPTH
93 public var List<Function1<ModelGenerationMethod, ModelGenerationMethodBasedGlobalConstraint>> additionalGlobalConstraints = new LinkedList 116 public var List<Function1<ModelGenerationMethod, ModelGenerationMethodBasedGlobalConstraint>> additionalGlobalConstraints = new LinkedList
@@ -101,4 +124,17 @@ public enum RealisticGuidance{
101 Composite, 124 Composite,
102 Composite_Without_Violations, 125 Composite_Without_Violations,
103 Violations 126 Violations
104} \ No newline at end of file 127}
128class CostObjectiveConfiguration {
129 public var List<CostObjectiveElementConfiguration> elements = newArrayList
130 public var ObjectiveKind kind
131 public var ObjectiveThreshold threshold
132 public var boolean findExtremum
133 public var CostObjectiveHint hint
134}
135
136class CostObjectiveElementConfiguration {
137 public var String patternQualifiedName
138 public var int weight
139}
140
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BasicScopeGlobalConstraint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BasicScopeGlobalConstraint.xtend
new file mode 100644
index 00000000..67f447ed
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BasicScopeGlobalConstraint.xtend
@@ -0,0 +1,103 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import com.google.common.collect.ImmutableList
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation
6import java.util.Comparator
7import java.util.List
8import org.eclipse.viatra.dse.base.ThreadContext
9import org.eclipse.viatra.dse.objectives.Comparators
10import org.eclipse.viatra.dse.objectives.IGlobalConstraint
11import org.eclipse.viatra.dse.objectives.IObjective
12import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
13
14class BasicScopeGlobalConstraint implements IGlobalConstraint, IObjective {
15 val PartialInterpretation p
16 val List<ScopeAssertion> assertions
17
18 new(PartialInterpretation p) {
19 this.p = p
20 assertions = ImmutableList.copyOf(p.scopes.map [
21 val currentSize = targetTypeInterpretation.elements.size
22 val minElements = minNewElements + currentSize
23 val maxElements = if (maxNewElements < 0) {
24 -1
25 } else {
26 maxNewElements + currentSize
27 }
28 new ScopeAssertion(minElements, maxElements, targetTypeInterpretation)
29 ])
30 }
31
32 override init(ThreadContext context) {
33 if (context.model != p) {
34 throw new IllegalArgumentException(
35 "Partial model must be passed to the constructor of BasicScopeGlobalConstraint")
36 }
37 }
38
39 override checkGlobalConstraint(ThreadContext context) {
40 assertions.forall[upperBoundSatisfied]
41 }
42
43 override getFitness(ThreadContext context) {
44 var double fitness = p.minNewElements
45 for (assertion : assertions) {
46 if (!assertion.lowerBoundSatisfied) {
47 fitness += 1
48 }
49 }
50 fitness
51 }
52
53 override satisifiesHardObjective(Double fitness) {
54 fitness <= 0.01
55 }
56
57 override BasicScopeGlobalConstraint createNew() {
58 this
59 }
60
61 override getName() {
62 class.name
63 }
64
65 override getComparator() {
66 Comparators.LOWER_IS_BETTER
67 }
68
69 override getLevel() {
70 2
71 }
72
73 override isHardObjective() {
74 true
75 }
76
77 override setComparator(Comparator<Double> comparator) {
78 throw new UnsupportedOperationException
79 }
80
81 override setLevel(int level) {
82 throw new UnsupportedOperationException
83 }
84
85 @FinalFieldsConstructor
86 private static class ScopeAssertion {
87 val int lowerBound
88 val int upperBound
89 val PartialTypeInterpratation typeDefinitions
90
91 private def getCount() {
92 typeDefinitions.elements.size
93 }
94
95 private def isLowerBoundSatisfied() {
96 count >= lowerBound
97 }
98
99 private def isUpperBoundSatisfied() {
100 upperBound < 0 || count <= upperBound
101 }
102 }
103}
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 e0f838a6..4b7cead1 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
@@ -9,33 +9,25 @@
9 *******************************************************************************/ 9 *******************************************************************************/
10package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse; 10package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse;
11 11
12import java.io.BufferedReader;
13import java.io.IOException;
14import java.io.InputStreamReader;
15import java.util.ArrayList;
16import java.util.Arrays; 12import java.util.Arrays;
17import java.util.Collection;
18import java.util.Collections; 13import java.util.Collections;
19import java.util.Comparator; 14import java.util.Comparator;
20import java.util.Iterator; 15import java.util.Iterator;
21import java.util.LinkedList; 16import java.util.LinkedList;
22import java.util.List; 17import java.util.List;
23import java.util.Map;
24import java.util.PriorityQueue; 18import java.util.PriorityQueue;
25import java.util.Random; 19import java.util.Random;
26 20
27import org.apache.log4j.Logger; 21import org.apache.log4j.Logger;
28import org.eclipse.emf.ecore.EObject; 22import org.eclipse.emf.ecore.EObject;
29import org.eclipse.emf.ecore.util.EcoreUtil; 23import org.eclipse.emf.ecore.util.EcoreUtil;
24import org.eclipse.viatra.dse.api.SolutionTrajectory;
30import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; 25import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
31import org.eclipse.viatra.dse.base.ThreadContext; 26import org.eclipse.viatra.dse.base.ThreadContext;
32import org.eclipse.viatra.dse.objectives.Fitness; 27import org.eclipse.viatra.dse.objectives.Fitness;
33import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper; 28import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
29import org.eclipse.viatra.dse.solutionstore.ISolutionFoundHandler;
34import org.eclipse.viatra.dse.solutionstore.SolutionStore; 30import org.eclipse.viatra.dse.solutionstore.SolutionStore;
35import org.eclipse.viatra.query.runtime.api.IPatternMatch;
36import org.eclipse.viatra.query.runtime.api.IQuerySpecification;
37import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
38import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher;
39 31
40import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel; 32import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel;
41import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner; 33import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner;
@@ -43,13 +35,11 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem;
43import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult; 35import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult;
44import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult; 36import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult;
45import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult; 37import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult;
46import hu.bme.mit.inf.dslreasoner.viatra2logic.NumericProblemSolver;
47import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod;
48import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic; 38import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic;
49import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation; 39import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation;
50import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedPartialInterpretationStateCoder;
51import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation; 40import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation;
52import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser; 41import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser;
42import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ModelGenerationMethod;
53import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration; 43import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration;
54import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace; 44import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace;
55 45
@@ -82,58 +72,72 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
82 // Running 72 // Running
83 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore; 73 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore;
84 private SolutionStore solutionStore; 74 private SolutionStore solutionStore;
85 private SolutionStoreWithCopy solutionStoreWithCopy;
86 private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor;
87 private volatile boolean isInterrupted = false; 75 private volatile boolean isInterrupted = false;
88 private ModelResult modelResultByInternalSolver = null; 76 private ModelResult modelResultByInternalSolver = null;
89 private Random random = new Random(); 77 private Random random = new Random();
90 //private Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers; 78// private Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers;
91 public ActivationSelector activationSelector = new EvenActivationSelector(random); 79 public ActivationSelector activationSelector = new EvenActivationSelector(random);
92 public NumericSolver numericSolver = null; 80 public ViatraReasonerSolutionSaver solutionSaver;
81 public NumericSolver numericSolver;
93 // Statistics 82 // Statistics
94 private int numberOfStatecoderFail = 0; 83 private int numberOfStatecoderFail = 0;
95 private int numberOfPrintedModel = 0; 84 private int numberOfPrintedModel = 0;
96 private int numberOfSolverCalls = 0; 85 private int numberOfSolverCalls = 0;
86 public long globalConstraintEvaluationTime = 0;
87 public long fitnessCalculationTime = 0;
97 88
98 public long explorationStarted = 0; 89 public long explorationStarted = 0;
99 90
100 public BestFirstStrategyForModelGeneration( 91 public BestFirstStrategyForModelGeneration(
101 ReasonerWorkspace workspace, 92 ReasonerWorkspace workspace,
102 ViatraReasonerConfiguration configuration, 93 ViatraReasonerConfiguration configuration,
103 ModelGenerationMethod method) 94 ModelGenerationMethod method,
104 { 95 ViatraReasonerSolutionSaver solutionSaver,
96 NumericSolver numericSolver) {
105 this.workspace = workspace; 97 this.workspace = workspace;
106 this.configuration = configuration; 98 this.configuration = configuration;
107 this.method = method; 99 this.method = method;
100 this.solutionSaver = solutionSaver;
101 this.numericSolver = numericSolver;
102// logger.setLevel(Level.DEBUG);
108 } 103 }
109 104
110 public SolutionStoreWithCopy getSolutionStoreWithCopy() {
111 return solutionStoreWithCopy;
112 }
113 public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() {
114 return solutionStoreWithDiversityDescriptor;
115 }
116 public int getNumberOfStatecoderFail() { 105 public int getNumberOfStatecoderFail() {
117 return numberOfStatecoderFail; 106 return numberOfStatecoderFail;
118 } 107 }
119 //LinkedList<ViatraQueryMatcher<? extends IPatternMatch>> matchers; 108 public long getForwardTime() {
109 return context.getDesignSpaceManager().getForwardTime();
110 }
111 public long getBacktrackingTime() {
112 return context.getDesignSpaceManager().getBacktrackingTime();
113 }
114
120 @Override 115 @Override
121 public void initStrategy(ThreadContext context) { 116 public void initStrategy(ThreadContext context) {
122 this.context = context; 117 this.context = context;
123 this.solutionStore = context.getGlobalContext().getSolutionStore(); 118 this.solutionStore = context.getGlobalContext().getSolutionStore();
119 solutionStore.registerSolutionFoundHandler(new ISolutionFoundHandler() {
120
121 @Override
122 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
123 // Ignore.
124 }
125
126 @Override
127 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
128 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolutions);
129 saveTimes();
130 logger.debug("Found a solution.");
131 }
132 });
133 numericSolver.init(context);
124 134
125// ViatraQueryEngine engine = context.getQueryEngine(); 135// ViatraQueryEngine engine = context.getQueryEngine();
126// // TODO: visualisation
127// matchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>(); 136// matchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
128// for(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> p : this.method.getAllPatterns()) { 137// for(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> p : this.method.getAllPatterns()) {
129// //System.out.println(p.getSimpleName()); 138// ViatraQueryMatcher<? extends IPatternMatch> matcher = p.getMatcher(engine);
130// ViatraQueryMatcher<? extends IPatternMatch> matcher = p.getMatcher(engine);
131// matchers.add(matcher);
132// } 139// }
133 140//
134 this.solutionStoreWithCopy = new SolutionStoreWithCopy();
135 this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement);
136
137 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 141 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
138 this.comparator = new Comparator<TrajectoryWithFitness>() { 142 this.comparator = new Comparator<TrajectoryWithFitness>() {
139 @Override 143 @Override
@@ -141,23 +145,14 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
141 return objectiveComparatorHelper.compare(o2.fitness, o1.fitness); 145 return objectiveComparatorHelper.compare(o2.fitness, o1.fitness);
142 } 146 }
143 }; 147 };
144
145 this.numericSolver = new NumericSolver(context, method, this.configuration.runIntermediateNumericalConsistencyChecks, false);
146 148
147 trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11, comparator); 149 trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11, comparator);
148 } 150 }
149 151
150 @Override 152 @Override
151 public void explore() { 153 public void explore() {
152// System.out.println("press enter");
153// try {
154// new BufferedReader(new InputStreamReader(System.in)).readLine();
155// } catch (IOException e) {
156// // TODO Auto-generated catch block
157// e.printStackTrace();
158// }
159 this.explorationStarted=System.nanoTime(); 154 this.explorationStarted=System.nanoTime();
160 if (!context.checkGlobalConstraints()) { 155 if (!checkGlobalConstraints()) {
161 logger.info("Global contraint is not satisifed in the first state. Terminate."); 156 logger.info("Global contraint is not satisifed in the first state. Terminate.");
162 return; 157 return;
163 } else if(!numericSolver.maySatisfiable()) { 158 } else if(!numericSolver.maySatisfiable()) {
@@ -169,14 +164,13 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
169 return; 164 return;
170 } 165 }
171 166
172 final Fitness firstFittness = context.calculateFitness(); 167 final Fitness firstFitness = calculateFitness();
173 checkForSolution(firstFittness); 168 checkForSolution(firstFitness);
174 169
175 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 170 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
176 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]); 171 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]);
177 TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness); 172 TrajectoryWithFitness currentTrajectoryWithFitness = new TrajectoryWithFitness(firstTrajectory, firstFitness);
178 trajectoiresToExplore.add(currentTrajectoryWithFittness); 173 trajectoiresToExplore.add(currentTrajectoryWithFitness);
179
180 //if(configuration) 174 //if(configuration)
181 visualiseCurrentState(); 175 visualiseCurrentState();
182// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) { 176// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) {
@@ -190,22 +184,22 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
190 184
191 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) { 185 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) {
192 186
193 if (currentTrajectoryWithFittness == null) { 187 if (currentTrajectoryWithFitness == null) {
194 if (trajectoiresToExplore.isEmpty()) { 188 if (trajectoiresToExplore.isEmpty()) {
195 logger.debug("State space is fully traversed."); 189 logger.debug("State space is fully traversed.");
196 return; 190 return;
197 } else { 191 } else {
198 currentTrajectoryWithFittness = selectState(); 192 currentTrajectoryWithFitness = selectState();
199 if (logger.isDebugEnabled()) { 193 if (logger.isDebugEnabled()) {
200 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray())); 194 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray()));
201 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness); 195 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFitness);
202 } 196 }
203 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory); 197 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFitness.trajectory);
204 } 198 }
205 } 199 }
206 200
207// visualiseCurrentState(); 201// visualiseCurrentState();
208// boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness); 202// boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithfitness);
209// if(consistencyCheckResult == true) { 203// if(consistencyCheckResult == true) {
210// continue mainLoop; 204// continue mainLoop;
211// } 205// }
@@ -215,29 +209,25 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
215 209
216 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && iterator.hasNext()) { 210 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && iterator.hasNext()) {
217 final Object nextActivation = iterator.next(); 211 final Object nextActivation = iterator.next();
218// if (!iterator.hasNext()) {
219// logger.debug("Last untraversed activation of the state.");
220// trajectoiresToExplore.remove(currentTrajectoryWithFittness);
221// }
222 logger.debug("Executing new activation: " + nextActivation); 212 logger.debug("Executing new activation: " + nextActivation);
223 context.executeAcitvationId(nextActivation); 213 context.executeAcitvationId(nextActivation);
214 method.getStatistics().incrementDecisionCount();
224 215
225 visualiseCurrentState(); 216 visualiseCurrentState();
226// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) { 217// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) {
227// int c = matcher.countMatches(); 218// int c = matcher.countMatches();
228// if(c>=100) { 219// if(c>=1) {
229// System.out.println(c+ " " +matcher.getPatternName()); 220// System.out.println(c+ " " +matcher.getPatternName());
230// } 221// }
231//
232// } 222// }
233 223
234 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness); 224 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFitness);
235 if(consistencyCheckResult == true) { continue mainLoop; } 225 if(consistencyCheckResult == true) { continue mainLoop; }
236 226
237 if (context.isCurrentStateAlreadyTraversed()) { 227 if (context.isCurrentStateAlreadyTraversed()) {
238 logger.info("The new state is already visited."); 228 logger.info("The new state is already visited.");
239 context.backtrack(); 229 context.backtrack();
240 } else if (!context.checkGlobalConstraints()) { 230 } else if (!checkGlobalConstraints()) {
241 logger.debug("Global contraint is not satisifed."); 231 logger.debug("Global contraint is not satisifed.");
242 context.backtrack(); 232 context.backtrack();
243 } else if (!numericSolver.maySatisfiable()) { 233 } else if (!numericSolver.maySatisfiable()) {
@@ -252,76 +242,84 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
252 continue; 242 continue;
253 } 243 }
254 244
255 TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness( 245 TrajectoryWithFitness nextTrajectoryWithfitness = new TrajectoryWithFitness(
256 context.getTrajectory().toArray(), nextFitness); 246 context.getTrajectory().toArray(), nextFitness);
257 trajectoiresToExplore.add(nextTrajectoryWithFittness); 247 trajectoiresToExplore.add(nextTrajectoryWithfitness);
258 248
259 int compare = objectiveComparatorHelper.compare(currentTrajectoryWithFittness.fitness, 249 int compare = objectiveComparatorHelper.compare(currentTrajectoryWithFitness.fitness,
260 nextTrajectoryWithFittness.fitness); 250 nextTrajectoryWithfitness.fitness);
261 if (compare < 0) { 251 if (compare < 0) {
262 logger.debug("Better fitness, moving on: " + nextFitness); 252 logger.debug("Better fitness, moving on: " + nextFitness);
263 currentTrajectoryWithFittness = nextTrajectoryWithFittness; 253 currentTrajectoryWithFitness = nextTrajectoryWithfitness;
264 continue mainLoop; 254 continue mainLoop;
265 } else if (compare == 0) { 255 } else if (compare == 0) {
266 logger.debug("Equally good fitness, moving on: " + nextFitness); 256 logger.debug("Equally good fitness, moving on: " + nextFitness);
267 currentTrajectoryWithFittness = nextTrajectoryWithFittness; 257 currentTrajectoryWithFitness = nextTrajectoryWithfitness;
268 continue mainLoop; 258 continue mainLoop;
269 } else { 259 } else {
270 logger.debug("Worse fitness."); 260 logger.debug("Worse fitness.");
271 currentTrajectoryWithFittness = null; 261 currentTrajectoryWithFitness = null;
272 continue mainLoop; 262 continue mainLoop;
273 } 263 }
274 } 264 }
275 } 265 }
276 266
277 logger.debug("State is fully traversed."); 267 logger.debug("State is fully traversed.");
278 trajectoiresToExplore.remove(currentTrajectoryWithFittness); 268 trajectoiresToExplore.remove(currentTrajectoryWithFitness);
279 currentTrajectoryWithFittness = null; 269 currentTrajectoryWithFitness = null;
280 270
281 } 271 }
282 logger.info("Interrupted."); 272 logger.info("Interrupted.");
283 } 273 }
284 274
275 private boolean checkGlobalConstraints() {
276 long start = System.nanoTime();
277 boolean result = context.checkGlobalConstraints();
278 globalConstraintEvaluationTime += System.nanoTime() - start;
279 return result;
280 }
281
282 private Fitness calculateFitness() {
283 long start = System.nanoTime();
284 Fitness fitness = context.calculateFitness();
285 fitnessCalculationTime += System.nanoTime() - start;
286 return fitness;
287 }
288
285 private List<Object> selectActivation() { 289 private List<Object> selectActivation() {
286 List<Object> activationIds; 290 List<Object> activationIds;
287 try { 291 try {
288 activationIds = this.activationSelector.randomizeActivationIDs(context.getUntraversedActivationIds()); 292 activationIds = this.activationSelector.randomizeActivationIDs(context.getUntraversedActivationIds());
289 } catch (NullPointerException e) { 293 } catch (NullPointerException e) {
294// logger.warn("Unexpected state code: " + context.getDesignSpaceManager().getCurrentState());
290 numberOfStatecoderFail++; 295 numberOfStatecoderFail++;
291 activationIds = Collections.emptyList(); 296 activationIds = Collections.emptyList();
292 } 297 }
293 return activationIds; 298 return activationIds;
294 } 299 }
295 300
296 private void checkForSolution(final Fitness fittness) { 301 private void checkForSolution(final Fitness fitness) {
297 if (fittness.isSatisifiesHardObjectives()) { 302 solutionStore.newSolution(context);
298 if (solutionStoreWithDiversityDescriptor.isDifferent(context)) {
299 if(numericSolver.currentSatisfiable()) {
300 Map<EObject, EObject> trace = solutionStoreWithCopy.newSolution(context);
301 numericSolver.fillSolutionCopy(trace);
302 solutionStoreWithDiversityDescriptor.newSolution(context);
303 solutionStore.newSolution(context);
304 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolution);
305 saveTimes();
306 logger.debug("Found a solution.");
307 }
308 }
309 }
310 } 303 }
304
311 public List<String> times = new LinkedList<String>(); 305 public List<String> times = new LinkedList<String>();
312 private void saveTimes() { 306 private void saveTimes() {
313 long statecoderTime = ((NeighbourhoodBasedPartialInterpretationStateCoder)this.context.getStateCoder()).getStatecoderRuntime()/1000000; 307 long forwardTime = context.getDesignSpaceManager().getForwardTime()/1000000;
314 long solutionCopy = solutionStoreWithCopy.getSumRuntime()/1000000; 308 long backtrackingTime = context.getDesignSpaceManager().getBacktrackingTime()/1000000;
315 long activationSelection = this.activationSelector.getRuntime()/1000000; 309 long activationSelection = this.activationSelector.getRuntime()/1000000;
310 long solutionCopierTime = this.solutionSaver.getTotalCopierRuntime()/1000000;
316 long numericalSolverSumTime = this.numericSolver.getRuntime()/1000000; 311 long numericalSolverSumTime = this.numericSolver.getRuntime()/1000000;
317 long numericalSolverProblemForming = this.numericSolver.getSolverSolvingProblem()/1000000; 312 long numericalSolverProblemForming = this.numericSolver.getSolverSolvingProblem()/1000000;
318 long numericalSolverSolving = this.numericSolver.getSolverSolvingProblem()/1000000; 313 long numericalSolverSolving = this.numericSolver.getSolverSolvingProblem()/1000000;
319 long numericalSolverInterpreting = this.numericSolver.getSolverSolution()/1000000; 314 long numericalSolverInterpreting = this.numericSolver.getSolverSolution()/1000000;
320 this.times.add( 315 this.times.add(
321 "(TransformationExecutionTime"+method.getStatistics().transformationExecutionTime/1000000+ 316 "(TransformationExecutionTime"+method.getStatistics().transformationExecutionTime/1000000+
322 "|StateCoderTime:"+statecoderTime+ 317 "|ForwardTime:"+forwardTime+
323 "|SolutionCopyTime:"+solutionCopy+ 318 "|Backtrackingtime:"+backtrackingTime+
319 "|GlobalConstraintEvaluationTime:"+(globalConstraintEvaluationTime/1000000)+
320 "|FitnessCalculationTime:"+(fitnessCalculationTime/1000000)+
324 "|ActivationSelectionTime:"+activationSelection+ 321 "|ActivationSelectionTime:"+activationSelection+
322 "|SolutionCopyTime:"+solutionCopierTime+
325 "|NumericalSolverSumTime:"+numericalSolverSumTime+ 323 "|NumericalSolverSumTime:"+numericalSolverSumTime+
326 "|NumericalSolverProblemFormingTime:"+numericalSolverProblemForming+ 324 "|NumericalSolverProblemFormingTime:"+numericalSolverProblemForming+
327 "|NumericalSolverSolvingTime:"+numericalSolverSolving+ 325 "|NumericalSolverSolvingTime:"+numericalSolverSolving+
@@ -355,16 +353,19 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
355 } else { 353 } else {
356 return trajectoiresToExplore.element(); 354 return trajectoiresToExplore.element();
357 } 355 }
358 } 356 }
359 357
360 public void visualiseCurrentState() { 358 public void visualiseCurrentState() {
361 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugCongiguration.partialInterpretatioVisualiser; 359 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugConfiguration.partialInterpretatioVisualiser;
362 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) { 360 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) {
363 PartialInterpretation p = (PartialInterpretation) (context.getModel()); 361 PartialInterpretation p = (PartialInterpretation) (context.getModel());
364 int id = ++numberOfPrintedModel; 362 int id = ++numberOfPrintedModel;
365 if (id % configuration.debugCongiguration.partalInterpretationVisualisationFrequency == 0) { 363 if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) {
366 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); 364 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p);
367 visualisation.writeToFile(workspace, String.format("state%09d.png", id)); 365 logger.debug("Visualizing state: " + id + " (" + context.getDesignSpaceManager().getCurrentState() + ")");
366 String name = String.format("state%09d", id);
367 visualisation.writeToFile(workspace, name + ".png");
368 workspace.writeModel((EObject) context.getModel(), name + ".xmi");
368 } 369 }
369 } 370 }
370 } 371 }
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend
new file mode 100644
index 00000000..fb1b2066
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend
@@ -0,0 +1,184 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import com.google.common.collect.HashMultiset
4import com.google.common.collect.ImmutableSet
5import com.google.common.collect.Multiset
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodWithTraces
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
10import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.DiversityDescriptor
11import java.util.Collection
12import java.util.HashSet
13import java.util.Map
14import java.util.Set
15import org.eclipse.viatra.dse.base.ThreadContext
16import org.eclipse.xtend.lib.annotations.Accessors
17
18interface DiversityChecker {
19 public static val NO_DIVERSITY_CHECKER = new DiversityChecker {
20 override isActive() {
21 false
22 }
23
24 override getTotalRuntime() {
25 0
26 }
27
28 override getSuccessRate() {
29 1.0
30 }
31
32 override newSolution(ThreadContext threadContext, Object solutionId, Collection<Object> dominatedSolutionIds) {
33 true
34 }
35 }
36
37 def boolean isActive()
38
39 def long getTotalRuntime()
40
41 def double getSuccessRate()
42
43 def boolean newSolution(ThreadContext threadContext, Object solutionId, Collection<Object> dominatedSolutionIds)
44
45 static def of(DiversityDescriptor descriptor) {
46 if (descriptor.ensureDiversity) {
47 new NodewiseDiversityChecker(descriptor)
48 } else {
49 NO_DIVERSITY_CHECKER
50 }
51 }
52}
53
54abstract class AbstractDiversityChecker implements DiversityChecker {
55 val DiversityDescriptor descriptor
56 val PartialInterpretation2ImmutableTypeLattice solutionCoder = new PartialInterpretation2ImmutableTypeLattice
57
58 @Accessors(PUBLIC_GETTER) var long totalRuntime = 0
59 var int allCheckCount = 0
60 var int successfulCheckCount = 0
61
62 protected new(DiversityDescriptor descriptor) {
63 if (!descriptor.ensureDiversity) {
64 throw new IllegalArgumentException(
65 "Diversity description should enforce diversity or NO_DIVERSITY_CHECKER should be used instead.")
66 }
67 this.descriptor = descriptor
68 }
69
70 override isActive() {
71 true
72 }
73
74 override getTotalRuntime() {
75 throw new UnsupportedOperationException("TODO: auto-generated method stub")
76 }
77
78 override getSuccessRate() {
79 (allCheckCount as double) / (successfulCheckCount as double)
80 }
81
82 override newSolution(ThreadContext threadContext, Object solutionId, Collection<Object> dominatedSolutionIds) {
83 val start = System.nanoTime
84 val model = threadContext.model as PartialInterpretation
85 val representation = solutionCoder.createRepresentation(model, descriptor.range, descriptor.parallels,
86 descriptor.maxNumber, descriptor.relevantTypes, descriptor.relevantRelations)
87 val isDifferent = internalNewSolution(representation, solutionId, dominatedSolutionIds)
88 totalRuntime += System.nanoTime - start
89 allCheckCount++
90 if (isDifferent) {
91 successfulCheckCount++
92 }
93 isDifferent
94 }
95
96 protected abstract def boolean internalNewSolution(
97 NeighbourhoodWithTraces<Map<? extends AbstractNodeDescriptor, Integer>, AbstractNodeDescriptor> representation,
98 Object solutionId, Collection<Object> dominatedSolutionIds)
99}
100
101class NodewiseDiversityChecker extends AbstractDiversityChecker {
102 var Multiset<Integer> nodeCodes = HashMultiset.create
103 val Map<Object, Set<Integer>> tracedNodeCodes = newHashMap
104
105 new(DiversityDescriptor descriptor) {
106 super(descriptor)
107 }
108
109 override protected internalNewSolution(
110 NeighbourhoodWithTraces<Map<? extends AbstractNodeDescriptor, Integer>, AbstractNodeDescriptor> representation,
111 Object solutionId, Collection<Object> dominatedSolutionIds) {
112 val nodeCodesInSolution = ImmutableSet.copyOf(representation.modelRepresentation.keySet.map[hashCode])
113 val remainingNodeCodes = if (dominatedSolutionIds.empty) {
114 nodeCodes
115 } else {
116 getRemainingNodeCodes(dominatedSolutionIds)
117 }
118 val hasNewCode = nodeCodesInSolution.exists[!remainingNodeCodes.contains(it)]
119 if (hasNewCode) {
120 nodeCodes = remainingNodeCodes
121 nodeCodes.addAll(nodeCodesInSolution)
122 for (dominatedSolutionId : dominatedSolutionIds) {
123 tracedNodeCodes.remove(dominatedSolutionId)
124 }
125 tracedNodeCodes.put(solutionId, nodeCodesInSolution)
126 }
127 hasNewCode
128 }
129
130 private def getRemainingNodeCodes(Collection<Object> dominatedSolutionIds) {
131 // TODO Optimize multiset operations.
132 val copyOfNodeCodes = HashMultiset.create(nodeCodes)
133 for (dominatedSolutionId : dominatedSolutionIds) {
134 val dominatedModelCode = tracedNodeCodes.get(dominatedSolutionId)
135 if (dominatedModelCode === null) {
136 throw new IllegalArgumentException("Unknown dominated solution: " + dominatedSolutionId)
137 }
138 copyOfNodeCodes.removeAll(dominatedModelCode)
139 }
140 copyOfNodeCodes
141 }
142}
143
144class GraphwiseDiversityChecker extends AbstractDiversityChecker {
145 var Set<Integer> modelCodes = newHashSet
146 val Map<Object, Integer> tracedModelCodes = newHashMap
147
148 new(DiversityDescriptor descriptor) {
149 super(descriptor)
150 }
151
152 override protected internalNewSolution(
153 NeighbourhoodWithTraces<Map<? extends AbstractNodeDescriptor, Integer>, AbstractNodeDescriptor> representation,
154 Object solutionId, Collection<Object> dominatedSolutionIds) {
155 val modelCodeOfSolution = representation.modelRepresentation.hashCode
156 val remainingModelCodes = if (dominatedSolutionIds.empty) {
157 modelCodes
158 } else {
159 getRemainingModelCodes(dominatedSolutionIds)
160 }
161 val isNewCode = !remainingModelCodes.contains(modelCodeOfSolution)
162 if (isNewCode) {
163 modelCodes = remainingModelCodes
164 modelCodes += modelCodeOfSolution
165 for (dominatedSolutionId : dominatedSolutionIds) {
166 tracedModelCodes.remove(dominatedSolutionId)
167 }
168 tracedModelCodes.put(solutionId, modelCodeOfSolution)
169 }
170 isNewCode
171 }
172
173 private def getRemainingModelCodes(Collection<Object> dominatedSolutionIds) {
174 val copyOfModelCodes = new HashSet(modelCodes)
175 for (dominatedSolutionId : dominatedSolutionIds) {
176 val dominatedModelCode = tracedModelCodes.get(dominatedSolutionId)
177 if (dominatedModelCode === null) {
178 throw new IllegalArgumentException("Unknown dominated solution: " + dominatedSolutionId)
179 }
180 copyOfModelCodes -= dominatedModelCode
181 }
182 copyOfModelCodes
183 }
184}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DseUtils.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DseUtils.xtend
new file mode 100644
index 00000000..3c2e3319
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DseUtils.xtend
@@ -0,0 +1,66 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.IThreeValuedObjective
4import org.eclipse.viatra.dse.base.ThreadContext
5import org.eclipse.viatra.dse.objectives.Comparators
6import org.eclipse.viatra.dse.objectives.Fitness
7import org.eclipse.viatra.dse.objectives.IObjective
8
9final class DseUtils {
10 private new() {
11 throw new IllegalStateException("This is a static utility class and should not be instantiated directly.")
12 }
13
14 static def calculateFitness(ThreadContext it, (IObjective)=>Double getFitness) {
15 val result = new Fitness
16 var boolean satisifiesHardObjectives = true
17 for (objective : objectives) {
18 val fitness = getFitness.apply(objective)
19 result.put(objective.name, fitness)
20 if (objective.isHardObjective() && !objective.satisifiesHardObjective(fitness)) {
21 satisifiesHardObjectives = false
22 }
23 }
24 result.satisifiesHardObjectives = satisifiesHardObjectives
25 result
26 }
27
28 static def caclulateBestPossibleFitness(ThreadContext threadContext) {
29 threadContext.calculateFitness [ objective |
30 if (objective instanceof IThreeValuedObjective) {
31 objective.getBestPossibleFitness(threadContext)
32 } else {
33 switch (objective.comparator) {
34 case Comparators.LOWER_IS_BETTER:
35 Double.NEGATIVE_INFINITY
36 case Comparators.HIGHER_IS_BETTER:
37 Double.POSITIVE_INFINITY
38 case Comparators.DIFFERENCE_TO_ZERO_IS_BETTER:
39 0.0
40 default:
41 throw new IllegalArgumentException("Unknown comparator for non-three-valued objective: " +
42 objective.name)
43 }
44 }
45 ]
46 }
47
48 static def caclulateWorstPossibleFitness(ThreadContext threadContext) {
49 threadContext.calculateFitness [ objective |
50 if (objective instanceof IThreeValuedObjective) {
51 objective.getWorstPossibleFitness(threadContext)
52 } else {
53 switch (objective.comparator) {
54 case Comparators.LOWER_IS_BETTER,
55 case Comparators.DIFFERENCE_TO_ZERO_IS_BETTER:
56 Double.POSITIVE_INFINITY
57 case Comparators.HIGHER_IS_BETTER:
58 Double.NEGATIVE_INFINITY
59 default:
60 throw new IllegalArgumentException("Unknown comparator for non-three-valued objective: " +
61 objective.name)
62 }
63 }
64 ]
65 }
66}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java
index f1bf96b6..d9f84b36 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java
@@ -16,6 +16,7 @@ import java.util.Random;
16import java.util.Set; 16import java.util.Set;
17 17
18import org.apache.log4j.Logger; 18import org.apache.log4j.Logger;
19import org.eclipse.emf.ecore.EObject;
19import org.eclipse.emf.ecore.util.EcoreUtil; 20import org.eclipse.emf.ecore.util.EcoreUtil;
20import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; 21import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
21import org.eclipse.viatra.dse.base.ThreadContext; 22import org.eclipse.viatra.dse.base.ThreadContext;
@@ -35,12 +36,12 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem;
35import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult; 36import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult;
36import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult; 37import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult;
37import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult; 38import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult;
38import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod;
39import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic; 39import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic;
40import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation; 40import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation;
41import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedPartialInterpretationStateCoder; 41import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedPartialInterpretationStateCoder;
42import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation; 42import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation;
43import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser; 43import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser;
44import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ModelGenerationMethod;
44import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.RealisticGuidance; 45import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.RealisticGuidance;
45import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration; 46import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration;
46import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace; 47import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace;
@@ -84,6 +85,8 @@ public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements
84 private double currentNodeTypeDistance = 1; 85 private double currentNodeTypeDistance = 1;
85 private int numNodesToGenerate = 0; 86 private int numNodesToGenerate = 0;
86 public long explorationStarted = 0; 87 public long explorationStarted = 0;
88 public long globalConstraintEvaluationTime = 0;
89 public long fitnessCalculationTime = 0;
87 90
88 public HillClimbingOnRealisticMetricStrategyForModelGeneration( 91 public HillClimbingOnRealisticMetricStrategyForModelGeneration(
89 ReasonerWorkspace workspace, 92 ReasonerWorkspace workspace,
@@ -104,6 +107,13 @@ public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements
104 public int getNumberOfStatecoderFail() { 107 public int getNumberOfStatecoderFail() {
105 return numberOfStatecoderFail; 108 return numberOfStatecoderFail;
106 } 109 }
110
111 public long getForwardTime() {
112 return context.getDesignSpaceManager().getForwardTime();
113 }
114 public long getBacktrackingTime() {
115 return context.getDesignSpaceManager().getBacktrackingTime();
116 }
107 117
108 @Override 118 @Override
109 public void initStrategy(ThreadContext context) { 119 public void initStrategy(ThreadContext context) {
@@ -147,13 +157,13 @@ public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements
147 //set whether allows must violations during the realistic generation 157 //set whether allows must violations during the realistic generation
148 allowMustViolation = configuration.allowMustViolations; 158 allowMustViolation = configuration.allowMustViolations;
149 targetSize = configuration.typeScopes.maxNewElements + 2; 159 targetSize = configuration.typeScopes.maxNewElements + 2;
150 this.numericSolver = new NumericSolver(context, method, this.configuration.runIntermediateNumericalConsistencyChecks, false); 160 //this.numericSolver = new NumericSolver(method, this.configuration.runIntermediateNumericalConsistencyChecks, false);
151 } 161 }
152 162
153 @Override 163 @Override
154 public void explore() { 164 public void explore() {
155 this.explorationStarted=System.nanoTime(); 165 this.explorationStarted=System.nanoTime();
156 if (!context.checkGlobalConstraints()) { 166 if (!checkGlobalConstraints()) {
157 logger.info("Global contraint is not satisifed in the first state. Terminate."); 167 logger.info("Global contraint is not satisifed in the first state. Terminate.");
158 return; 168 return;
159 } 169 }
@@ -236,6 +246,14 @@ public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements
236 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness); 246 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness);
237 if(consistencyCheckResult == true) { continue mainLoop; } 247 if(consistencyCheckResult == true) { continue mainLoop; }
238 248
249// if (context.isCurrentStateAlreadyTraversed()) {
250// logger.info("The new state is already visited.");
251// context.backtrack();
252// } else if (!checkGlobalConstraints()) {
253// logger.debug("Global contraint is not satisifed.");
254// context.backtrack();
255// }
256
239 int currentSize = model.getNewElements().size(); 257 int currentSize = model.getNewElements().size();
240 int targetDiff = targetSize - currentSize; 258 int targetDiff = targetSize - currentSize;
241 boolean shouldFinish = currentSize >= targetSize; 259 boolean shouldFinish = currentSize >= targetSize;
@@ -278,6 +296,20 @@ public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements
278 logger.info("Interrupted."); 296 logger.info("Interrupted.");
279 } 297 }
280 298
299 private boolean checkGlobalConstraints() {
300 long start = System.nanoTime();
301 boolean result = context.checkGlobalConstraints();
302 globalConstraintEvaluationTime += System.nanoTime() - start;
303 return result;
304 }
305
306 private Fitness calculateFitness() {
307 long start = System.nanoTime();
308 Fitness fitness = context.calculateFitness();
309 fitnessCalculationTime += System.nanoTime() - start;
310 return fitness;
311 }
312
281 /** 313 /**
282 * 314 *
283 * @param activationIds 315 * @param activationIds
@@ -475,7 +507,7 @@ public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements
475 solutionStoreWithCopy.newSolution(context); 507 solutionStoreWithCopy.newSolution(context);
476 solutionStoreWithDiversityDescriptor.newSolution(context); 508 solutionStoreWithDiversityDescriptor.newSolution(context);
477 solutionStore.newSolution(context); 509 solutionStore.newSolution(context);
478 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolution); 510 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolutions);
479 511
480 logger.debug("Found a solution."); 512 logger.debug("Found a solution.");
481 } 513 }
@@ -484,23 +516,27 @@ public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements
484 516
485 public List<String> times = new LinkedList<String>(); 517 public List<String> times = new LinkedList<String>();
486 private void saveTimes() { 518 private void saveTimes() {
519 long forwardTime = context.getDesignSpaceManager().getForwardTime()/1000000;
520 long backtrackingTime = context.getDesignSpaceManager().getBacktrackingTime()/1000000;
487 long statecoderTime = ((NeighbourhoodBasedPartialInterpretationStateCoder)this.context.getStateCoder()).getStatecoderRuntime()/1000000; 521 long statecoderTime = ((NeighbourhoodBasedPartialInterpretationStateCoder)this.context.getStateCoder()).getStatecoderRuntime()/1000000;
488 long solutionCopy = solutionStoreWithCopy.getSumRuntime()/1000000; 522 long solutionCopy = solutionStoreWithCopy.getSumRuntime()/1000000;
489 long activationSelection = this.activationSelector.getRuntime()/1000000; 523 long activationSelection = this.activationSelector.getRuntime()/1000000;
490 long numericalSolverSumTime = this.numericSolver.getRuntime()/1000000; 524// long numericalSolverSumTime = this.numericSolver.getRuntime()/1000000;
491 long numericalSolverProblemForming = this.numericSolver.getSolverSolvingProblem()/1000000; 525// long numericalSolverProblemForming = this.numericSolver.getSolverSolvingProblem()/1000000;
492 long numericalSolverSolving = this.numericSolver.getSolverSolvingProblem()/1000000; 526// long numericalSolverSolving = this.numericSolver.getSolverSolvingProblem()/1000000;
493 long numericalSolverInterpreting = this.numericSolver.getSolverSolution()/1000000; 527// long numericalSolverInterpreting = this.numericSolver.getSolverSolution()/1000000;
494 long metricCalculationTime = this.method.getStatistics().metricCalculationTime / 1000000; 528 long metricCalculationTime = this.method.getStatistics().metricCalculationTime / 1000000;
495 this.times.add( 529 this.times.add(
496 "(TransformationExecutionTime"+method.getStatistics().transformationExecutionTime/1000000+ 530 "(TransformationExecutionTime"+method.getStatistics().transformationExecutionTime/1000000+
531 "|ForwardTime:"+forwardTime+
532 "|Backtrackingtime:"+backtrackingTime+
497 "|StateCoderTime:"+statecoderTime+ 533 "|StateCoderTime:"+statecoderTime+
498 "|SolutionCopyTime:"+solutionCopy+ 534 "|SolutionCopyTime:"+solutionCopy+
499 "|ActivationSelectionTime:"+activationSelection+ 535 "|ActivationSelectionTime:"+activationSelection+
500 "|NumericalSolverSumTime:"+numericalSolverSumTime+ 536 //"|NumericalSolverSumTime:"+numericalSolverSumTime+
501 "|NumericalSolverProblemFormingTime:"+numericalSolverProblemForming+ 537 //"|NumericalSolverProblemFormingTime:"+numericalSolverProblemForming+
502 "|NumericalSolverSolvingTime:"+numericalSolverSolving+ 538 //"|NumericalSolverSolvingTime:"+numericalSolverSolving+
503 "|NumericalSolverInterpretingSolution:"+numericalSolverInterpreting+ 539 //"|NumericalSolverInterpretingSolution:"+numericalSolverInterpreting+
504 "|MetricCalculationTime:"+metricCalculationTime + ")" 540 "|MetricCalculationTime:"+metricCalculationTime + ")"
505 ); 541 );
506 542
@@ -544,13 +580,16 @@ public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements
544// } 580// }
545 581
546 public void visualiseCurrentState() { 582 public void visualiseCurrentState() {
547 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugCongiguration.partialInterpretatioVisualiser; 583 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugConfiguration.partialInterpretatioVisualiser;
548 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) { 584 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) {
549 PartialInterpretation p = (PartialInterpretation) (context.getModel()); 585 PartialInterpretation p = (PartialInterpretation) (context.getModel());
550 int id = ++numberOfPrintedModel; 586 int id = ++numberOfPrintedModel;
551 if (id % configuration.debugCongiguration.partalInterpretationVisualisationFrequency == 0) { 587 if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) {
552 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); 588 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p);
553 visualisation.writeToFile(workspace, String.format("state%09d.png", id)); 589 logger.debug("Visualizing state: " + id + " (" + context.getDesignSpaceManager().getCurrentState() + ")");
590 String name = String.format("state%09d", id);
591 visualisation.writeToFile(workspace, name + ".png");
592 workspace.writeModel((EObject) context.getModel(), name + ".xmi");
554 } 593 }
555 } 594 }
556 } 595 }
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/InconsistentScopeGlobalConstraint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/InconsistentScopeGlobalConstraint.xtend
new file mode 100644
index 00000000..2e039ca2
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/InconsistentScopeGlobalConstraint.xtend
@@ -0,0 +1,25 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import org.eclipse.viatra.dse.objectives.IGlobalConstraint
4import org.eclipse.viatra.dse.base.ThreadContext
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
6
7class InconsistentScopeGlobalConstraint implements IGlobalConstraint {
8
9 override init(ThreadContext context) {
10 // Nothing to initialize.
11 }
12
13 override createNew() {
14 this
15 }
16
17 override getName() {
18 class.name
19 }
20
21 override checkGlobalConstraint(ThreadContext context) {
22 val partialModel = context.model as PartialInterpretation
23 partialModel.minNewElements <= partialModel.maxNewElements || partialModel.maxNewElements < 0
24 }
25}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/LoggerSolutionFoundHandler.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/LoggerSolutionFoundHandler.xtend
new file mode 100644
index 00000000..39ef5f9a
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/LoggerSolutionFoundHandler.xtend
@@ -0,0 +1,24 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration
4import org.apache.log4j.Logger
5import org.eclipse.viatra.dse.api.SolutionTrajectory
6import org.eclipse.viatra.dse.base.ThreadContext
7import org.eclipse.viatra.dse.solutionstore.ISolutionFoundHandler
8import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
9
10@FinalFieldsConstructor
11class LoggerSolutionFoundHandler implements ISolutionFoundHandler {
12 val ViatraReasonerConfiguration configuration
13
14 val logger = Logger.getLogger(SolutionCopier)
15
16 override solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
17 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolutions)
18 logger.debug("Found a solution.")
19 }
20
21 override solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
22 // We are not interested in invalid solutions, ignore.
23 }
24}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend
index a10530c7..27208cf4 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend
@@ -1,67 +1,49 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import com.google.common.collect.ImmutableList
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration
6import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.IThreeValuedObjective
3import java.util.Comparator 7import java.util.Comparator
4import java.util.List 8import java.util.List
5import org.eclipse.viatra.dse.base.ThreadContext 9import org.eclipse.viatra.dse.base.ThreadContext
6import org.eclipse.viatra.dse.objectives.Comparators 10import org.eclipse.viatra.dse.objectives.Comparators
7import org.eclipse.viatra.dse.objectives.IObjective 11import org.eclipse.viatra.dse.objectives.IObjective
8import org.eclipse.viatra.dse.objectives.impl.BaseObjective 12import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PrimitiveElement
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
10import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration
11 13
12//class ViatraReasonerNumbers { 14class ModelGenerationCompositeObjective implements IThreeValuedObjective {
13// public static val scopePriority = 2 15 val IObjective scopeObjective
14// public static val unfinishedMultiplicityPriority = 2
15// public static val unifinshedWFPriority = 2
16// //public static val complexityPriority = 4
17//
18// public static val scopeWeigth = 1.0
19// public static val unfinishedMultiplicityWeigth = 1.5
20// public static val unfinishedWFWeigth = 1.5
21// //public static val complexityWeigth = 0.1
22//
23// public static val useCompositeObjective = true
24// public static val compositePriority = 2
25//}
26
27class ModelGenerationCompositeObjective implements IObjective{
28 val ScopeObjective scopeObjective
29 val List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives 16 val List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives
30 val UnfinishedWFObjective unfinishedWFObjective 17 val UnfinishedWFObjective unfinishedWFObjective
31 var PartialInterpretation model=null; 18 var PartialInterpretation model = null
32 val boolean punishSize
33 val int scopeWeight 19 val int scopeWeight
34 val int conaintmentWeight 20 val int conaintmentWeight
35 val int nonContainmentWeight 21 val int nonContainmentWeight
36 val int unfinishedWFWeight 22 val int unfinishedWFWeight
37 23
38 new( 24 new(
39 ScopeObjective scopeObjective, 25 IObjective scopeObjective,
40 List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives, 26 List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives,
41 UnfinishedWFObjective unfinishedWFObjective, 27 UnfinishedWFObjective unfinishedWFObjective,
42 ViatraReasonerConfiguration configuration) 28 ViatraReasonerConfiguration configuration)
43 { 29 {
44 this.scopeObjective = scopeObjective 30 this(
45 this.unfinishedMultiplicityObjectives = unfinishedMultiplicityObjectives 31 scopeObjective, unfinishedMultiplicityObjectives, unfinishedWFObjective,
46 this.unfinishedWFObjective = unfinishedWFObjective 32 configuration.scopeWeight, configuration.conaintmentWeight, configuration.nonContainmentWeight,
47 33 configuration.unfinishedWFWeight
48 this.punishSize = configuration.punishSize 34 )
49 this.scopeWeight = configuration.scopeWeight
50 this.conaintmentWeight = configuration.conaintmentWeight
51 this.nonContainmentWeight = configuration.nonContainmentWeight
52 this.unfinishedWFWeight = configuration.unfinishedWFWeight
53 } 35 }
36
54 new( 37 new(
55 ScopeObjective scopeObjective, 38 IObjective scopeObjective,
56 List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives, 39 List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives,
57 UnfinishedWFObjective unfinishedWFObjective, 40 UnfinishedWFObjective unfinishedWFObjective,
58 boolean punishSize, int scopeWeight, int conaintmentWeight, int nonContainmentWeight, int unfinishedWFWeight) 41 int scopeWeight, int conaintmentWeight, int nonContainmentWeight, int unfinishedWFWeight)
59 { 42 {
60 this.scopeObjective = scopeObjective 43 this.scopeObjective = scopeObjective
61 this.unfinishedMultiplicityObjectives = unfinishedMultiplicityObjectives 44 this.unfinishedMultiplicityObjectives = unfinishedMultiplicityObjectives
62 this.unfinishedWFObjective = unfinishedWFObjective 45 this.unfinishedWFObjective = unfinishedWFObjective
63 46
64 this.punishSize = punishSize
65 this.scopeWeight = scopeWeight 47 this.scopeWeight = scopeWeight
66 this.conaintmentWeight = conaintmentWeight 48 this.conaintmentWeight = conaintmentWeight
67 this.nonContainmentWeight = nonContainmentWeight 49 this.nonContainmentWeight = nonContainmentWeight
@@ -74,33 +56,34 @@ class ModelGenerationCompositeObjective implements IObjective{
74 this.unfinishedMultiplicityObjectives.forEach[it.init(context)] 56 this.unfinishedMultiplicityObjectives.forEach[it.init(context)]
75 this.unfinishedWFObjective.init(context) 57 this.unfinishedWFObjective.init(context)
76 } 58 }
77 59
78 override createNew() { 60 override createNew() {
79 return new ModelGenerationCompositeObjective( 61 return new ModelGenerationCompositeObjective(
80 this.scopeObjective, this.unfinishedMultiplicityObjectives, this.unfinishedWFObjective, 62 scopeObjective.createNew,
81 this.punishSize, this.scopeWeight, this.conaintmentWeight, this.nonContainmentWeight, this.unfinishedWFWeight) 63 ImmutableList.copyOf(unfinishedMultiplicityObjectives.map[createNew as UnfinishedMultiplicityObjective]),
64 unfinishedWFObjective.createNew as UnfinishedWFObjective,
65 scopeWeight, conaintmentWeight, nonContainmentWeight, unfinishedWFWeight
66 )
82 } 67 }
83 68
84 override getComparator() { Comparators.LOWER_IS_BETTER } 69 override getComparator() { Comparators.LOWER_IS_BETTER }
70
85 override getFitness(ThreadContext context) { 71 override getFitness(ThreadContext context) {
86 72
87 val scopeFitnes = scopeObjective.getFitness(context) 73 val scopeFitnes = scopeObjective.getFitness(context)
88 //val unfinishedMultiplicitiesFitneses = unfinishedMultiplicityObjectives.map[x|x.getFitness(context)]
89 val unfinishedWFsFitness = unfinishedWFObjective.getFitness(context) 74 val unfinishedWFsFitness = unfinishedWFObjective.getFitness(context)
90 75
91 var containmentMultiplicity = 0.0 76 var containmentMultiplicity = 0.0
92 var nonContainmentMultiplicity = 0.0 77 var nonContainmentMultiplicity = 0.0
93 for(multiplicityObjective : unfinishedMultiplicityObjectives) { 78 for(multiplicityObjective : unfinishedMultiplicityObjectives) {
79 val multiplicity = multiplicityObjective.getFitness(context)
80// println(multiplicityObjective.name + "=" + multiplicity)
94 if(multiplicityObjective.containment) { 81 if(multiplicityObjective.containment) {
95 containmentMultiplicity+=multiplicityObjective.getFitness(context) 82 containmentMultiplicity+=multiplicity
96 } else { 83 } else {
97 nonContainmentMultiplicity+=multiplicityObjective.getFitness(context) 84 nonContainmentMultiplicity+=multiplicity
98 } 85 }
99 } 86
100 val size = if(punishSize) {
101 0.9/model.newElements.size
102 } else {
103 0
104 } 87 }
105 88
106 var sum = 0.0 89 var sum = 0.0
@@ -108,25 +91,33 @@ class ModelGenerationCompositeObjective implements IObjective{
108 sum += containmentMultiplicity*conaintmentWeight 91 sum += containmentMultiplicity*conaintmentWeight
109 sum += nonContainmentMultiplicity*nonContainmentWeight 92 sum += nonContainmentMultiplicity*nonContainmentWeight
110 sum += unfinishedWFsFitness*unfinishedWFWeight 93 sum += unfinishedWFsFitness*unfinishedWFWeight
111 sum+=size
112 94
113 //println('''Sum=«sum»|Scope=«scopeFitnes»|ContainmentMultiplicity=«containmentMultiplicity»|NonContainmentMultiplicity=«nonContainmentMultiplicity»|WFs=«unfinishedWFsFitness»''') 95// println('''scope=«scopeFitnes», containment=«containmentMultiplicity», nonContainment=«nonContainmentMultiplicity», wf=«unfinishedWFsFitness», sum=«sum»''')
114 96
115 return sum 97 return sum
116 } 98 }
117 99
118 override getLevel() { 2 } 100 override getWorstPossibleFitness(ThreadContext threadContext) {
119 override getName() { "CompositeUnfinishednessObjective"} 101 Double.POSITIVE_INFINITY
102 }
120 103
104 override getBestPossibleFitness(ThreadContext threadContext) {
105 0.0
106 }
107
108 override getLevel() { 2 }
109
110 override getName() { "CompositeUnfinishednessObjective" }
111
121 override isHardObjective() { true } 112 override isHardObjective() { true }
122 override satisifiesHardObjective(Double fitness) { fitness < 0.95 } 113
123 114 override satisifiesHardObjective(Double fitness) { fitness < 0.01 }
124 115
125 override setComparator(Comparator<Double> comparator) { 116 override setComparator(Comparator<Double> comparator) {
126 throw new UnsupportedOperationException("TODO: auto-generated method stub") 117 throw new UnsupportedOperationException("Model generation objective comparator cannot be set.")
127 } 118 }
119
128 override setLevel(int level) { 120 override setLevel(int level) {
129 throw new UnsupportedOperationException("TODO: auto-generated method stub") 121 throw new UnsupportedOperationException("Model generation objective level cannot be set.")
130 } 122 }
131 123}
132} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend
index 0b0feb1a..70e8e9c2 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend
@@ -1,13 +1,13 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import hu.bme.mit.inf.dslreasoner.viatra2logic.NumericTranslator 3import hu.bme.mit.inf.dslreasoner.viatra2logic.NumericTranslator
4import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BooleanElement 4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BooleanElement
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.IntegerElement 5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.IntegerElement
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PrimitiveElement 7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PrimitiveElement
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.RealElement 8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.RealElement
10import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.StringElement 9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.StringElement
10import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ModelGenerationMethod
11import java.math.BigDecimal 11import java.math.BigDecimal
12import java.util.HashMap 12import java.util.HashMap
13import java.util.LinkedHashMap 13import java.util.LinkedHashMap
@@ -21,7 +21,8 @@ import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
21import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint 21import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint
22 22
23class NumericSolver { 23class NumericSolver {
24 val ThreadContext threadContext; 24 val ModelGenerationMethod method
25 var ThreadContext threadContext
25 val constraint2MustUnitPropagationPrecondition = new HashMap<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>> 26 val constraint2MustUnitPropagationPrecondition = new HashMap<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>>
26 val constraint2CurrentUnitPropagationPrecondition = new HashMap<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>> 27 val constraint2CurrentUnitPropagationPrecondition = new HashMap<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>>
27 NumericTranslator t = new NumericTranslator 28 NumericTranslator t = new NumericTranslator
@@ -35,8 +36,16 @@ class NumericSolver {
35 var int numberOfSolverCalls = 0 36 var int numberOfSolverCalls = 0
36 var int numberOfCachedSolverCalls = 0 37 var int numberOfCachedSolverCalls = 0
37 38
38 new(ThreadContext threadContext, ModelGenerationMethod method, boolean intermediateConsistencyCheck, boolean caching) { 39 new(ModelGenerationMethod method, boolean intermediateConsistencyCheck, boolean caching) {
39 this.threadContext = threadContext 40 this.method = method
41 this.intermediateConsistencyCheck = intermediateConsistencyCheck
42 this.caching = caching
43 }
44
45 def init(ThreadContext context) {
46 // This makes the NumericSolver single-threaded,
47 // but that's not a problem, because we only use the solver on a single thread anyways.
48 this.threadContext = context
40 val engine = threadContext.queryEngine 49 val engine = threadContext.queryEngine
41 for(entry : method.mustUnitPropagationPreconditions.entrySet) { 50 for(entry : method.mustUnitPropagationPreconditions.entrySet) {
42 val constraint = entry.key 51 val constraint = entry.key
@@ -50,8 +59,6 @@ class NumericSolver {
50 val matcher = querySpec.getMatcher(engine); 59 val matcher = querySpec.getMatcher(engine);
51 constraint2CurrentUnitPropagationPrecondition.put(constraint,matcher) 60 constraint2CurrentUnitPropagationPrecondition.put(constraint,matcher)
52 } 61 }
53 this.intermediateConsistencyCheck = intermediateConsistencyCheck
54 this.caching = caching
55 } 62 }
56 63
57 def getRuntime(){runtime} 64 def getRuntime(){runtime}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend
index efc2ef36..b48d0831 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend
@@ -22,12 +22,13 @@ import java.util.List
22import java.util.Map 22import java.util.Map
23import java.util.TreeSet 23import java.util.TreeSet
24import org.eclipse.emf.ecore.EObject 24import org.eclipse.emf.ecore.EObject
25import org.eclipse.xtend.lib.annotations.Accessors
25import org.eclipse.xtext.xbase.lib.Functions.Function1 26import org.eclipse.xtext.xbase.lib.Functions.Function1
26 27
27import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* 28import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
28 29
29class PartialModelAsLogicInterpretation implements LogicModelInterpretation{ 30class PartialModelAsLogicInterpretation implements LogicModelInterpretation{
30 val PartialInterpretation partialInterpretation 31 @Accessors val PartialInterpretation partialInterpretation
31 val Map<EObject, EObject> trace; 32 val Map<EObject, EObject> trace;
32 val Map<TypeDeclaration,PartialComplexTypeInterpretation> type2Interpretation 33 val Map<TypeDeclaration,PartialComplexTypeInterpretation> type2Interpretation
33 val Map<RelationDeclaration,PartialRelationInterpretation> relation2Interpretation 34 val Map<RelationDeclaration,PartialRelationInterpretation> relation2Interpretation
@@ -219,4 +220,4 @@ class PartialModelAsLogicInterpretation implements LogicModelInterpretation{
219 } 220 }
220 builder 221 builder
221 } 222 }
222} \ No newline at end of file 223}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PunishSizeObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PunishSizeObjective.xtend
new file mode 100644
index 00000000..bad8e4d1
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PunishSizeObjective.xtend
@@ -0,0 +1,52 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PrimitiveElement
5import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.AbstractThreeValuedObjective
6import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveKind
7import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold
8import org.eclipse.viatra.dse.base.ThreadContext
9
10class PunishSizeObjective extends AbstractThreeValuedObjective {
11 static val NAME = typeof(PunishSizeObjective).name
12
13 new(ObjectiveKind kind, int level) {
14 super(NAME, kind, ObjectiveThreshold.NO_THRESHOLD, level)
15 }
16
17 override createNew() {
18 new PunishSizeObjective(kind, level)
19 }
20
21 override init(ThreadContext context) {
22 // Nothing to initialize.
23 }
24
25 override getRawFitness(ThreadContext threadContext) {
26 val model = threadContext.model
27 if (model instanceof PartialInterpretation) {
28 val size = model.newObjectCount
29// println('''size=«size»''')
30 size as double
31 } else {
32 throw new IllegalArgumentException("notifier must be a PartialInterpretation")
33 }
34 }
35
36 override getLowestPossibleFitness(ThreadContext threadContext) {
37 getRawFitness(threadContext)
38 }
39
40 override getHighestPossibleFitness(ThreadContext threadContext) {
41 val model = threadContext.model
42 if (model instanceof PartialInterpretation) {
43 (model.newObjectCount + model.maxNewElements) as double
44 } else {
45 throw new IllegalArgumentException("notifier must be a PartialInterpretation")
46 }
47 }
48
49 private def getNewObjectCount(PartialInterpretation interpretation) {
50 interpretation.newElements.reject[it instanceof PrimitiveElement].size
51 }
52} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend
index 69efe0d7..b61bd20b 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend
@@ -23,9 +23,9 @@ class ScopeObjective implements IObjective{
23 23
24 override getFitness(ThreadContext context) { 24 override getFitness(ThreadContext context) {
25 val interpretation = context.model as PartialInterpretation 25 val interpretation = context.model as PartialInterpretation
26 var res = interpretation.minNewElements.doubleValue 26 var res = interpretation.minNewElementsHeuristic.doubleValue
27 for(scope : interpretation.scopes) { 27 for(scope : interpretation.scopes) {
28 res += scope.minNewElements*2 28 res += scope.minNewElementsHeuristic * 2
29 } 29 }
30 return res 30 return res
31 } 31 }
@@ -41,4 +41,4 @@ class ScopeObjective implements IObjective{
41 throw new UnsupportedOperationException("TODO: auto-generated method stub") 41 throw new UnsupportedOperationException("TODO: auto-generated method stub")
42 } 42 }
43 override getLevel() { 2 } 43 override getLevel() { 2 }
44} \ No newline at end of file 44}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionCopier.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionCopier.xtend
new file mode 100644
index 00000000..888eda18
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionCopier.xtend
@@ -0,0 +1,82 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import com.google.common.collect.ImmutableList
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import java.util.LinkedHashMap
6import java.util.List
7import java.util.Map
8import org.eclipse.emf.ecore.EObject
9import org.eclipse.emf.ecore.util.EcoreUtil
10import org.eclipse.viatra.dse.base.ThreadContext
11import org.eclipse.xtend.lib.annotations.Accessors
12import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
13
14@FinalFieldsConstructor
15class CopiedSolution {
16 @Accessors val PartialInterpretation partialInterpretations
17 @Accessors val Map<EObject, EObject> trace
18 @Accessors val long copierRuntime
19 @Accessors var boolean current = true
20}
21
22/**
23 * Based on {@link SolutionStore.BestSolutionSaver}.
24 *
25 * Will also automatically fill any missing numerical values in the saved solutions
26 * using the supplied {@link NumericSolver}.
27 */
28class SolutionCopier {
29 val copiedSolutions = new LinkedHashMap<Object, CopiedSolution>
30
31 @Accessors NumericSolver numericSolver
32 long startTime = System.nanoTime
33 @Accessors(PUBLIC_GETTER) long totalCopierRuntime = 0
34
35 def void copySolution(ThreadContext context, Object solutionId) {
36 val existingCopy = copiedSolutions.get(solutionId)
37 if (existingCopy === null) {
38 val copyStart = System.nanoTime
39 val solution = context.model as PartialInterpretation
40 val copier = new EcoreUtil.Copier
41 val copiedPartialInterpretation = copier.copy(solution) as PartialInterpretation
42 copier.copyReferences
43 totalCopierRuntime += System.nanoTime - copyStart
44 val copierRuntime = System.nanoTime - startTime
45 val copiedSolution = new CopiedSolution(copiedPartialInterpretation, copier, copierRuntime)
46 //numericSolver?.fillSolutionCopy(copiedSolution.trace)
47 copiedSolutions.put(solutionId, copiedSolution)
48 } else {
49 existingCopy.current = true
50 }
51 }
52
53 def void markAsObsolete(Object solutionId) {
54 val copiedSolution = copiedSolutions.get(solutionId)
55 if (copiedSolution === null) {
56 throw new IllegalStateException("No solution to mark as obsolete for state code: " + solutionId)
57 }
58 copiedSolution.current = false
59 }
60
61 def List<PartialInterpretation> getPartialInterpretations(boolean currentOnly) {
62 getListOfCopiedSolutions(currentOnly).map[partialInterpretations]
63 }
64
65 def List<Map<EObject, EObject>> getTraces(boolean currentOnly) {
66 getListOfCopiedSolutions(currentOnly).map[trace]
67 }
68
69 def List<Long> getAllCopierRuntimes(boolean currentOnly) {
70 getListOfCopiedSolutions(currentOnly).map[copierRuntime]
71 }
72
73 def List<CopiedSolution> getListOfCopiedSolutions(boolean currentOnly) {
74 val values = copiedSolutions.values
75 val filteredSolutions = if (currentOnly) {
76 values.filter[current]
77 } else {
78 values
79 }
80 ImmutableList.copyOf(filteredSolutions)
81 }
82}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend
index 21867a4e..4bd2c349 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend
@@ -1,14 +1,12 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import java.util.List
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 3import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import java.util.LinkedList 4import java.util.LinkedList
6import org.eclipse.emf.ecore.EObject 5import java.util.List
7import java.util.Map 6import java.util.Map
7import org.eclipse.emf.ecore.EObject
8import org.eclipse.emf.ecore.util.EcoreUtil 8import org.eclipse.emf.ecore.util.EcoreUtil
9import org.eclipse.viatra.dse.base.ThreadContext 9import org.eclipse.viatra.dse.base.ThreadContext
10import java.util.TreeMap
11import java.util.SortedMap
12 10
13class SolutionStoreWithCopy { 11class SolutionStoreWithCopy {
14 12
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend
deleted file mode 100644
index 1e7f18a8..00000000
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend
+++ /dev/null
@@ -1,120 +0,0 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.DiversityDescriptor
6import java.util.LinkedList
7import java.util.List
8import org.eclipse.viatra.dse.base.ThreadContext
9import java.util.HashSet
10import java.util.Set
11
12enum DiversityGranularity {
13 Nodewise, Graphwise
14}
15
16class SolutionStoreWithDiversityDescriptor {
17 val DiversityDescriptor descriptor
18 DiversityGranularity granularity
19 val PartialInterpretation2ImmutableTypeLattice solutionCoder = new PartialInterpretation2ImmutableTypeLattice
20 val Set<Integer> solutionCodeList = new HashSet
21
22 var long runtime
23 var int allCheck
24 var int successfulCheck
25
26 new(DiversityDescriptor descriptor) {
27 if(descriptor.ensureDiversity) {
28 this.descriptor = descriptor
29 this.granularity = DiversityGranularity::Nodewise
30 } else {
31 this.descriptor = null
32 this.granularity = DiversityGranularity::Nodewise
33 }
34 }
35
36 def public isActive() {
37 descriptor!==null
38 }
39
40 def getSumRuntime() {
41 return runtime
42 }
43 def getSuccessRate() {
44 return successfulCheck as double / allCheck
45 }
46
47 def isDifferent(ThreadContext context) {
48 if(active) {
49 val start = System.nanoTime
50 val model = context.model as PartialInterpretation
51 var boolean isDifferent
52 if(this.granularity == DiversityGranularity::Graphwise) {
53 val code = solutionCoder.createRepresentation(model,
54 descriptor.range,
55 descriptor.parallels,
56 descriptor.maxNumber,
57 descriptor.relevantTypes,
58 descriptor.relevantRelations).modelRepresentation.hashCode
59
60 isDifferent = !solutionCodeList.contains(code)
61 } else if(this.granularity == DiversityGranularity::Nodewise){
62 val codes = solutionCoder.createRepresentation(model,
63 descriptor.range,
64 descriptor.parallels,
65 descriptor.maxNumber,
66 descriptor.relevantTypes,
67 descriptor.relevantRelations).modelRepresentation.keySet.map[hashCode].toList
68 val differentCodes = codes.filter[!solutionCodeList.contains(it)]
69 //println(differentCodes.size)
70
71 isDifferent = differentCodes.size>=1
72 } else {
73 throw new UnsupportedOperationException('''Unsupported diversity type: «this.granularity»''')
74 }
75
76 runtime += System.nanoTime - start
77 allCheck++
78 if(isDifferent) { successfulCheck++ }
79 return isDifferent
80 } else {
81 allCheck++
82 successfulCheck++
83 return true
84 }
85 }
86
87 def canBeDifferent(ThreadContext context) {
88 return true
89 }
90
91 def newSolution(ThreadContext context) {
92 if(active) {
93 val start = System.nanoTime
94 val model = context.model as PartialInterpretation
95 if(this.granularity == DiversityGranularity::Graphwise) {
96 val code = solutionCoder.createRepresentation(model,
97 descriptor.range,
98 descriptor.parallels,
99 descriptor.maxNumber,
100 descriptor.relevantTypes,
101 descriptor.relevantRelations).modelRepresentation.hashCode
102
103 solutionCodeList += code.hashCode
104 } else if(this.granularity == DiversityGranularity::Nodewise){
105 val codes = solutionCoder.createRepresentation(model,
106 descriptor.range,
107 descriptor.parallels,
108 descriptor.maxNumber,
109 descriptor.relevantTypes,
110 descriptor.relevantRelations).modelRepresentation.keySet.map[hashCode].toList
111
112 solutionCodeList += codes.map[it.hashCode]
113 } else {
114 throw new UnsupportedOperationException('''Unsupported diversity type: «this.granularity»''')
115 }
116
117 runtime += System.nanoTime - start
118 }
119 }
120} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend
new file mode 100644
index 00000000..8ed3e912
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend
@@ -0,0 +1,27 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import org.eclipse.viatra.dse.base.ThreadContext
4import org.eclipse.viatra.dse.objectives.IGlobalConstraint
5import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
6
7@FinalFieldsConstructor
8class SurelyViolatedObjectiveGlobalConstraint implements IGlobalConstraint {
9 val ViatraReasonerSolutionSaver solutionSaver
10
11 override init(ThreadContext context) {
12 // Nothing to initialize.
13 }
14
15 override createNew() {
16 this
17 }
18
19 override getName() {
20 class.name
21 }
22
23 override checkGlobalConstraint(ThreadContext context) {
24 val bestFitness = DseUtils.caclulateBestPossibleFitness(context)
25 bestFitness.satisifiesHardObjectives && solutionSaver.fitnessMayBeSaved(bestFitness)
26 }
27}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend
index 2b0807d6..e1582d3b 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend
@@ -1,15 +1,15 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.MultiplicityGoalConstraintCalculator 3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.MultiplicityGoalConstraintCalculator
4import java.util.Comparator 4import java.util.Comparator
5import org.eclipse.viatra.dse.base.ThreadContext 5import org.eclipse.viatra.dse.base.ThreadContext
6import org.eclipse.viatra.dse.objectives.IObjective
7import org.eclipse.viatra.dse.objectives.Comparators 6import org.eclipse.viatra.dse.objectives.Comparators
7import org.eclipse.viatra.dse.objectives.IObjective
8 8
9class UnfinishedMultiplicityObjective implements IObjective { 9class UnfinishedMultiplicityObjective implements IObjective {
10 val MultiplicityGoalConstraintCalculator unfinishedMultiplicity; 10 val MultiplicityGoalConstraintCalculator unfinishedMultiplicity
11 11
12 public new(MultiplicityGoalConstraintCalculator unfinishedMultiplicity) { 12 new(MultiplicityGoalConstraintCalculator unfinishedMultiplicity) {
13 this.unfinishedMultiplicity = unfinishedMultiplicity 13 this.unfinishedMultiplicity = unfinishedMultiplicity
14 } 14 }
15 15
@@ -29,12 +29,13 @@ class UnfinishedMultiplicityObjective implements IObjective {
29 override satisifiesHardObjective(Double fitness) { return fitness <=0.01 } 29 override satisifiesHardObjective(Double fitness) { return fitness <=0.01 }
30 30
31 override setComparator(Comparator<Double> comparator) { 31 override setComparator(Comparator<Double> comparator) {
32 throw new UnsupportedOperationException("TODO: auto-generated method stub") 32 throw new UnsupportedOperationException
33 } 33 }
34 override setLevel(int level) { 34 override setLevel(int level) {
35 throw new UnsupportedOperationException("TODO: auto-generated method stub") 35 throw new UnsupportedOperationException
36 } 36 }
37
37 def isContainment() { 38 def isContainment() {
38 return this.unfinishedMultiplicity.containment 39 return this.unfinishedMultiplicity.containment
39 } 40 }
40} \ No newline at end of file 41}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend
index e0111cf6..1b61ffa5 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend
@@ -1,56 +1,64 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import org.eclipse.viatra.dse.objectives.IObjective 3import java.util.ArrayList
4import org.eclipse.viatra.query.runtime.api.IPatternMatch
5import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
6import org.eclipse.viatra.query.runtime.api.IQuerySpecification
7import java.util.Collection 4import java.util.Collection
8import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine 5import java.util.Comparator
9import org.eclipse.viatra.query.runtime.emf.EMFScope
10import org.eclipse.viatra.dse.base.ThreadContext
11import java.util.List 6import java.util.List
7import org.eclipse.viatra.dse.base.ThreadContext
12import org.eclipse.viatra.dse.objectives.Comparators 8import org.eclipse.viatra.dse.objectives.Comparators
13import java.util.ArrayList 9import org.eclipse.viatra.dse.objectives.IObjective
14import java.util.Comparator 10import org.eclipse.viatra.query.runtime.api.IPatternMatch
11import org.eclipse.viatra.query.runtime.api.IQuerySpecification
12import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
15 13
16class UnfinishedWFObjective implements IObjective { 14class UnfinishedWFObjective implements IObjective {
17 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFs 15 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFs
18 val List<ViatraQueryMatcher<?>> matchers 16 val List<ViatraQueryMatcher<?>> matchers
19 17
20 public new(Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFs) { 18 new(
19 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFs) {
21 this.unfinishedWFs = unfinishedWFs 20 this.unfinishedWFs = unfinishedWFs
22 matchers = new ArrayList(unfinishedWFs.size) 21 matchers = new ArrayList(unfinishedWFs.size)
23 } 22 }
23
24 override getName() '''unfinishedWFs''' 24 override getName() '''unfinishedWFs'''
25
25 override createNew() { 26 override createNew() {
26 return new UnfinishedWFObjective(unfinishedWFs) 27 return new UnfinishedWFObjective(unfinishedWFs)
27 } 28 }
29
28 override init(ThreadContext context) { 30 override init(ThreadContext context) {
29 val engine = context.queryEngine//ViatraQueryEngine.on(new EMFScope(context.model)) 31 val engine = context.queryEngine // ViatraQueryEngine.on(new EMFScope(context.model))
30 for(unfinishedWF : unfinishedWFs) { 32 for (unfinishedWF : unfinishedWFs) {
31 matchers += unfinishedWF.getMatcher(engine) 33 matchers += unfinishedWF.getMatcher(engine)
32 } 34 }
33 } 35 }
34 36
35 override getComparator() { Comparators.LOWER_IS_BETTER } 37 override getComparator() { Comparators.LOWER_IS_BETTER }
38
36 override getFitness(ThreadContext context) { 39 override getFitness(ThreadContext context) {
37 var sumOfMatches = 0 40 var sumOfMatches = 0
38 for(matcher : matchers) { 41 for (matcher : matchers) {
39 val number = matcher.countMatches 42 val number = matcher.countMatches
40 //println('''«matcher.patternName» = «number»''') 43// if (number > 0) {
41 sumOfMatches+=number 44// println('''«matcher.patternName» = «number»''')
45// }
46 sumOfMatches += number
42 } 47 }
43 return sumOfMatches.doubleValue 48 return sumOfMatches.doubleValue
44 } 49 }
45 50
46 override getLevel() { 2 } 51 override getLevel() { 2 }
52
47 override isHardObjective() { true } 53 override isHardObjective() { true }
48 override satisifiesHardObjective(Double fitness) { return fitness <=0.01 } 54
49 55 override satisifiesHardObjective(Double fitness) { return fitness <= 0.01 }
56
50 override setComparator(Comparator<Double> comparator) { 57 override setComparator(Comparator<Double> comparator) {
51 throw new UnsupportedOperationException("TODO: auto-generated method stub") 58 throw new UnsupportedOperationException()
52 } 59 }
60
53 override setLevel(int level) { 61 override setLevel(int level) {
54 throw new UnsupportedOperationException("TODO: auto-generated method stub") 62 throw new UnsupportedOperationException()
55 } 63 }
56} \ No newline at end of file 64}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend
new file mode 100644
index 00000000..e00f76ff
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend
@@ -0,0 +1,250 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.Bounds
4import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.DirectionalThresholdObjective
5import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.IObjectiveBoundsProvider
6import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold
7import java.util.HashMap
8import java.util.Map
9import org.eclipse.viatra.dse.api.DSEException
10import org.eclipse.viatra.dse.api.Solution
11import org.eclipse.viatra.dse.api.SolutionTrajectory
12import org.eclipse.viatra.dse.base.ThreadContext
13import org.eclipse.viatra.dse.objectives.Fitness
14import org.eclipse.viatra.dse.objectives.IObjective
15import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper
16import org.eclipse.viatra.dse.solutionstore.SolutionStore.ISolutionSaver
17import org.eclipse.xtend.lib.annotations.Accessors
18
19/**
20 * Based on {@link SolutionStore.BestSolutionSaver}.
21 *
22 * Will also automatically fill any missing numerical values in the saved solutions
23 * using the supplied {@link NumericSolver}.
24 */
25class ViatraReasonerSolutionSaver implements ISolutionSaver, IObjectiveBoundsProvider {
26 static val TOLERANCE = 1e-10
27
28 @Accessors val SolutionCopier solutionCopier
29 @Accessors val DiversityChecker diversityChecker
30 val IObjective[][] leveledExtremalObjectives
31 val boolean hasExtremalObjectives
32 val int numberOfRequiredSolutions
33 val ObjectiveComparatorHelper comparatorHelper
34 val Map<SolutionTrajectory, Fitness> trajectories = new HashMap
35
36 @Accessors var NumericSolver numericSolver
37 @Accessors var Map<Object, Solution> solutionsCollection
38
39 new(IObjective[][] leveledExtremalObjectives, int numberOfRequiredSolutions, DiversityChecker diversityChecker) {
40 this.diversityChecker = diversityChecker
41 comparatorHelper = new ObjectiveComparatorHelper(leveledExtremalObjectives)
42 this.leveledExtremalObjectives = leveledExtremalObjectives
43 hasExtremalObjectives = leveledExtremalObjectives.exists[!empty]
44 this.numberOfRequiredSolutions = numberOfRequiredSolutions
45 this.solutionCopier = new SolutionCopier
46 }
47
48 def setNumericSolver(NumericSolver numericSolver) {
49 this.numericSolver = numericSolver
50 solutionCopier.numericSolver = numericSolver
51 }
52
53 override saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
54 if (hasExtremalObjectives) {
55 saveBestSolutionOnly(context, id, solutionTrajectory)
56 } else {
57 saveAnyDiverseSolution(context, id, solutionTrajectory)
58 }
59 }
60
61 private def saveBestSolutionOnly(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
62 val fitness = context.lastFitness
63 if (!shouldSaveSolution(fitness, context)) {
64 return false
65 }
66 println("Found: " + fitness)
67 val dominatedTrajectories = newArrayList
68 for (entry : trajectories.entrySet) {
69 val isLastFitnessBetter = comparatorHelper.compare(fitness, entry.value)
70 if (isLastFitnessBetter < 0) {
71 // Found a trajectory that dominates the current one, no need to save
72 return false
73 }
74 if (isLastFitnessBetter > 0) {
75 dominatedTrajectories += entry.key
76 }
77 }
78 if (dominatedTrajectories.size == 0 && !needsMoreSolutionsWithSameFitness) {
79 return false
80 }
81 if (!diversityChecker.newSolution(context, id, dominatedTrajectories.map[solution.stateCode])) {
82 return false
83 }
84 // We must save the new trajectory before removing dominated trajectories
85 // to avoid removing the current solution when it is reachable only via dominated trajectories.
86 val solutionSaved = basicSaveSolution(context, id, solutionTrajectory, fitness)
87 for (dominatedTrajectory : dominatedTrajectories) {
88 trajectories -= dominatedTrajectory
89 val dominatedSolution = dominatedTrajectory.solution
90 if (!dominatedSolution.trajectories.remove(dominatedTrajectory)) {
91 throw new DSEException(
92 "Dominated solution is not reachable from dominated trajectory. This should never happen!")
93 }
94 if (dominatedSolution.trajectories.empty) {
95 val dominatedSolutionId = dominatedSolution.stateCode
96 solutionCopier.markAsObsolete(dominatedSolutionId)
97 solutionsCollection -= dominatedSolutionId
98 }
99 }
100 solutionSaved
101 }
102
103 private def saveAnyDiverseSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
104 val fitness = context.lastFitness
105 if (!shouldSaveSolution(fitness, context)) {
106 return false
107 }
108 if (!diversityChecker.newSolution(context, id, emptyList)) {
109 return false
110 }
111 basicSaveSolution(context, id, solutionTrajectory, fitness)
112 }
113
114 private def shouldSaveSolution(Fitness fitness, ThreadContext context) {
115 fitness.satisifiesHardObjectives && (numericSolver === null || numericSolver.currentSatisfiable)
116 }
117
118 private def basicSaveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory,
119 Fitness fitness) {
120 var boolean solutionSaved = false
121 var dseSolution = solutionsCollection.get(id)
122 if (dseSolution === null) {
123 solutionCopier.copySolution(context, id)
124 dseSolution = new Solution(id, solutionTrajectory)
125 solutionsCollection.put(id, dseSolution)
126 solutionSaved = true
127 } else {
128 solutionSaved = dseSolution.trajectories.add(solutionTrajectory)
129 }
130 if (solutionSaved) {
131 solutionTrajectory.solution = dseSolution
132 trajectories.put(solutionTrajectory, fitness)
133 }
134 solutionSaved
135 }
136
137 def fitnessMayBeSaved(Fitness fitness) {
138 if (!hasExtremalObjectives) {
139 return true
140 }
141 var boolean mayDominate
142 for (existingFitness : trajectories.values) {
143 val isNewFitnessBetter = comparatorHelper.compare(fitness, existingFitness)
144 if (isNewFitnessBetter < 0) {
145 return false
146 }
147 if (isNewFitnessBetter > 0) {
148 mayDominate = true
149 }
150 }
151 mayDominate || needsMoreSolutionsWithSameFitness
152 }
153
154 private def boolean needsMoreSolutionsWithSameFitness() {
155 if (solutionsCollection === null) {
156 // The solutions collection will only be initialized upon saving the first solution.
157 return true
158 }
159 solutionsCollection.size < numberOfRequiredSolutions
160 }
161
162 def getTotalCopierRuntime() {
163 solutionCopier.totalCopierRuntime
164 }
165
166 override computeRequiredBounds(IObjective objective, Bounds bounds) {
167 if (!hasExtremalObjectives) {
168 return
169 }
170 if (objective instanceof DirectionalThresholdObjective) {
171 switch (threshold : objective.threshold) {
172 case ObjectiveThreshold.NO_THRESHOLD: {
173 // No threshold to set.
174 }
175 ObjectiveThreshold.Exclusive: {
176 switch (kind : objective.kind) {
177 case HIGHER_IS_BETTER:
178 bounds.tightenLowerBound(Math.floor(threshold.threshold + 1) as int)
179 case LOWER_IS_BETTER:
180 bounds.tightenUpperBound(Math.ceil(threshold.threshold - 1) as int)
181 default:
182 throw new IllegalArgumentException("Unknown objective kind" + kind)
183 }
184 if (threshold.clampToThreshold) {
185 return
186 }
187 }
188 ObjectiveThreshold.Inclusive: {
189 switch (kind : objective.kind) {
190 case HIGHER_IS_BETTER:
191 bounds.tightenLowerBound(Math.ceil(threshold.threshold) as int)
192 case LOWER_IS_BETTER:
193 bounds.tightenUpperBound(Math.floor(threshold.threshold) as int)
194 default:
195 throw new IllegalArgumentException("Unknown objective kind" + kind)
196 }
197 if (threshold.clampToThreshold) {
198 return
199 }
200 }
201 default:
202 throw new IllegalArgumentException("Unknown threshold: " + threshold)
203 }
204 for (level : leveledExtremalObjectives) {
205 switch (level.size) {
206 case 0: {
207 // Nothing to do, wait for the next level.
208 }
209 case 1: {
210 val primaryObjective = level.get(0)
211 if (primaryObjective != objective) {
212 // There are no worst-case bounds for secondary objectives.
213 return
214 }
215 }
216 default:
217 // There are no worst-case bounds for Pareto front calculation.
218 return
219 }
220 }
221 val fitnessIterator = trajectories.values.iterator
222 if (!fitnessIterator.hasNext) {
223 return
224 }
225 val fitness = fitnessIterator.next.get(objective.name)
226 while (fitnessIterator.hasNext) {
227 val otherFitness = fitnessIterator.next.get(objective.name)
228 if (Math.abs(fitness - otherFitness) > TOLERANCE) {
229 throw new IllegalStateException("Inconsistent fitness: " + objective.name)
230 }
231 }
232 switch (kind : objective.kind) {
233 case HIGHER_IS_BETTER:
234 if (needsMoreSolutionsWithSameFitness) {
235 bounds.tightenLowerBound(Math.floor(fitness) as int)
236 } else {
237 bounds.tightenLowerBound(Math.floor(fitness + 1) as int)
238 }
239 case LOWER_IS_BETTER:
240 if (needsMoreSolutionsWithSameFitness) {
241 bounds.tightenUpperBound(Math.ceil(fitness) as int)
242 } else {
243 bounds.tightenUpperBound(Math.ceil(fitness - 1) as int)
244 }
245 default:
246 throw new IllegalArgumentException("Unknown objective kind" + kind)
247 }
248 }
249 }
250}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend
index 5a528a9e..6d772f32 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend
@@ -1,5 +1,6 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import com.google.common.collect.ImmutableList
3import java.util.ArrayList 4import java.util.ArrayList
4import java.util.Collection 5import java.util.Collection
5import org.eclipse.viatra.dse.objectives.Comparators 6import org.eclipse.viatra.dse.objectives.Comparators
@@ -12,25 +13,33 @@ import org.eclipse.viatra.query.runtime.api.IQuerySpecification
12import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher 13import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
13 14
14class WF2ObjectiveConverter { 15class WF2ObjectiveConverter {
15 16 static val INVALIDATED_WFS_NAME = "invalidatedWFs"
17
16 def createCompletenessObjective( 18 def createCompletenessObjective(
17 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWF) 19 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWF) {
18 { 20 new UnfinishedWFObjective(unfinishedWF)
19 val res = new ConstraintsObjective('''unfinishedWFs''', 21 }
20 unfinishedWF.map[ 22
21 new QueryConstraint(it.fullyQualifiedName,it,2.0) 23 def createInvalidationObjective(
22 ].toList 24 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidatedByWF) {
25 createConstraintObjective(INVALIDATED_WFS_NAME, invalidatedByWF)
26 }
27
28 def IGlobalConstraint createInvalidationGlobalConstraint(
29 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidatedByWF) {
30 new ModelQueriesGlobalConstraint(INVALIDATED_WFS_NAME, new ArrayList(invalidatedByWF))
31 }
32
33 private def createConstraintObjective(String name,
34 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> queries) {
35 val res = new ConstraintsObjective(
36 name,
37 ImmutableList.copyOf(queries.map [
38 new QueryConstraint(it.fullyQualifiedName, it, 1.0)
39 ])
23 ) 40 )
24 res.withComparator(Comparators.LOWER_IS_BETTER) 41 res.withComparator(Comparators.LOWER_IS_BETTER)
25 res.level = 2 42 res.level = 2
26 return res 43 res
27 }
28
29 def IGlobalConstraint createInvalidationObjective(
30 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidatedByWF)
31 {
32 return new ModelQueriesGlobalConstraint('''invalidatedWFs''',
33 new ArrayList(invalidatedByWF)
34 )
35 } 44 }
36} \ No newline at end of file 45}
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
new file mode 100644
index 00000000..cd911ab5
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend
@@ -0,0 +1,35 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import org.eclipse.viatra.dse.base.ThreadContext
4
5abstract class AbstractThreeValuedObjective extends DirectionalThresholdObjective implements IThreeValuedObjective {
6 protected new(String name, ObjectiveKind kind, ObjectiveThreshold threshold, int level) {
7 super(name, kind, threshold, level)
8 }
9
10 abstract def double getLowestPossibleFitness(ThreadContext threadContext)
11
12 abstract def double getHighestPossibleFitness(ThreadContext threadContext)
13
14 override getWorstPossibleFitness(ThreadContext threadContext) {
15 switch (kind) {
16 case LOWER_IS_BETTER:
17 getHighestPossibleFitness(threadContext)
18 case HIGHER_IS_BETTER:
19 getLowestPossibleFitness(threadContext)
20 default:
21 throw new IllegalStateException("Unknown three valued objective kind: " + kind)
22 }
23 }
24
25 override getBestPossibleFitness(ThreadContext threadContext) {
26 switch (kind) {
27 case LOWER_IS_BETTER:
28 getLowestPossibleFitness(threadContext)
29 case HIGHER_IS_BETTER:
30 getHighestPossibleFitness(threadContext)
31 default:
32 throw new IllegalStateException("Unknown three valued objective kind: " + kind)
33 }
34 }
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 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import com.google.common.collect.ImmutableList
4import java.util.Collection
5import org.eclipse.viatra.dse.base.ThreadContext
6
7class 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/CostElementMatchers.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostElementMatchers.xtend
new file mode 100644
index 00000000..885b14e8
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostElementMatchers.xtend
@@ -0,0 +1,137 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import com.google.common.collect.ImmutableList
4import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicproblemPackage
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage
6import java.util.List
7import org.eclipse.emf.ecore.EObject
8import org.eclipse.viatra.query.runtime.api.IPatternMatch
9import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
10import org.eclipse.xtend.lib.annotations.Data
11import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
12import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
13
14@FunctionalInterface
15interface ParameterScopeBound {
16 def double getUpperBound()
17}
18
19@Data
20class CostElementMatch {
21 val IPatternMatch match
22 val boolean must
23
24 def isMulti() {
25 CostElementMatchers.isMultiMatch(match)
26 }
27}
28
29@Data
30class CostElementMatchers {
31 val ViatraQueryMatcher<? extends IPatternMatch> currentMatcher
32 val ViatraQueryMatcher<? extends IPatternMatch> mayMatcher
33 val ViatraQueryMatcher<? extends IPatternMatch> mustMatcher
34 val List<ParameterScopeBound> parameterScopeBounds
35 val int weight
36
37 def getCurrentNumberOfMatches() {
38 currentMatcher.countMatches
39 }
40
41 def getMinimumNumberOfMatches() {
42 mustMatcher.countMatches
43 }
44
45 def getMaximumNumberOfMatches() {
46 var double sum = 0
47 val iterator = mayMatcher.streamAllMatches.iterator
48 while (iterator.hasNext) {
49 val match = iterator.next
50 var double product = 1
51 val numberOfParameters = parameterScopeBounds.size
52 for (var int i = 0; i < numberOfParameters; i++) {
53 if (isMulti(match.get(i + 2))) {
54 val scopeBound = parameterScopeBounds.get(i)
55 product *= scopeBound.upperBound
56 }
57
58 }
59 sum += product
60 }
61 sum
62 }
63
64 def getMatches() {
65 ImmutableList.copyOf(mayMatcher.streamAllMatches.iterator.map [ match |
66 new CostElementMatch(match, mustMatcher.isMatch(match))
67 ])
68 }
69
70 def projectMayMatch(IPatternMatch match, int... indices) {
71 mayMatcher.projectMatch(match, indices)
72 }
73
74 private static def <T extends IPatternMatch> projectMatch(ViatraQueryMatcher<T> matcher, IPatternMatch match, int... indices) {
75 checkMatch(match)
76 val n = matcher.specification.parameters.length - 2
77 if (indices.length != n) {
78 throw new IllegalArgumentException("Invalid number of projection indices")
79 }
80 val newMatch = matcher.newEmptyMatch
81 newMatch.set(0, match.get(0))
82 newMatch.set(1, match.get(1))
83 for (var int i = 0; i < n; i++) {
84 newMatch.set(i + 2, match.get(indices.get(i)))
85 }
86 if (!matcher.hasMatch(newMatch)) {
87 throw new IllegalArgumentException("Projected match does not exist")
88 }
89 return newMatch
90 }
91
92 private static def <T extends IPatternMatch> isMatch(ViatraQueryMatcher<T> matcher, IPatternMatch match) {
93 val n = matcher.specification.parameters.length
94 if (n != match.specification.parameters.length) {
95 throw new IllegalArgumentException("Invalid number of match arguments")
96 }
97 val newMatch = matcher.newEmptyMatch
98 for (var int i = 0; i < n; i++) {
99 newMatch.set(i, match.get(i))
100 }
101 return matcher.hasMatch(newMatch)
102 }
103
104 static def isMulti(Object o) {
105 if (o instanceof EObject) {
106 switch (feature : o.eContainmentFeature) {
107 case LogicproblemPackage.eINSTANCE.logicProblem_Elements,
108 case PartialinterpretationPackage.eINSTANCE.partialInterpretation_NewElements:
109 false
110 case PartialinterpretationPackage.eINSTANCE.partialInterpretation_OpenWorldElements:
111 true
112 default:
113 throw new IllegalStateException("Unknown containment feature for element: " + feature)
114 }
115 } else {
116 false
117 }
118 }
119
120 static def isMultiMatch(IPatternMatch match) {
121 checkMatch(match)
122 val n = match.specification.parameters.length
123 for (var int i = 2; i < n; i++) {
124 if (isMulti(match.get(i))) {
125 return true
126 }
127 }
128 false
129 }
130
131 private static def checkMatch(IPatternMatch match) {
132 val n = match.specification.parameters.length
133 if (n < 2 || !(match.get(0) instanceof LogicProblem) || !(match.get(1) instanceof PartialInterpretation)) {
134 throw new IllegalArgumentException("Match is not from the partial interpretation")
135 }
136 }
137}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostObjectiveHint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostObjectiveHint.xtend
new file mode 100644
index 00000000..2434073d
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostObjectiveHint.xtend
@@ -0,0 +1,68 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.BoundSaturationListener
4import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ExtendedLinearExpressionBuilder
5import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeConstraintHint
6import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeExpressionBuilderFactory
7import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedronExtensionOperator
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.PatternGenerator
9import java.util.Map
10import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
11import org.eclipse.xtend.lib.annotations.Accessors
12
13abstract class CostObjectiveHint implements LinearTypeConstraintHint, BoundSaturationListener {
14 @Accessors ThreeValuedCostObjective objective
15 @Accessors IObjectiveBoundsProvider boundsProvider
16
17 Integer bestUpper = null
18
19 override getAdditionalPatterns(PatternGenerator patternGenerator, Map<String, PQuery> fqnToPQuery) {
20 ''''''
21 }
22
23 override createConstraintUpdater(LinearTypeExpressionBuilderFactory builderFactory) {
24 null
25 }
26
27 def isExact() {
28 false
29 }
30
31 def PolyhedronExtensionOperator createPolyhedronExtensionOperator(
32 Map<String, CostElementMatchers> costElementMatchers) {
33 null
34 }
35
36 def setObjective(ThreeValuedCostObjective objective) {
37 if (this.objective !== null) {
38 throw new IllegalStateException("Objective was already set")
39 }
40 this.objective = objective
41 }
42
43 def setBoundsProvider(IObjectiveBoundsProvider boundsProvider) {
44 if (this.boundsProvider !== null) {
45 throw new IllegalStateException("Objective bounds provider was already set")
46 }
47 this.boundsProvider = boundsProvider
48 }
49
50 protected def buildWithBounds(ExtendedLinearExpressionBuilder builder) {
51 val bounds = builder.build(this)
52 if (objective !== null && boundsProvider !== null) {
53 boundsProvider.computeRequiredBounds(objective, bounds)
54 }
55 if (exact && bestUpper !== null) {
56 bounds.tightenLowerBound(bestUpper)
57 }
58 bounds
59 }
60
61 override boundsSaturated(Integer lower, Integer upper) {
62 if (upper !== null && (bestUpper === null || bestUpper < upper)) {
63 bestUpper = upper
64 }
65 objective?.boundsSaturated(lower, upper)
66 }
67
68}
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 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import java.util.Comparator
4import org.eclipse.viatra.dse.base.ThreadContext
5import org.eclipse.viatra.dse.objectives.IObjective
6import org.eclipse.xtend.lib.annotations.Accessors
7import org.eclipse.xtend.lib.annotations.Data
8import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
9
10abstract 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
129abstract 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/IObjectiveBoundsProvider.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IObjectiveBoundsProvider.xtend
new file mode 100644
index 00000000..3c4d36a5
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IObjectiveBoundsProvider.xtend
@@ -0,0 +1,8 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.Bounds
4import org.eclipse.viatra.dse.objectives.IObjective
5
6interface IObjectiveBoundsProvider {
7 def void computeRequiredBounds(IObjective objective, Bounds bounds)
8}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IThreeValuedObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IThreeValuedObjective.xtend
new file mode 100644
index 00000000..4a870a3e
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IThreeValuedObjective.xtend
@@ -0,0 +1,10 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import org.eclipse.viatra.dse.base.ThreadContext
4import org.eclipse.viatra.dse.objectives.IObjective
5
6interface IThreeValuedObjective extends IObjective {
7 def Double getWorstPossibleFitness(ThreadContext threadContext)
8
9 def Double getBestPossibleFitness(ThreadContext threadContext)
10}
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 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import com.google.common.collect.ImmutableList
4import java.util.Collection
5import org.eclipse.viatra.dse.base.ThreadContext
6import org.eclipse.viatra.query.runtime.api.IPatternMatch
7import org.eclipse.viatra.query.runtime.api.IQuerySpecification
8import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
9import org.eclipse.xtend.lib.annotations.Data
10
11@Data
12class MatchCostElement {
13 val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification
14 val double weight
15}
16
17class 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
new file mode 100644
index 00000000..cbbaaafd
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java
@@ -0,0 +1,60 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization;
2
3import java.util.Comparator;
4
5import org.eclipse.viatra.dse.objectives.Comparators;
6
7public enum ObjectiveKind {
8 LOWER_IS_BETTER {
9
10 @Override
11 public Comparator<Double> getComparator() {
12 return Comparators.LOWER_IS_BETTER;
13 }
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
25 },
26 HIGHER_IS_BETTER {
27
28 @Override
29 public Comparator<Double> getComparator() {
30 return Comparators.HIGHER_IS_BETTER;
31 }
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
43 };
44
45 public abstract Comparator<Double> getComparator();
46
47 public abstract double getInvalidValue();
48
49 public abstract double getSatisfiedValue();
50
51 public static ObjectiveKind fromComparator(Comparator<Double> comparator) {
52 if (Comparators.LOWER_IS_BETTER.equals(comparator)) {
53 return ObjectiveKind.LOWER_IS_BETTER;
54 } else if (Comparators.HIGHER_IS_BETTER.equals(comparator)) {
55 return ObjectiveKind.HIGHER_IS_BETTER;
56 } else {
57 throw new IllegalStateException("Only LOWER_IS_BETTER and HIGHER_IS_BETTER comparators are supported.");
58 }
59 }
60}
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 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import org.eclipse.viatra.dse.base.ThreadContext
4import org.eclipse.viatra.query.runtime.api.IPatternMatch
5import org.eclipse.viatra.query.runtime.api.IQuerySpecification
6import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
7
8class 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
new file mode 100644
index 00000000..9b1a7e9f
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend
@@ -0,0 +1,80 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.BoundSaturationListener
4import java.util.Map
5import org.eclipse.viatra.dse.base.ThreadContext
6import org.eclipse.xtend.lib.annotations.Accessors
7
8class ThreeValuedCostObjective extends AbstractThreeValuedObjective implements BoundSaturationListener {
9 @Accessors val Map<String, CostElementMatchers> matchers
10 double lowerBoundHint = Double.NEGATIVE_INFINITY
11 double upperBoundHint = Double.POSITIVE_INFINITY
12
13 new(String name, Map<String, CostElementMatchers> matchers, ObjectiveKind kind, ObjectiveThreshold threshold,
14 int level) {
15 super(name, kind, threshold, level)
16 this.matchers = matchers
17 }
18
19 override createNew() {
20 // new ThreeValuedCostObjective(name, matchers, kind, threshold, level)
21 throw new UnsupportedOperationException("ThreeValuedCostObjective can only be used from a single thread")
22 }
23
24 override init(ThreadContext context) {
25 }
26
27 override getRawFitness(ThreadContext context) {
28 var double cost = 0
29 for (matcher : matchers.values) {
30 cost += matcher.weight * matcher.currentNumberOfMatches
31 }
32 cost
33 }
34
35 override getLowestPossibleFitness(ThreadContext threadContext) {
36 var double cost = 0
37 for (matcher : matchers.values) {
38 if (matcher.weight >= 0) {
39 cost += matcher.weight * matcher.minimumNumberOfMatches
40 } else {
41 cost += matcher.weight * matcher.maximumNumberOfMatches
42 }
43 }
44 val boundWithHint = Math.max(lowerBoundHint, cost)
45 if (boundWithHint > upperBoundHint) {
46 throw new IllegalStateException("Inconsistent cost bounds")
47 }
48 boundWithHint
49 }
50
51 override getHighestPossibleFitness(ThreadContext threadContext) {
52 var double cost = 0
53 for (matcher : matchers.values) {
54 if (matcher.weight <= 0) {
55 cost += matcher.weight * matcher.minimumNumberOfMatches
56 } else {
57 cost += matcher.weight * matcher.maximumNumberOfMatches
58 }
59 }
60 val boundWithHint = Math.min(upperBoundHint, cost)
61 if (boundWithHint < lowerBoundHint) {
62 throw new IllegalStateException("Inconsistent cost bounds")
63 }
64 boundWithHint
65 }
66
67 override boundsSaturated(Integer lower, Integer upper) {
68 lowerBoundHint = if (lower === null) {
69 Double.NEGATIVE_INFINITY
70 } else {
71 lower
72 }
73 upperBoundHint = if (upper === null) {
74 Double.POSITIVE_INFINITY
75 } else {
76 upper
77 }
78 println('''Bounds saturated: «lower»..«upper»''')
79 }
80}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjectiveProvider.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjectiveProvider.xtend
new file mode 100644
index 00000000..c2750acd
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjectiveProvider.xtend
@@ -0,0 +1,205 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import com.google.common.collect.ImmutableList
4import com.google.common.collect.ImmutableMap
5import com.google.common.collect.Lists
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference
7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference
8import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntTypeReference
9import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference
10import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
11import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.StringTypeReference
12import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration
13import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeReference
14import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.TransfomedViatraQuery
15import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedronExtensionOperator
16import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.ModalPatternQueries
17import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialBooleanInterpretation
18import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
19import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialIntegerInterpretation
20import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
21import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRealInterpretation
22import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialStringInterpretation
23import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope
24import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.CostObjectiveConfiguration
25import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.CostObjectiveElementConfiguration
26import java.util.Collection
27import java.util.Map
28import org.eclipse.viatra.dse.objectives.IObjective
29import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
30import org.eclipse.xtend.lib.annotations.Data
31
32@Data
33class ThreeValuedCostObjectiveProviderResult {
34 val Collection<IObjective> objectives
35 val Collection<CostObjectiveHint> hints
36 val Collection<PolyhedronExtensionOperator> extensionOperators
37 val IObjective[][] leveledExtremalObjectives
38 val boolean optimizationProblem
39}
40
41class ThreeValuedCostObjectiveProvider {
42 static val COST_OBJECTIVE_LEVEL = 3
43
44 val ViatraQueryEngine queryEngine
45 val Map<String, ModalPatternQueries> modalRelationQueries
46 val Map<String, Relation> qualifiedNameToRelationMap
47 val ParameterScopeBound defaultBounds
48 val ParameterScopeBound booleanBounds
49 val ParameterScopeBound integerBounds
50 val ParameterScopeBound realBounds
51 val ParameterScopeBound stringBounds
52 val Map<TypeDeclaration, ParameterScopeBound> typeDeclarationToBoundsMap
53
54 new(ViatraQueryEngine queryEngine, PartialInterpretation interpretation,
55 Map<String, ModalPatternQueries> modalRelationQueries) {
56 this.queryEngine = queryEngine
57 this.modalRelationQueries = modalRelationQueries
58 qualifiedNameToRelationMap = ImmutableMap.copyOf(
59 interpretation.problem.annotations.filter(TransfomedViatraQuery).
60 toMap([patternFullyQualifiedName], [target]))
61 defaultBounds = new PartialInterpretationBasedParameterScopeBound(interpretation)
62 var ParameterScopeBound booleanBounds = null
63 var ParameterScopeBound integerBounds = null
64 var ParameterScopeBound realBounds = null
65 var ParameterScopeBound stringBounds = null
66 val typeDeclarationToBoundsMapBuilder = ImmutableMap.builder
67 for (scope : interpretation.scopes) {
68 val bounds = new ScopeBasedParameterScopeBound(scope)
69 switch (typeInterpretation : scope.targetTypeInterpretation) {
70 PartialBooleanInterpretation:
71 if (booleanBounds === null) {
72 booleanBounds = bounds
73 } else {
74 throw new IllegalStateException("Duplicate partial boolean interpretation")
75 }
76 PartialIntegerInterpretation:
77 if (integerBounds === null) {
78 integerBounds = bounds
79 } else {
80 throw new IllegalStateException("Duplicate partial integer interpretation")
81 }
82 PartialRealInterpretation:
83 if (realBounds === null) {
84 realBounds = bounds
85 } else {
86 throw new IllegalStateException("Duplicate partial real interpretation")
87 }
88 PartialStringInterpretation:
89 if (stringBounds === null) {
90 stringBounds = bounds
91 } else {
92 throw new IllegalStateException("Duplicate partial string interpretation")
93 }
94 PartialComplexTypeInterpretation:
95 typeDeclarationToBoundsMapBuilder.put(typeInterpretation.interpretationOf, bounds)
96 }
97 }
98 this.booleanBounds = booleanBounds ?: defaultBounds
99 this.integerBounds = integerBounds ?: defaultBounds
100 this.realBounds = realBounds ?: defaultBounds
101 this.stringBounds = stringBounds ?: defaultBounds
102 typeDeclarationToBoundsMap = typeDeclarationToBoundsMapBuilder.build
103 }
104
105 def getCostObjectives(Collection<CostObjectiveConfiguration> costObjectives) {
106 val objectives = ImmutableList.<IObjective>builder
107 val hints = ImmutableList.<CostObjectiveHint>builder
108 val extensionOperators = ImmutableList.<PolyhedronExtensionOperator>builder
109 val extremalObjectives = Lists.newArrayListWithExpectedSize(costObjectives.size)
110 for (entry : costObjectives.indexed) {
111 val objectiveName = '''costObjective«entry.key»'''
112 val objectiveConfig = entry.value
113 val costObjective = transformCostObjective(objectiveConfig, objectiveName)
114 objectives.add(costObjective)
115 if (objectiveConfig.findExtremum) {
116 extremalObjectives += costObjective
117 }
118 val hint = objectiveConfig.hint
119 if (hint !== null) {
120 hints.add(hint)
121 hint.objective = costObjective
122 val extensionOperator = hint.createPolyhedronExtensionOperator(costObjective.matchers)
123 if (extensionOperator !== null) {
124 extensionOperators.add(extensionOperator)
125 }
126 }
127 }
128 new ThreeValuedCostObjectiveProviderResult(
129 objectives.build,
130 hints.build,
131 extensionOperators.build,
132 newArrayList(extremalObjectives),
133 !extremalObjectives.empty
134 )
135 }
136
137 private def transformCostObjective(CostObjectiveConfiguration configuration, String name) {
138 val costElements = ImmutableMap.copyOf(configuration.elements.toMap([patternQualifiedName], [
139 transformCostElement
140 ]))
141 new ThreeValuedCostObjective(name, costElements, configuration.kind, configuration.threshold,
142 COST_OBJECTIVE_LEVEL)
143 }
144
145 private def transformCostElement(CostObjectiveElementConfiguration elementConfig) {
146 val relationName = elementConfig.patternQualifiedName
147 val modalQueries = modalRelationQueries.get(relationName)
148 if (modalQueries === null) {
149 throw new IllegalArgumentException("Unknown relation queries: " + relationName)
150 }
151 val relation = qualifiedNameToRelationMap.get(relationName)
152 if (relation === null) {
153 throw new IllegalArgumentException("Unknown transformed relation: " + relationName)
154 }
155 val parameterBounds = ImmutableList.copyOf(relation.parameters.map[parameterBound])
156 new CostElementMatchers(
157 queryEngine.getMatcher(modalQueries.currentQuery),
158 queryEngine.getMatcher(modalQueries.mayQuery),
159 queryEngine.getMatcher(modalQueries.mustQuery),
160 parameterBounds,
161 elementConfig.weight
162 )
163 }
164
165 private def getParameterBound(TypeReference typeReference) {
166 switch (typeReference) {
167 BoolTypeReference: booleanBounds
168 IntTypeReference: integerBounds
169 RealTypeReference: realBounds
170 StringTypeReference: stringBounds
171 ComplexTypeReference: typeDeclarationToBoundsMap.getOrDefault(typeReference.referred, defaultBounds)
172 }
173 }
174
175 private static abstract class AbstractParameterScopeBound implements ParameterScopeBound {
176 override getUpperBound() {
177 val rawValue = rawUpperBound
178 if (rawValue < 0) {
179 Double.POSITIVE_INFINITY
180 } else {
181 rawValue
182 }
183 }
184
185 protected def int getRawUpperBound()
186 }
187
188 @Data
189 private static class ScopeBasedParameterScopeBound extends AbstractParameterScopeBound {
190 val Scope scope
191
192 override protected getRawUpperBound() {
193 scope.maxNewElements
194 }
195 }
196
197 @Data
198 private static class PartialInterpretationBasedParameterScopeBound extends AbstractParameterScopeBound {
199 val PartialInterpretation interpretation
200
201 override protected getRawUpperBound() {
202 interpretation.maxNewElements
203 }
204 }
205}