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:33:58 -0500
committerLibravatar 20001LastOrder <boqi.chen@mail.mcgill.ca>2020-11-04 01:33:58 -0500
commita20af4d0dbf5eab84ee271d426528aabb5a8ac3b (patch)
treea9ab772ee313125aaf3a941d66e131b408d949ba /Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver
parentchanges in settings of measurements (diff)
parentmerge with current master, comment numerical solver related logging (diff)
downloadVIATRA-Generator-a20af4d0dbf5eab84ee271d426528aabb5a8ac3b.tar.gz
VIATRA-Generator-a20af4d0dbf5eab84ee271d426528aabb5a8ac3b.tar.zst
VIATRA-Generator-a20af4d0dbf5eab84ee271d426528aabb5a8ac3b.zip
fix merging issue
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.xtend331
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend96
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ActivationSelector.xtend24
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BalancedActivationSelector.xtend51
-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.java207
-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/EvenActivationSelector.xtend20
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java1000
-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.xtend130
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend192
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend67
-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.xtend9
-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.xtend18
-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
39 files changed, 3418 insertions, 914 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 4331420d..4d2fd741 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
@@ -10,20 +10,28 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
10import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicproblemPackage 10import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicproblemPackage
11import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicresultFactory 11import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicresultFactory
12import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult 12import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult
13import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethodProvider
14import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator 13import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator
14import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy
15import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser 15import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser
16import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 16import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
17import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage 17import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage
18import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.AbstractNeighbourhoodBasedStateCoderFactory
18import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory 19import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory
19import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedStateCoderFactory 20import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedHashStateCoderFactory
21import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.PairwiseNeighbourhoodBasedStateCoderFactory
22import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BasicScopeGlobalConstraint
20import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.HillClimbingOnRealisticMetricStrategyForModelGeneration 23import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.HillClimbingOnRealisticMetricStrategyForModelGeneration
24import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.InconsistentScopeGlobalConstraint
25import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.LoggerSolutionFoundHandler
21import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ModelGenerationCompositeObjective 26import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ModelGenerationCompositeObjective
27import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.NumericSolver
22import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PartialModelAsLogicInterpretation 28import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PartialModelAsLogicInterpretation
29import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PunishSizeObjective
23import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ScopeObjective 30import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ScopeObjective
31import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.SurelyViolatedObjectiveGlobalConstraint
24import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.UnfinishedMultiplicityObjective 32import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.UnfinishedMultiplicityObjective
25import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.UnfinishedWFObjective
26import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.WF2ObjectiveConverter 33import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.WF2ObjectiveConverter
34import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveKind
27import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace 35import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace
28import java.util.List 36import java.util.List
29import java.util.Map 37import java.util.Map
@@ -34,193 +42,320 @@ import org.eclipse.viatra.dse.api.DesignSpaceExplorer.DseLoggingLevel
34import org.eclipse.viatra.dse.solutionstore.SolutionStore 42import org.eclipse.viatra.dse.solutionstore.SolutionStore
35import org.eclipse.viatra.dse.statecode.IStateCoderFactory 43import org.eclipse.viatra.dse.statecode.IStateCoderFactory
36 44
37class ViatraReasoner extends LogicReasoner{ 45class ViatraReasoner extends LogicReasoner {
38 val PartialInterpretationInitialiser initialiser = new PartialInterpretationInitialiser() 46 val PartialInterpretationInitialiser initialiser = new PartialInterpretationInitialiser()
39 val ModelGenerationMethodProvider modelGenerationMethodProvider = new ModelGenerationMethodProvider 47 val ModelGenerationMethodProvider modelGenerationMethodProvider = new ModelGenerationMethodProvider
40 val extension LogicresultFactory factory = LogicresultFactory.eINSTANCE 48 val extension LogicresultFactory factory = LogicresultFactory.eINSTANCE
41 val WF2ObjectiveConverter wf2ObjectiveConverter = new WF2ObjectiveConverter 49 val WF2ObjectiveConverter wf2ObjectiveConverter = new WF2ObjectiveConverter
42 50
43 51 override solve(LogicProblem problem, LogicSolverConfiguration configuration,
44 override solve(LogicProblem problem, LogicSolverConfiguration configuration, ReasonerWorkspace workspace) throws LogicReasonerException { 52 ReasonerWorkspace workspace) throws LogicReasonerException {
45 val viatraConfig = configuration.asConfig 53 val viatraConfig = configuration.asConfig
46 54
47 if(viatraConfig.debugCongiguration.logging) { 55 if (viatraConfig.documentationLevel == DocumentationLevel.FULL) {
48 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.VERBOSE_FULL) 56 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.VERBOSE_FULL)
49 } else { 57 } else {
50 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.WARN) 58 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.WARN)
51 } 59 }
52 60
53 val DesignSpaceExplorer dse = new DesignSpaceExplorer(); 61 val DesignSpaceExplorer dse = new DesignSpaceExplorer();
54 62
55 dse.addMetaModelPackage(LogiclanguagePackage.eINSTANCE) 63 dse.addMetaModelPackage(LogiclanguagePackage.eINSTANCE)
56 dse.addMetaModelPackage(LogicproblemPackage.eINSTANCE) 64 dse.addMetaModelPackage(LogicproblemPackage.eINSTANCE)
57 dse.addMetaModelPackage(PartialinterpretationPackage.eINSTANCE) 65 dse.addMetaModelPackage(PartialinterpretationPackage.eINSTANCE)
58 66
59 val transformationStartTime = System.nanoTime 67 val transformationStartTime = System.nanoTime
60 68 val emptySolution = initialiser.initialisePartialInterpretation(problem, viatraConfig.typeScopes).output
61 69 if ((viatraConfig.documentationLevel == DocumentationLevel::FULL ||
62 70 viatraConfig.documentationLevel == DocumentationLevel::NORMAL) && workspace !== null) {
63 val emptySolution = initialiser.initialisePartialInterpretation(problem,viatraConfig.typeScopes).output 71 workspace.writeModel(emptySolution, "init.partialmodel")
64 72 }
65 if((viatraConfig.documentationLevel == DocumentationLevel::FULL || viatraConfig.documentationLevel == DocumentationLevel::NORMAL) && workspace !== null) { 73
66 workspace.writeModel(emptySolution,"init.partialmodel")
67 }
68 emptySolution.problemConainer = problem 74 emptySolution.problemConainer = problem
69 val emptySolutionCopy = EcoreUtil.copy(emptySolution) 75 val emptySolutionCopy = EcoreUtil.copy(emptySolution)
76
70 val ScopePropagator scopePropagator = new ScopePropagator(emptySolution) 77 val ScopePropagator scopePropagator = new ScopePropagator(emptySolution)
71 scopePropagator.propagateAllScopeConstraints 78 scopePropagator.propagateAllScopeConstraints
72 79
80 var BasicScopeGlobalConstraint basicScopeGlobalConstraint = null
81 if (viatraConfig.scopePropagatorStrategy == ScopePropagatorStrategy.None) {
82 basicScopeGlobalConstraint = new BasicScopeGlobalConstraint(emptySolution)
83 emptySolution.scopes.clear
84 }
85
73 val method = modelGenerationMethodProvider.createModelGenerationMethod( 86 val method = modelGenerationMethodProvider.createModelGenerationMethod(
74 problem, 87 problem,
75 emptySolution, 88 emptySolution,
76 workspace, 89 workspace,
77 viatraConfig.nameNewElements, 90 viatraConfig
78 viatraConfig.typeInferenceMethod,
79 scopePropagator,
80 viatraConfig.documentationLevel
81 ) 91 )
82 92
83 dse.addObjective(new ModelGenerationCompositeObjective( 93 val compositeObjective = new ModelGenerationCompositeObjective(
84 new ScopeObjective, 94 basicScopeGlobalConstraint ?: new ScopeObjective,
85 method.unfinishedMultiplicities.map[new UnfinishedMultiplicityObjective(it)], 95 method.unfinishedMultiplicities.map[new UnfinishedMultiplicityObjective(it)],
86 new UnfinishedWFObjective(method.unfinishedWF), 96 wf2ObjectiveConverter.createCompletenessObjective(method.unfinishedWF),
87 viatraConfig.isWFOptional 97 viatraConfig
88 )) 98 )
99 dse.addObjective(compositeObjective)
100 if (viatraConfig.punishSize != PunishSizeStrategy.NONE) {
101 val punishSizeStrategy = switch (viatraConfig.punishSize) {
102 case SMALLER_IS_BETTER: ObjectiveKind.LOWER_IS_BETTER
103 case LARGER_IS_BETTER: ObjectiveKind.HIGHER_IS_BETTER
104 default: throw new IllegalArgumentException("Unknown PunishSizeStrategy: " + viatraConfig.punishSize)
105 }
106 val punishObjective = new PunishSizeObjective(punishSizeStrategy, compositeObjective.level + 1)
107 dse.addObjective(punishObjective)
108 }
89 109
90 dse.addGlobalConstraint(wf2ObjectiveConverter.createInvalidationObjective(method.invalidWF)) 110 for (costObjective : method.costObjectives) {
91 for(additionalConstraint : viatraConfig.searchSpaceConstraints.additionalGlobalConstraints) { 111 dse.addObjective(costObjective)
112 }
113 val numberOfRequiredSolutions = configuration.solutionScope.numberOfRequiredSolutions
114 val solutionStore = if (method.optimizationProblem) {
115 new SolutionStore()
116 } else {
117 new SolutionStore(numberOfRequiredSolutions)
118 }
119 solutionStore.registerSolutionFoundHandler(new LoggerSolutionFoundHandler(viatraConfig))
120 val numericSolver = new NumericSolver(method, viatraConfig.runIntermediateNumericalConsistencyChecks, false)
121 val solutionSaver = method.solutionSaver
122 solutionSaver.numericSolver = numericSolver
123 val solutionCopier = solutionSaver.solutionCopier
124 val diversityChecker = solutionSaver.diversityChecker
125 solutionStore.withSolutionSaver(solutionSaver)
126 dse.solutionStore = solutionStore
127
128 dse.addGlobalConstraint(wf2ObjectiveConverter.createInvalidationGlobalConstraint(method.invalidWF))
129 dse.addGlobalConstraint(new SurelyViolatedObjectiveGlobalConstraint(solutionSaver))
130 dse.addGlobalConstraint(new InconsistentScopeGlobalConstraint)
131 if (basicScopeGlobalConstraint !== null) {
132 dse.addGlobalConstraint(basicScopeGlobalConstraint)
133 }
134 for (additionalConstraint : viatraConfig.searchSpaceConstraints.additionalGlobalConstraints) {
92 dse.addGlobalConstraint(additionalConstraint.apply(method)) 135 dse.addGlobalConstraint(additionalConstraint.apply(method))
93 } 136 }
94 137
95 dse.setInitialModel(emptySolution,false) 138 dse.setInitialModel(emptySolution, false)
96 139
97 val IStateCoderFactory statecoder = if(viatraConfig.stateCoderStrategy == StateCoderStrategy.Neighbourhood) { 140 val IStateCoderFactory statecoder = switch (viatraConfig.stateCoderStrategy) {
98 new NeighbourhoodBasedStateCoderFactory 141 case Neighbourhood:
99 } else { 142 new NeighbourhoodBasedHashStateCoderFactory
100 new IdentifierBasedStateCoderFactory 143 case PairwiseNeighbourhood:
144 new PairwiseNeighbourhoodBasedStateCoderFactory
145 default:
146 new IdentifierBasedStateCoderFactory
101 } 147 }
102 dse.stateCoderFactory = statecoder 148 dse.stateCoderFactory = statecoder
103 149
104 dse.maxNumberOfThreads = 1 150 dse.maxNumberOfThreads = 1
105 151
106 val solutionStore = new SolutionStore(configuration.solutionScope.numberOfRequiredSolution) 152 for (rule : method.relationRefinementRules) {
107 dse.solutionStore = solutionStore
108
109 for(rule : method.relationRefinementRules) {
110 dse.addTransformationRule(rule) 153 dse.addTransformationRule(rule)
111 } 154 }
112 for(rule : method.objectRefinementRules) { 155 for (rule : method.objectRefinementRules) {
113 dse.addTransformationRule(rule) 156 dse.addTransformationRule(rule)
114 } 157 }
115 158
116 val strategy = new HillClimbingOnRealisticMetricStrategyForModelGeneration(workspace,viatraConfig,method) 159 val strategy = new HillClimbingOnRealisticMetricStrategyForModelGeneration(workspace,viatraConfig,method)
117 viatraConfig.progressMonitor.workedForwardTransformation 160 viatraConfig.progressMonitor.workedForwardTransformation
118 161 val transformationFinished = System.nanoTime
119 val transformationTime = System.nanoTime - transformationStartTime 162 val transformationTime = transformationFinished - transformationStartTime
120 val solverStartTime = System.nanoTime 163 val solverStartTime = System.nanoTime
121 164
122 var boolean stoppedByTimeout 165 var boolean stoppedByTimeout
123 var boolean stoppedByException 166 try {
124 try{ 167 stoppedByTimeout = dse.startExplorationWithTimeout(strategy, configuration.runtimeLimit * 1000);
125 stoppedByTimeout = dse.startExplorationWithTimeout(strategy,configuration.runtimeLimit*1000);
126 stoppedByException = false
127 } catch (NullPointerException npe) { 168 } catch (NullPointerException npe) {
128 stoppedByTimeout = false 169 stoppedByTimeout = false
129 stoppedByException = true
130 } 170 }
131 val solverTime = System.nanoTime - solverStartTime 171 val solverTime = System.nanoTime - solverStartTime
132 viatraConfig.progressMonitor.workedSearchFinished 172 viatraConfig.progressMonitor.workedSearchFinished
133 173
134 //find trajectory to each solution 174 // additionalMatches = strategy.solutionStoreWithCopy.additionalMatches
135 if(viatraConfig.documentationLevel == DocumentationLevel.NONE){
136 PartialInterpretationMetric.initPaths();
137 //PartialInterpretationMetric.outputTrajectories(emptySolutionCopy, dse.solutions.toList());
138 }
139
140 //additionalMatches = strategy.solutionStoreWithCopy.additionalMatches
141 val statistics = createStatistics => [ 175 val statistics = createStatistics => [
142 //it.solverTime = viatraConfig.runtimeLimit 176 // it.solverTime = viatraConfig.runtimeLimit
143 it.solverTime = (solverTime/1000000) as int 177 it.solverTime = (solverTime / 1000000) as int
144 it.transformationTime = (transformationTime/1000000) as int 178 it.transformationTime = (transformationTime / 1000000) as int
145 for(x : 0..<strategy.solutionStoreWithCopy.allRuntimes.size) { 179 for (pair : solutionCopier.getAllCopierRuntimes(true).indexed) {
146 it.entries += createIntStatisticEntry => [ 180 it.entries += createIntStatisticEntry => [
147 it.name = '''_Solution«x»FoundAt''' 181 it.name = '''Solution«pair.key»FoundAt'''
148 it.value = (strategy.solutionStoreWithCopy.allRuntimes.get(x)/1000000) as int 182 it.value = (pair.value / 1000000) as int
149 ] 183 ]
150 } 184 }
185 for (x : 0 ..< strategy.times.size) {
186 it.entries += createStringStatisticEntry => [
187 it.name = '''Solution«x+1»DetailedStatistics'''
188 it.value = strategy.times.get(x)
189 ]
190 }
191 it.entries += createIntStatisticEntry => [
192 it.name = "ExplorationInitializationTime"
193 it.value = ((strategy.explorationStarted - transformationFinished) / 1000000) as int
194 ]
195 it.entries += createIntStatisticEntry => [
196 it.name = "TransformationExecutionTime"
197 it.value = (method.statistics.transformationExecutionTime / 1000000) as int
198 ]
199 it.entries += createIntStatisticEntry => [
200 it.name = "ScopePropagationTime"
201 it.value = (method.statistics.scopePropagationTime / 1000000) as int
202 ]
203 it.entries += createIntStatisticEntry => [
204 it.name = "MustRelationPropagationTime"
205 it.value = (method.statistics.mustRelationPropagationTime / 1000000) as int
206 ]
207 it.entries += createIntStatisticEntry => [
208 it.name = "TypeAnalysisTime"
209 it.value = (method.statistics.preliminaryTypeAnalisisTime / 1000000) as int
210 ]
211 it.entries += createIntStatisticEntry => [
212 it.name = "StateCoderTime"
213 it.value = (statecoder.runtime / 1000000) as int
214 ]
215 it.entries += createIntStatisticEntry => [
216 it.name = "StateCoderFailCount"
217 it.value = strategy.numberOfStatecoderFail
218 ]
151 it.entries += createIntStatisticEntry => [ 219 it.entries += createIntStatisticEntry => [
152 it.name = "TransformationExecutionTime" it.value = (method.statistics.transformationExecutionTime/1000000) as int 220 it.name = "SolutionCopyTime"
221 it.value = (solutionCopier.getTotalCopierRuntime / 1000000) as int
153 ] 222 ]
154 it.entries += createIntStatisticEntry => [ 223 it.entries += createIntStatisticEntry => [
155 it.name = "TypeAnalysisTime" it.value = (method.statistics.PreliminaryTypeAnalisisTime/1000000) as int 224 it.name = "States"
225 it.value = dse.numberOfStates as int
226 ]
227 it.entries += createIntStatisticEntry => [
228 it.name = "ForwardTime"
229 it.value = (strategy.forwardTime / 1000000) as int
230 ]
231 it.entries += createIntStatisticEntry => [
232 it.name = "BacktrackingTime"
233 it.value = (strategy.backtrackingTime / 1000000) as int
234 ]
235 it.entries += createIntStatisticEntry => [
236 it.name = "GlobalConstraintEvaluationTime"
237 it.value = (strategy.globalConstraintEvaluationTime / 1000000) as int
238 ]
239 it.entries += createIntStatisticEntry => [
240 it.name = "FitnessCalculationTime"
241 it.value = (strategy.fitnessCalculationTime / 1000000) as int
242 ]
243 it.entries += createIntStatisticEntry => [
244 it.name = "SolutionCopyTime"
245 it.value = (solutionSaver.totalCopierRuntime / 1000000) as int
246 ]
247 it.entries += createIntStatisticEntry => [
248 it.name = "ActivationSelectionTime"
249 it.value = (strategy.activationSelector.runtime / 1000000) as int
250 ]
251 it.entries += createIntStatisticEntry => [
252 it.name = "Decisions"
253 it.value = method.statistics.decisionsTried
156 ] 254 ]
157 it.entries += createIntStatisticEntry =>[ 255 it.entries += createIntStatisticEntry =>[
158 it.name = "MetricCalculationTime" it.value = (method.statistics.metricCalculationTime/1000000) as int 256 it.name = "MetricCalculationTime" it.value = (method.statistics.metricCalculationTime/1000000) as int
159 ] 257 ]
160 it.entries += createIntStatisticEntry => [ 258 it.entries += createIntStatisticEntry => [
161 it.name = "StateCoderTime" it.value = (statecoder.runtime/1000000) as int 259 it.name = "Transformations"
260 it.value = method.statistics.transformationInvocations
162 ] 261 ]
163 it.entries += createIntStatisticEntry => [ 262 it.entries += createIntStatisticEntry => [
164 it.name = "StateCoderFailCount" it.value = strategy.numberOfStatecoderFail 263 it.name = "ScopePropagations"
264 it.value = method.statistics.scopePropagatorInvocations
165 ] 265 ]
166 it.entries += createIntStatisticEntry => [ 266 it.entries += createIntStatisticEntry => [
167 it.name = "SolutionCopyTime" it.value = (strategy.solutionStoreWithCopy.sumRuntime/1000000) as int 267 it.name = "ScopePropagationsSolverCalls"
268 it.value = method.statistics.scopePropagatorSolverInvocations
168 ] 269 ]
169 if(strategy.solutionStoreWithDiversityDescriptor.isActive) { 270// it.entries += createIntStatisticEntry => [
271// it.name = "NumericalSolverSumTime"
272// it.value = (strategy.numericSolver.runtime / 1000000) as int
273// ]
274// it.entries += createIntStatisticEntry => [
275// it.name = "NumericalSolverProblemFormingTime"
276// it.value = (strategy.numericSolver.solverFormingProblem / 1000000) as int
277// ]
278// it.entries += createIntStatisticEntry => [
279// it.name = "NumericalSolverSolvingTime"
280// it.value = (strategy.numericSolver.solverSolvingProblem / 1000000) as int
281// ]
282// it.entries += createIntStatisticEntry => [
283// it.name = "NumericalSolverInterpretingSolution"
284// it.value = (strategy.numericSolver.solverSolution / 1000000) as int
285// ]
286// it.entries += createIntStatisticEntry => [
287// it.name = "NumericalSolverCachingTime"
288// it.value = (strategy.numericSolver.cachingTime / 1000000) as int
289// ]
290// it.entries += createIntStatisticEntry => [
291// it.name = "NumericalSolverCallNumber"
292// it.value = strategy.numericSolver.numberOfSolverCalls
293// ]
294// it.entries += createIntStatisticEntry => [
295// it.name = "NumericalSolverCachedAnswerNumber"
296// it.value = strategy.numericSolver.numberOfCachedSolverCalls
297// ]
298 if (diversityChecker.active) {
170 it.entries += createIntStatisticEntry => [ 299 it.entries += createIntStatisticEntry => [
171 it.name = "SolutionDiversityCheckTime" it.value = (strategy.solutionStoreWithDiversityDescriptor.sumRuntime/1000000) as int 300 it.name = "SolutionDiversityCheckTime"
301 it.value = (diversityChecker.totalRuntime / 1000000) as int
172 ] 302 ]
173 it.entries += createRealStatisticEntry => [ 303 it.entries += createRealStatisticEntry => [
174 it.name = "SolutionDiversitySuccessRate" it.value = strategy.solutionStoreWithDiversityDescriptor.successRate 304 it.name = "SolutionDiversitySuccessRate"
305 it.value = diversityChecker.successRate
175 ] 306 ]
176 } 307 }
177 ] 308 ]
178 309
179 viatraConfig.progressMonitor.workedBackwardTransformationFinished 310 viatraConfig.progressMonitor.workedBackwardTransformationFinished
180 311
181 if(stoppedByTimeout) { 312 if (stoppedByTimeout) {
182 return createInsuficientResourcesResult=>[ 313 return createInsuficientResourcesResult => [
183 it.problem = problem 314 it.problem = problem
184 it.resourceName="time" 315 it.resourceName = "time"
185 it.representation += strategy.solutionStoreWithCopy.solutions 316 it.representation += solutionCopier.getPartialInterpretations(true)
186 it.statistics = statistics 317 it.statistics = statistics
187 ] 318 ]
188 } else { 319 } else {
189 if(solutionStore.solutions.empty) { 320 if (solutionStore.solutions.empty) {
190 return createInconsistencyResult => [ 321 return createInconsistencyResult => [
191 it.problem = problem 322 it.problem = problem
192 it.representation += strategy.solutionStoreWithCopy.solutions 323 it.representation += solutionCopier.getPartialInterpretations(true)
193 it.statistics = statistics 324 it.statistics = statistics
194 ] 325 ]
195 } else { 326 } else {
196 return createModelResult => [ 327 return createModelResult => [
197 it.problem = problem 328 it.problem = problem
198 it.trace = strategy.solutionStoreWithCopy.copyTraces 329 it.trace = solutionCopier.getTraces(true)
199 it.representation += strategy.solutionStoreWithCopy.solutions 330 it.representation += solutionCopier.getPartialInterpretations(true)
200 it.statistics = statistics 331 it.statistics = statistics
201 ] 332 ]
202 } 333 }
203 } 334 }
204 } 335 }
205 336
206 private def dispatch long runtime(NeighbourhoodBasedStateCoderFactory sc) { 337 private def dispatch long runtime(AbstractNeighbourhoodBasedStateCoderFactory sc) {
207 sc.sumStatecoderRuntime 338 sc.sumStatecoderRuntime
208 } 339 }
209 340
210 private def dispatch long runtime(IdentifierBasedStateCoderFactory sc) { 341 private def dispatch long runtime(IdentifierBasedStateCoderFactory sc) {
211 sc.sumStatecoderRuntime 342 sc.sumStatecoderRuntime
212 } 343 }
213 344
214 override getInterpretations(ModelResult modelResult) { 345 override getInterpretations(ModelResult modelResult) {
215 val indexes = 0..<modelResult.representation.size 346 val indexes = 0 ..< modelResult.representation.size
216 val traces = modelResult.trace as List<Map<EObject, EObject>>; 347 val traces = modelResult.trace as List<Map<EObject, EObject>>;
217 val res = indexes.map[i | new PartialModelAsLogicInterpretation(modelResult.representation.get(i) as PartialInterpretation,traces.get(i))].toList 348 val res = indexes.map [ i |
349 new PartialModelAsLogicInterpretation(modelResult.representation.get(i) as PartialInterpretation,
350 traces.get(i))
351 ].toList
218 return res 352 return res
219 } 353 }
220 354
221 private def ViatraReasonerConfiguration asConfig(LogicSolverConfiguration configuration) { 355 private def ViatraReasonerConfiguration asConfig(LogicSolverConfiguration configuration) {
222 if(configuration instanceof ViatraReasonerConfiguration) { 356 if (configuration instanceof ViatraReasonerConfiguration) {
223 return configuration 357 return configuration
224 } else throw new IllegalArgumentException('''Wrong configuration. Expected: «ViatraReasonerConfiguration.name», but got: «configuration.class.name»"''') 358 } else
359 throw new IllegalArgumentException('''Wrong configuration. Expected: «ViatraReasonerConfiguration.name», but got: «configuration.class.name»"''')
225 } 360 }
226} 361}
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 10734859..628844de 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
@@ -5,21 +5,37 @@ import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner
5import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicSolverConfiguration 5import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicSolverConfiguration
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration 6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration 7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod
9import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeInferenceMethod 8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeInferenceMethod
9import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeConstraintHint
10import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedralScopePropagatorConstraints
11import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedralScopePropagatorSolver
12import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy
13import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.UnitPropagationPatternGenerator
10import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser 14import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser
15import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostObjectiveHint
16import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveKind
17import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold
11import java.util.LinkedList 18import java.util.LinkedList
12import java.util.List 19import java.util.List
13import java.util.Set 20import java.util.Set
14import org.eclipse.xtext.xbase.lib.Functions.Function1 21import org.eclipse.xtext.xbase.lib.Functions.Function1
15 22
16public enum StateCoderStrategy { 23enum StateCoderStrategy {
17 Neighbourhood, NeighbourhoodWithEquivalence, IDBased, DefinedByDiversity 24 Neighbourhood,
25 PairwiseNeighbourhood,
26 NeighbourhoodWithEquivalence,
27 IDBased,
28 DefinedByDiversity
18} 29}
19 30
20class ViatraReasonerConfiguration extends LogicSolverConfiguration{ 31enum PunishSizeStrategy {
21 //public var Iterable<PQuery> existingQueries 32 NONE,
22 33 SMALLER_IS_BETTER,
34 LARGER_IS_BETTER
35}
36
37class ViatraReasonerConfiguration extends LogicSolverConfiguration {
38 // public var Iterable<PQuery> existingQueries
23 public var nameNewElements = false 39 public var nameNewElements = false
24 public var StateCoderStrategy stateCoderStrategy = StateCoderStrategy.Neighbourhood 40 public var StateCoderStrategy stateCoderStrategy = StateCoderStrategy.Neighbourhood
25 public var TypeInferenceMethod typeInferenceMethod = TypeInferenceMethod.PreliminaryAnalysis 41 public var TypeInferenceMethod typeInferenceMethod = TypeInferenceMethod.PreliminaryAnalysis
@@ -27,7 +43,7 @@ class ViatraReasonerConfiguration extends LogicSolverConfiguration{
27 * Once per 1/randomBacktrackChance the search selects a random state. 43 * Once per 1/randomBacktrackChance the search selects a random state.
28 */ 44 */
29 public var int randomBacktrackChance = 20; 45 public var int randomBacktrackChance = 20;
30 46
31 /** 47 /**
32 * Describes the required diversity between the solutions. 48 * Describes the required diversity between the solutions.
33 * Null means that the solutions have to have different state codes only. 49 * Null means that the solutions have to have different state codes only.
@@ -41,22 +57,40 @@ class ViatraReasonerConfiguration extends LogicSolverConfiguration{
41 /** 57 /**
42 * Configuration for debugging support. 58 * Configuration for debugging support.
43 */ 59 */
44 public var DebugConfiguration debugCongiguration = new DebugConfiguration 60 public var DebugConfiguration debugConfiguration = new DebugConfiguration
45 /** 61 /**
46 * Configuration for cutting search space. 62 * Configuration for cutting search space.
47 */ 63 */
48 public var SearchSpaceConstraint searchSpaceConstraints = new SearchSpaceConstraint 64 public var SearchSpaceConstraint searchSpaceConstraints = new SearchSpaceConstraint
49 65
50 public var RealisticGuidance realisticGuidance = RealisticGuidance.Composite; 66 public var runIntermediateNumericalConsistencyChecks = true
67
68 public var punishSize = PunishSizeStrategy.NONE
69 public var scopeWeight = 1
70 public var conaintmentWeight = 2
71 public var nonContainmentWeight = 1
72 public var unfinishedWFWeight = 1
73 public var calculateObjectCreationCosts = false
74
75 public var RealisticGuidance realisticGuidance = RealisticGuidance.Composite;
51 76
52 public var isWFOptional = false; 77 public var isWFOptional = false;
53 78
54 public var allowMustViolations = false; 79 public var allowMustViolations = false;
55 80
56 public var String domain = ''; 81 public var String domain = '';
82 public var ScopePropagatorStrategy scopePropagatorStrategy = new ScopePropagatorStrategy.Polyhedral(
83 PolyhedralScopePropagatorConstraints.Relational, PolyhedralScopePropagatorSolver.Clp)
84// public var ScopePropagatorStrategy scopePropagatorStrategy = ScopePropagatorStrategy.BasicTypeHierarchy
85
86 public var List<LinearTypeConstraintHint> hints = newArrayList
87
88 public var List<CostObjectiveConfiguration> costObjectives = newArrayList
89
90 public var List<UnitPropagationPatternGenerator> unitPropagationPatternGenerators = newArrayList
57} 91}
58 92
59public class DiversityDescriptor { 93class DiversityDescriptor {
60 public var ensureDiversity = false 94 public var ensureDiversity = false
61 public static val FixPointRange = -1 95 public static val FixPointRange = -1
62 public var int range = FixPointRange 96 public var int range = FixPointRange
@@ -66,6 +100,23 @@ public class DiversityDescriptor {
66 public var Set<RelationDeclaration> relevantRelations = null 100 public var Set<RelationDeclaration> relevantRelations = null
67} 101}
68 102
103class DebugConfiguration {
104 public var PartialInterpretationVisualiser partialInterpretatioVisualiser = null
105 public var partalInterpretationVisualisationFrequency = 1
106}
107
108class InternalConsistencyCheckerConfiguration {
109 public var LogicReasoner internalIncosnsitencyDetector = null
110 public var LogicSolverConfiguration internalInconsistencDetectorConfiguration = null
111 public var incternalConsistencyCheckingFrequency = 1
112}
113
114class SearchSpaceConstraint {
115 public static val UNLIMITED_MAXDEPTH = Integer.MAX_VALUE
116 public var int maxDepth = UNLIMITED_MAXDEPTH
117 public var List<Function1<ModelGenerationMethod, ModelGenerationMethodBasedGlobalConstraint>> additionalGlobalConstraints = new LinkedList
118}
119
69public enum RealisticGuidance{ 120public enum RealisticGuidance{
70 MPC, 121 MPC,
71 NodeActivity, 122 NodeActivity,
@@ -75,21 +126,16 @@ public enum RealisticGuidance{
75 Composite_Without_Violations, 126 Composite_Without_Violations,
76 Violations 127 Violations
77} 128}
78 129class CostObjectiveConfiguration {
79public class DebugConfiguration { 130 public var List<CostObjectiveElementConfiguration> elements = newArrayList
80 public var logging = false 131 public var ObjectiveKind kind
81 public var PartialInterpretationVisualiser partialInterpretatioVisualiser = null; 132 public var ObjectiveThreshold threshold
82 public var partalInterpretationVisualisationFrequency = 1 133 public var boolean findExtremum
134 public var CostObjectiveHint hint
83} 135}
84 136
85public class InternalConsistencyCheckerConfiguration { 137class CostObjectiveElementConfiguration {
86 public var LogicReasoner internalIncosnsitencyDetector = null 138 public var String patternQualifiedName
87 public var LogicSolverConfiguration internalInconsistencDetectorConfiguration = null 139 public var int weight
88 public var incternalConsistencyCheckingFrequency = 1
89} 140}
90 141
91public class SearchSpaceConstraint {
92 public static val UNLIMITED_MAXDEPTH = Integer.MAX_VALUE
93 public var int maxDepth = UNLIMITED_MAXDEPTH
94 public var List<Function1<ModelGenerationMethod, ModelGenerationMethodBasedGlobalConstraint>> additionalGlobalConstraints = new LinkedList
95} \ 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/ActivationSelector.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ActivationSelector.xtend
new file mode 100644
index 00000000..65f9814c
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ActivationSelector.xtend
@@ -0,0 +1,24 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import java.util.ArrayList
4import java.util.Collection
5import java.util.Random
6
7abstract class ActivationSelector {
8 long runtime = 0
9 protected val Random r
10 new(Random r) {
11 this.r = r
12 }
13
14 def randomizeActivationIDs(Collection<Object> activationIDs) {
15 val startTime = System.nanoTime
16 val res = internalRandomizationOfActivationIDs(activationIDs)
17 runtime+= System.nanoTime-startTime
18 return res
19 }
20 def protected ArrayList<Object> internalRandomizationOfActivationIDs(Collection<Object> activationIDs);
21 def getRuntime(){
22 return runtime
23 }
24} \ 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/BalancedActivationSelector.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BalancedActivationSelector.xtend
new file mode 100644
index 00000000..2df9957b
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BalancedActivationSelector.xtend
@@ -0,0 +1,51 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import java.util.Collection
4import java.util.HashMap
5import java.util.Map
6import java.util.List
7import java.util.Random
8import java.util.ArrayList
9import java.util.LinkedList
10import java.util.Collections
11
12class BalancedActivationSelector extends ActivationSelector{
13 val Random r = new Random
14
15 new(Random r) {
16 super(r)
17 }
18
19 override protected internalRandomizationOfActivationIDs(Collection<Object> activationIDs) {
20 val Map<String,List<Object>> urns = new HashMap
21 val res = new ArrayList(activationIDs.size)
22 for(activationID : activationIDs) {
23 val pair = activationID as Pair<String,? extends Object>
24 val name = pair.key
25 val selectedUrn = urns.get(name)
26 if(selectedUrn!==null) {
27 selectedUrn.add(activationID)
28 } else {
29 val collection = new LinkedList
30 collection.add(activationID)
31 urns.put(name,collection)
32 }
33 }
34
35 for(list:urns.values) {
36 Collections.shuffle(list,r)
37 }
38
39 while(!urns.empty) {
40 val randomEntry = urns.entrySet.get(r.nextInt(urns.size))
41 val list = randomEntry.value
42 val removedLast = list.remove(list.size-1)
43 res.add(removedLast)
44 if(list.empty) {
45 urns.remove(randomEntry.key)
46 }
47 }
48 return res
49 }
50
51} \ 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/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 d9a1e54c..2940d12d 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,9 +9,7 @@
9 *******************************************************************************/ 9 *******************************************************************************/
10package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse; 10package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse;
11 11
12import java.util.ArrayList;
13import java.util.Arrays; 12import java.util.Arrays;
14import java.util.Collection;
15import java.util.Collections; 13import java.util.Collections;
16import java.util.Comparator; 14import java.util.Comparator;
17import java.util.Iterator; 15import java.util.Iterator;
@@ -22,17 +20,16 @@ import java.util.Random;
22 20
23import org.apache.log4j.Level; 21import org.apache.log4j.Level;
24import org.apache.log4j.Logger; 22import org.apache.log4j.Logger;
23import org.eclipse.emf.ecore.EObject;
25import org.eclipse.emf.ecore.util.EcoreUtil; 24import org.eclipse.emf.ecore.util.EcoreUtil;
25import org.eclipse.viatra.dse.api.SolutionTrajectory;
26import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; 26import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
27import org.eclipse.viatra.dse.base.ThreadContext; 27import org.eclipse.viatra.dse.base.ThreadContext;
28import org.eclipse.viatra.dse.objectives.Fitness; 28import org.eclipse.viatra.dse.objectives.Fitness;
29import org.eclipse.viatra.dse.objectives.IObjective; 29import org.eclipse.viatra.dse.objectives.IObjective;
30import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper; 30import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
31import org.eclipse.viatra.dse.solutionstore.ISolutionFoundHandler;
31import org.eclipse.viatra.dse.solutionstore.SolutionStore; 32import org.eclipse.viatra.dse.solutionstore.SolutionStore;
32import org.eclipse.viatra.query.runtime.api.IPatternMatch;
33import org.eclipse.viatra.query.runtime.api.IQuerySpecification;
34import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
35import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher;
36 33
37import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel; 34import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel;
38import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner; 35import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner;
@@ -40,11 +37,11 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem;
40import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult; 37import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult;
41import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult; 38import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult;
42import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult; 39import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult;
43import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod;
44import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic; 40import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic;
45import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation; 41import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation;
46import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation; 42import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation;
47import 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;
48import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration; 45import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration;
49import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace; 46import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace;
50 47
@@ -77,54 +74,72 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
77 // Running 74 // Running
78 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore; 75 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore;
79 private SolutionStore solutionStore; 76 private SolutionStore solutionStore;
80 private SolutionStoreWithCopy solutionStoreWithCopy;
81 private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor;
82 private volatile boolean isInterrupted = false; 77 private volatile boolean isInterrupted = false;
83 private ModelResult modelResultByInternalSolver = null; 78 private ModelResult modelResultByInternalSolver = null;
84 private Random random = new Random(); 79 private Random random = new Random();
85 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers; 80// private Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers;
86 81 public ActivationSelector activationSelector = new EvenActivationSelector(random);
82 public ViatraReasonerSolutionSaver solutionSaver;
83 public NumericSolver numericSolver;
87 // Statistics 84 // Statistics
88 private int numberOfStatecoderFail = 0; 85 private int numberOfStatecoderFail = 0;
89 private int numberOfPrintedModel = 0; 86 private int numberOfPrintedModel = 0;
90 private int numberOfSolverCalls = 0; 87 private int numberOfSolverCalls = 0;
88 public long globalConstraintEvaluationTime = 0;
89 public long fitnessCalculationTime = 0;
90
91 public long explorationStarted = 0;
91 92
92 public BestFirstStrategyForModelGeneration( 93 public BestFirstStrategyForModelGeneration(
93 ReasonerWorkspace workspace, 94 ReasonerWorkspace workspace,
94 ViatraReasonerConfiguration configuration, 95 ViatraReasonerConfiguration configuration,
95 ModelGenerationMethod method) 96 ModelGenerationMethod method,
96 { 97 ViatraReasonerSolutionSaver solutionSaver,
98 NumericSolver numericSolver) {
97 this.workspace = workspace; 99 this.workspace = workspace;
98 this.configuration = configuration; 100 this.configuration = configuration;
99 this.method = method; 101 this.method = method;
102 this.solutionSaver = solutionSaver;
103 this.numericSolver = numericSolver;
104// logger.setLevel(Level.DEBUG);
100 } 105 }
101 106
102 public SolutionStoreWithCopy getSolutionStoreWithCopy() {
103 return solutionStoreWithCopy;
104 }
105 public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() {
106 return solutionStoreWithDiversityDescriptor;
107 }
108 public int getNumberOfStatecoderFail() { 107 public int getNumberOfStatecoderFail() {
109 return numberOfStatecoderFail; 108 return numberOfStatecoderFail;
110 } 109 }
110 public long getForwardTime() {
111 return context.getDesignSpaceManager().getForwardTime();
112 }
113 public long getBacktrackingTime() {
114 return context.getDesignSpaceManager().getBacktrackingTime();
115 }
111 116
112 @Override 117 @Override
113 public void initStrategy(ThreadContext context) { 118 public void initStrategy(ThreadContext context) {
114 this.context = context; 119 this.context = context;
115 this.solutionStore = context.getGlobalContext().getSolutionStore(); 120 this.solutionStore = context.getGlobalContext().getSolutionStore();
116 ViatraQueryEngine engine = context.getQueryEngine(); 121 solutionStore.registerSolutionFoundHandler(new ISolutionFoundHandler() {
117// // TODO: visualisation 122
118 matchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>(); 123 @Override
119 for(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> p : this.method.getAllPatterns()) { 124 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
120 //System.out.println(p.getSimpleName()); 125 // Ignore.
121 ViatraQueryMatcher<? extends IPatternMatch> matcher = p.getMatcher(engine); 126 }
122 matchers.add(matcher); 127
123 } 128 @Override
129 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
130 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolutions);
131 saveTimes();
132 logger.debug("Found a solution.");
133 }
134 });
135 numericSolver.init(context);
124 136
125 this.solutionStoreWithCopy = new SolutionStoreWithCopy(); 137// ViatraQueryEngine engine = context.getQueryEngine();
126 this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement); 138// matchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
127 139// for(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> p : this.method.getAllPatterns()) {
140// ViatraQueryMatcher<? extends IPatternMatch> matcher = p.getMatcher(engine);
141// }
142//
128 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 143 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
129 this.comparator = new Comparator<TrajectoryWithFitness>() { 144 this.comparator = new Comparator<TrajectoryWithFitness>() {
130 @Override 145 @Override
@@ -138,23 +153,26 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
138 153
139 @Override 154 @Override
140 public void explore() { 155 public void explore() {
141 if (!context.checkGlobalConstraints()) { 156 this.explorationStarted=System.nanoTime();
157 if (!checkGlobalConstraints()) {
142 logger.info("Global contraint is not satisifed in the first state. Terminate."); 158 logger.info("Global contraint is not satisifed in the first state. Terminate.");
143 return; 159 return;
160 } else if(!numericSolver.maySatisfiable()) {
161 logger.info("Numeric contraints are not satisifed in the first state. Terminate.");
162 return;
144 } 163 }
145 if (configuration.searchSpaceConstraints.maxDepth == 0) { 164 if (configuration.searchSpaceConstraints.maxDepth == 0) {
146 logger.info("Maximal depth is reached in the initial solution. Terminate."); 165 logger.info("Maximal depth is reached in the initial solution. Terminate.");
147 return; 166 return;
148 } 167 }
149 168
150 final Fitness firstFittness = context.calculateFitness(); 169 final Fitness firstFitness = calculateFitness();
151 checkForSolution(firstFittness); 170 checkForSolution(firstFitness);
152 171
153 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 172 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
154 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]); 173 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]);
155 TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness); 174 TrajectoryWithFitness currentTrajectoryWithFitness = new TrajectoryWithFitness(firstTrajectory, firstFitness);
156 trajectoiresToExplore.add(currentTrajectoryWithFittness); 175 trajectoiresToExplore.add(currentTrajectoryWithFitness);
157
158 //if(configuration) 176 //if(configuration)
159 visualiseCurrentState(); 177 visualiseCurrentState();
160// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) { 178// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) {
@@ -168,22 +186,22 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
168 186
169 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) { 187 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) {
170 188
171 if (currentTrajectoryWithFittness == null) { 189 if (currentTrajectoryWithFitness == null) {
172 if (trajectoiresToExplore.isEmpty()) { 190 if (trajectoiresToExplore.isEmpty()) {
173 logger.debug("State space is fully traversed."); 191 logger.debug("State space is fully traversed.");
174 return; 192 return;
175 } else { 193 } else {
176 currentTrajectoryWithFittness = selectState(); 194 currentTrajectoryWithFitness = selectState();
177 if (logger.isDebugEnabled()) { 195 if (logger.isDebugEnabled()) {
178 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray())); 196 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray()));
179 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness); 197 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFitness);
180 } 198 }
181 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory); 199 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFitness.trajectory);
182 } 200 }
183 } 201 }
184 202
185// visualiseCurrentState(); 203// visualiseCurrentState();
186// boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness); 204// boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithfitness);
187// if(consistencyCheckResult == true) { 205// if(consistencyCheckResult == true) {
188// continue mainLoop; 206// continue mainLoop;
189// } 207// }
@@ -193,32 +211,30 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
193 211
194 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && iterator.hasNext()) { 212 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && iterator.hasNext()) {
195 final Object nextActivation = iterator.next(); 213 final Object nextActivation = iterator.next();
196// if (!iterator.hasNext()) {
197// logger.debug("Last untraversed activation of the state.");
198// trajectoiresToExplore.remove(currentTrajectoryWithFittness);
199// }
200 logger.debug("Executing new activation: " + nextActivation); 214 logger.debug("Executing new activation: " + nextActivation);
201 context.executeAcitvationId(nextActivation); 215 context.executeAcitvationId(nextActivation);
216 method.getStatistics().incrementDecisionCount();
202 217
203 visualiseCurrentState(); 218 visualiseCurrentState();
204// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) { 219// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) {
205// System.out.println(matcher.getPatternName()); 220// int c = matcher.countMatches();
206// System.out.println("---------"); 221// if(c>=1) {
207// for(IPatternMatch m : matcher.getAllMatches()) { 222// System.out.println(c+ " " +matcher.getPatternName());
208// System.out.println(m); 223// }
209// }
210// System.out.println("---------");
211// } 224// }
212 225
213 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness); 226 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFitness);
214 if(consistencyCheckResult == true) { continue mainLoop; } 227 if(consistencyCheckResult == true) { continue mainLoop; }
215 228
216 if (context.isCurrentStateAlreadyTraversed()) { 229 if (context.isCurrentStateAlreadyTraversed()) {
217 logger.info("The new state is already visited."); 230 logger.info("The new state is already visited.");
218 context.backtrack(); 231 context.backtrack();
219 } else if (!context.checkGlobalConstraints()) { 232 } else if (!checkGlobalConstraints()) {
220 logger.debug("Global contraint is not satisifed."); 233 logger.debug("Global contraint is not satisifed.");
221 context.backtrack(); 234 context.backtrack();
235 } else if (!numericSolver.maySatisfiable()) {
236 logger.debug("Numeric constraints are not satisifed.");
237 context.backtrack();
222 } else { 238 } else {
223 final Fitness nextFitness = context.calculateFitness(); 239 final Fitness nextFitness = context.calculateFitness();
224 checkForSolution(nextFitness); 240 checkForSolution(nextFitness);
@@ -228,59 +244,89 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
228 continue; 244 continue;
229 } 245 }
230 246
231 TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness( 247 TrajectoryWithFitness nextTrajectoryWithfitness = new TrajectoryWithFitness(
232 context.getTrajectory().toArray(), nextFitness); 248 context.getTrajectory().toArray(), nextFitness);
233 trajectoiresToExplore.add(nextTrajectoryWithFittness); 249 trajectoiresToExplore.add(nextTrajectoryWithfitness);
234 250
235 int compare = objectiveComparatorHelper.compare(currentTrajectoryWithFittness.fitness, 251 int compare = objectiveComparatorHelper.compare(currentTrajectoryWithFitness.fitness,
236 nextTrajectoryWithFittness.fitness); 252 nextTrajectoryWithfitness.fitness);
237 if (compare < 0) { 253 if (compare < 0) {
238 logger.debug("Better fitness, moving on: " + nextFitness); 254 logger.debug("Better fitness, moving on: " + nextFitness);
239 currentTrajectoryWithFittness = nextTrajectoryWithFittness; 255 currentTrajectoryWithFitness = nextTrajectoryWithfitness;
240 continue mainLoop; 256 continue mainLoop;
241 } else if (compare == 0) { 257 } else if (compare == 0) {
242 logger.debug("Equally good fitness, moving on: " + nextFitness); 258 logger.debug("Equally good fitness, moving on: " + nextFitness);
243 currentTrajectoryWithFittness = nextTrajectoryWithFittness; 259 currentTrajectoryWithFitness = nextTrajectoryWithfitness;
244 continue mainLoop; 260 continue mainLoop;
245 } else { 261 } else {
246 logger.debug("Worse fitness."); 262 logger.debug("Worse fitness.");
247 currentTrajectoryWithFittness = null; 263 currentTrajectoryWithFitness = null;
248 continue mainLoop; 264 continue mainLoop;
249 } 265 }
250 } 266 }
251 } 267 }
252 268
253 logger.debug("State is fully traversed."); 269 logger.debug("State is fully traversed.");
254 trajectoiresToExplore.remove(currentTrajectoryWithFittness); 270 trajectoiresToExplore.remove(currentTrajectoryWithFitness);
255 currentTrajectoryWithFittness = null; 271 currentTrajectoryWithFitness = null;
256 272
257 } 273 }
258 logger.info("Interrupted."); 274 logger.info("Interrupted.");
259 } 275 }
260 276
277 private boolean checkGlobalConstraints() {
278 long start = System.nanoTime();
279 boolean result = context.checkGlobalConstraints();
280 globalConstraintEvaluationTime += System.nanoTime() - start;
281 return result;
282 }
283
284 private Fitness calculateFitness() {
285 long start = System.nanoTime();
286 Fitness fitness = context.calculateFitness();
287 fitnessCalculationTime += System.nanoTime() - start;
288 return fitness;
289 }
290
261 private List<Object> selectActivation() { 291 private List<Object> selectActivation() {
262 List<Object> activationIds; 292 List<Object> activationIds;
263 try { 293 try {
264 activationIds = new ArrayList<Object>(context.getUntraversedActivationIds()); 294 activationIds = this.activationSelector.randomizeActivationIDs(context.getUntraversedActivationIds());
265 Collections.shuffle(activationIds);
266 } catch (NullPointerException e) { 295 } catch (NullPointerException e) {
296// logger.warn("Unexpected state code: " + context.getDesignSpaceManager().getCurrentState());
267 numberOfStatecoderFail++; 297 numberOfStatecoderFail++;
268 activationIds = Collections.emptyList(); 298 activationIds = Collections.emptyList();
269 } 299 }
270 return activationIds; 300 return activationIds;
271 } 301 }
272 302
273 private void checkForSolution(final Fitness fittness) { 303 private void checkForSolution(final Fitness fitness) {
274 if (fittness.isSatisifiesHardObjectives()) { 304 solutionStore.newSolution(context);
275 if (solutionStoreWithDiversityDescriptor.isDifferent(context)) { 305 }
276 solutionStoreWithCopy.newSolution(context); 306
277 solutionStoreWithDiversityDescriptor.newSolution(context); 307 public List<String> times = new LinkedList<String>();
278 solutionStore.newSolution(context); 308 private void saveTimes() {
279 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolution); 309 long forwardTime = context.getDesignSpaceManager().getForwardTime()/1000000;
280 310 long backtrackingTime = context.getDesignSpaceManager().getBacktrackingTime()/1000000;
281 logger.debug("Found a solution."); 311 long activationSelection = this.activationSelector.getRuntime()/1000000;
282 } 312 long solutionCopierTime = this.solutionSaver.getTotalCopierRuntime()/1000000;
283 } 313 long numericalSolverSumTime = this.numericSolver.getRuntime()/1000000;
314 long numericalSolverProblemForming = this.numericSolver.getSolverSolvingProblem()/1000000;
315 long numericalSolverSolving = this.numericSolver.getSolverSolvingProblem()/1000000;
316 long numericalSolverInterpreting = this.numericSolver.getSolverSolution()/1000000;
317 this.times.add(
318 "(TransformationExecutionTime"+method.getStatistics().transformationExecutionTime/1000000+
319 "|ForwardTime:"+forwardTime+
320 "|Backtrackingtime:"+backtrackingTime+
321 "|GlobalConstraintEvaluationTime:"+(globalConstraintEvaluationTime/1000000)+
322 "|FitnessCalculationTime:"+(fitnessCalculationTime/1000000)+
323 "|ActivationSelectionTime:"+activationSelection+
324 "|SolutionCopyTime:"+solutionCopierTime+
325 "|NumericalSolverSumTime:"+numericalSolverSumTime+
326 "|NumericalSolverProblemFormingTime:"+numericalSolverProblemForming+
327 "|NumericalSolverSolvingTime:"+numericalSolverSolving+
328 "|NumericalSolverInterpretingSolution:"+numericalSolverInterpreting+")");
329
284 } 330 }
285 331
286 @Override 332 @Override
@@ -309,7 +355,7 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
309 } else { 355 } else {
310 return trajectoiresToExplore.element(); 356 return trajectoiresToExplore.element();
311 } 357 }
312 } 358 }
313 359
314// private void logCurrentStateMetric() { 360// private void logCurrentStateMetric() {
315// if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) { 361// if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) {
@@ -322,13 +368,16 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
322 368
323 369
324 public void visualiseCurrentState() { 370 public void visualiseCurrentState() {
325 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugCongiguration.partialInterpretatioVisualiser; 371 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugConfiguration.partialInterpretatioVisualiser;
326 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) { 372 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) {
327 PartialInterpretation p = (PartialInterpretation) (context.getModel()); 373 PartialInterpretation p = (PartialInterpretation) (context.getModel());
328 int id = ++numberOfPrintedModel; 374 int id = ++numberOfPrintedModel;
329 if (id % configuration.debugCongiguration.partalInterpretationVisualisationFrequency == 0) { 375 if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) {
330 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); 376 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p);
331 visualisation.writeToFile(workspace, String.format("state%09d.png", id)); 377 logger.debug("Visualizing state: " + id + " (" + context.getDesignSpaceManager().getCurrentState() + ")");
378 String name = String.format("state%09d", id);
379 visualisation.writeToFile(workspace, name + ".png");
380 workspace.writeModel((EObject) context.getModel(), name + ".xmi");
332 } 381 }
333 } 382 }
334 } 383 }
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/EvenActivationSelector.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/EvenActivationSelector.xtend
new file mode 100644
index 00000000..82a5f32d
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/EvenActivationSelector.xtend
@@ -0,0 +1,20 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import java.util.Random
4import java.util.Collection
5import java.util.Collections
6import java.util.ArrayList
7
8class EvenActivationSelector extends ActivationSelector {
9
10 new(Random r) {
11 super(r)
12 }
13
14 override protected internalRandomizationOfActivationIDs(Collection<Object> activationIDs) {
15 val toShuffle = new ArrayList<Object>(activationIDs);
16 Collections.shuffle(toShuffle);
17 return toShuffle
18 }
19
20} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java
index eb7df089..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,480 +36,540 @@ 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.visualisation.PartialInterpretationVisualisation; 42import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation;
42import 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;
43import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.RealisticGuidance; 45import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.RealisticGuidance;
44import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration; 46import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration;
45import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace; 47import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace;
46 48
47public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements IStrategy { 49public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements IStrategy {
48 // Services and Configuration 50 // Services and Configuration
49 private ThreadContext context; 51 private ThreadContext context;
50 private ReasonerWorkspace workspace; 52 private ReasonerWorkspace workspace;
51 private ViatraReasonerConfiguration configuration; 53 private ViatraReasonerConfiguration configuration;
52 private ModelGenerationMethod method; 54 private ModelGenerationMethod method;
53 private PartialInterpretation2Logic partialInterpretation2Logic = new PartialInterpretation2Logic(); 55 private PartialInterpretation2Logic partialInterpretation2Logic = new PartialInterpretation2Logic();
54 private Comparator<TrajectoryWithFitness> comparator; 56 private Comparator<TrajectoryWithFitness> comparator;
55 private Logger logger = Logger.getLogger(IStrategy.class); 57 private Logger logger = Logger.getLogger(IStrategy.class);
58 public NumericSolver numericSolver = null;
59
60 // Running
61 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore;
62 private SolutionStore solutionStore;
63 private SolutionStoreWithCopy solutionStoreWithCopy;
64 private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor;
65 private volatile boolean isInterrupted = false;
66 private ModelResult modelResultByInternalSolver = null;
67 private Random random = new Random();
68
69 // matchers for detecting the number of violations
70 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mustMatchers;
71 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mayMatchers;
72
73 // Encode the used activations of a particular state
74 private Map<Object, List<Object>> stateAndActivations;
75 private boolean allowMustViolation;
76 private Domain domain;
77 int targetSize;
78 public ActivationSelector activationSelector = new EvenActivationSelector(random);
79 // Statistics
80 private int numberOfStatecoderFail = 0;
81 private int numberOfPrintedModel = 0;
82 private int numberOfSolverCalls = 0;
83 private PartialInterpretationMetricDistance metricDistance;
84 private double currentStateValue = Double.MAX_VALUE;
85 private double currentNodeTypeDistance = 1;
86 private int numNodesToGenerate = 0;
87 public long explorationStarted = 0;
88 public long globalConstraintEvaluationTime = 0;
89 public long fitnessCalculationTime = 0;
90
91 public HillClimbingOnRealisticMetricStrategyForModelGeneration(
92 ReasonerWorkspace workspace,
93 ViatraReasonerConfiguration configuration,
94 ModelGenerationMethod method)
95 {
96 this.workspace = workspace;
97 this.configuration = configuration;
98 this.method = method;
99 }
100
101 public SolutionStoreWithCopy getSolutionStoreWithCopy() {
102 return solutionStoreWithCopy;
103 }
104 public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() {
105 return solutionStoreWithDiversityDescriptor;
106 }
107 public int getNumberOfStatecoderFail() {
108 return numberOfStatecoderFail;
109 }
110
111 public long getForwardTime() {
112 return context.getDesignSpaceManager().getForwardTime();
113 }
114 public long getBacktrackingTime() {
115 return context.getDesignSpaceManager().getBacktrackingTime();
116 }
117
118 @Override
119 public void initStrategy(ThreadContext context) {
120 this.context = context;
121 this.solutionStore = context.getGlobalContext().getSolutionStore();
122 domain = Domain.valueOf(configuration.domain);
123
124 ViatraQueryEngine engine = context.getQueryEngine();
125// // TODO: visualisation
126 mustMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
127 mayMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
56 128
57 // Running 129 // manully restict the number of super types of one class
58 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore; 130 this.method.getInvalidWF().forEach(a ->{
59 private SolutionStore solutionStore; 131 ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine);
60 private SolutionStoreWithCopy solutionStoreWithCopy; 132 mustMatchers.add(matcher);
61 private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor; 133 });
62 private volatile boolean isInterrupted = false;
63 private ModelResult modelResultByInternalSolver = null;
64 private Random random = new Random();
65 134
66 // matchers for detecting the number of violations 135 this.method.getUnfinishedWF().forEach(a ->{
67 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mustMatchers; 136 ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine);
68 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mayMatchers; 137 mayMatchers.add(matcher);
138 });
69 139
70 // Encode the used activations of a particular state
71 private Map<Object, List<Object>> stateAndActivations;
72 private boolean allowMustViolation;
73 private Domain domain;
74 int targetSize;
75
76 // Statistics
77 private int numberOfStatecoderFail = 0;
78 private int numberOfPrintedModel = 0;
79 private int numberOfSolverCalls = 0;
80 private PartialInterpretationMetricDistance metricDistance;
81 private double currentStateValue = Double.MAX_VALUE;
82 private double currentNodeTypeDistance = 1;
83 private int numNodesToGenerate = 0;
84 140
85 public HillClimbingOnRealisticMetricStrategyForModelGeneration( 141 //set up comparator
86 ReasonerWorkspace workspace, 142 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
87 ViatraReasonerConfiguration configuration, 143 this.comparator = new Comparator<TrajectoryWithFitness>() {
88 ModelGenerationMethod method) 144 @Override
89 { 145 public int compare(TrajectoryWithFitness o1, TrajectoryWithFitness o2) {
90 this.workspace = workspace; 146 return objectiveComparatorHelper.compare(o2.fitness, o1.fitness);
91 this.configuration = configuration; 147 }
92 this.method = method; 148 };
93 }
94 149
95 public SolutionStoreWithCopy getSolutionStoreWithCopy() { 150 this.solutionStoreWithCopy = new SolutionStoreWithCopy();
96 return solutionStoreWithCopy; 151 this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement);
97 } 152
98 public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() { 153 trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11, comparator);
99 return solutionStoreWithDiversityDescriptor; 154 stateAndActivations = new HashMap<Object, List<Object>>();
155 metricDistance = new PartialInterpretationMetricDistance(domain);
156
157 //set whether allows must violations during the realistic generation
158 allowMustViolation = configuration.allowMustViolations;
159 targetSize = configuration.typeScopes.maxNewElements + 2;
160 //this.numericSolver = new NumericSolver(method, this.configuration.runIntermediateNumericalConsistencyChecks, false);
161 }
162
163 @Override
164 public void explore() {
165 this.explorationStarted=System.nanoTime();
166 if (!checkGlobalConstraints()) {
167 logger.info("Global contraint is not satisifed in the first state. Terminate.");
168 return;
100 } 169 }
101 public int getNumberOfStatecoderFail() { 170 if (configuration.searchSpaceConstraints.maxDepth == 0) {
102 return numberOfStatecoderFail; 171 logger.info("Maximal depth is reached in the initial solution. Terminate.");
172 return;
103 } 173 }
104
105 @Override
106 public void initStrategy(ThreadContext context) {
107 this.context = context;
108 this.solutionStore = context.getGlobalContext().getSolutionStore();
109 domain = Domain.valueOf(configuration.domain);
110
111 ViatraQueryEngine engine = context.getQueryEngine();
112// // TODO: visualisation
113 mustMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
114 mayMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
115
116 // manully restict the number of super types of one class
117 this.method.getInvalidWF().forEach(a ->{
118 ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine);
119 mustMatchers.add(matcher);
120 });
121
122 this.method.getUnfinishedWF().forEach(a ->{
123 ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine);
124 mayMatchers.add(matcher);
125 });
126 174
127 175 final Fitness firstFittness = context.calculateFitness();
128 //set up comparator 176
129 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 177 //final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
130 this.comparator = new Comparator<TrajectoryWithFitness>() { 178 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]);
131 @Override 179 TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness);
132 public int compare(TrajectoryWithFitness o1, TrajectoryWithFitness o2) { 180 trajectoiresToExplore.add(currentTrajectoryWithFittness);
133 return objectiveComparatorHelper.compare(o2.fitness, o1.fitness); 181 Object lastState = null;
182
183 //if(configuration)
184 visualiseCurrentState();
185 // the two is the True and False node generated at the beginning of the generation
186 int count = 0;
187 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) {
188
189 if (currentTrajectoryWithFittness == null) {
190 if (trajectoiresToExplore.isEmpty()) {
191 logger.debug("State space is fully traversed.");
192 return;
193 } else {
194 currentTrajectoryWithFittness = selectState();
195 if (logger.isDebugEnabled()) {
196 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray()));
197 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness);
198 }
199 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory);
200
201 // reset the regression for this trajectory
202 metricDistance.getLinearModel().resetRegression(context.getCurrentStateId());
134 } 203 }
135 }; 204 }
136 205
137 this.solutionStoreWithCopy = new SolutionStoreWithCopy(); 206 List<Object> activationIds = selectActivation();
138 this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement); 207 PartialInterpretation model = (PartialInterpretation) context.getModel();
208 System.out.println(model.getNewElements().size());
209 System.out.println("# violations: " + getNumberOfViolations(mayMatchers));
139 210
140 trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11, comparator); 211 Map<Object, Double> valueMap = new HashMap<Object,Double>();
141 stateAndActivations = new HashMap<Object, List<Object>>();
142 metricDistance = new PartialInterpretationMetricDistance(domain);
143 212
144 //set whether allows must violations during the realistic generation 213 //init epsilon and draw
145 allowMustViolation = configuration.allowMustViolations; 214 MetricDistanceGroup heuristics = metricDistance.calculateMetricDistanceKS(model);
146 targetSize = configuration.typeScopes.maxNewElements + 2;
147 }
148 215
149 @Override 216 if(!stateAndActivations.containsKey(context.getCurrentStateId())) {
150 public void explore() { 217 stateAndActivations.put(context.getCurrentStateId(), new ArrayList<Object>());
151 if (!context.checkGlobalConstraints()) {
152 logger.info("Global contraint is not satisifed in the first state. Terminate.");
153 return;
154 }
155 if (configuration.searchSpaceConstraints.maxDepth == 0) {
156 logger.info("Maximal depth is reached in the initial solution. Terminate.");
157 return;
158 } 218 }
159 219
160 final Fitness firstFittness = context.calculateFitness(); 220 // calculate values for epsilon greedy
161 221 double epsilon = 1.0/count;
162 //final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 222 double draw = Math.random();
163 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]); 223 count++;
164 TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness); 224 this.currentNodeTypeDistance = heuristics.getNodeTypeDistance();
165 trajectoiresToExplore.add(currentTrajectoryWithFittness); 225 numNodesToGenerate = model.getMaxNewElements();
166 Object lastState = null; 226 System.out.println("NA distance: " + heuristics.getNADistance());
167 227 System.out.println("MPC distance: " + heuristics.getMPCDistance());
168 //if(configuration) 228 System.out.println("Out degree distance:" + heuristics.getOutDegreeDistance());
169 visualiseCurrentState(); 229 System.out.println("NodeType :" + currentNodeTypeDistance);
170 // the two is the True and False node generated at the beginning of the generation
171 int count = 0;
172 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) {
173 230
174 if (currentTrajectoryWithFittness == null) {
175 if (trajectoiresToExplore.isEmpty()) {
176 logger.debug("State space is fully traversed.");
177 return;
178 } else {
179 currentTrajectoryWithFittness = selectState();
180 if (logger.isDebugEnabled()) {
181 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray()));
182 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness);
183 }
184 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory);
185
186 // reset the regression for this trajectory
187 metricDistance.getLinearModel().resetRegression(context.getCurrentStateId());
188 }
189 }
190
191 List<Object> activationIds = selectActivation();
192 PartialInterpretation model = (PartialInterpretation) context.getModel();
193// System.out.println(model.getNewElements().size());
194// System.out.println("# violations: " + getNumberOfViolations(mayMatchers));
195
196 Map<Object, Double> valueMap = new HashMap<Object,Double>();
197
198 //init epsilon and draw
199 MetricDistanceGroup heuristics = metricDistance.calculateMetricDistanceKS(model);
200 231
201 if(!stateAndActivations.containsKey(context.getCurrentStateId())) { 232 //TODO: the number of activations to be checked should be configurasble
202 stateAndActivations.put(context.getCurrentStateId(), new ArrayList<Object>()); 233 if(activationIds.size() > 50) {
203 } 234 activationIds = activationIds.subList(0, 50);
235 }
236
237 valueMap = sortWithWeight(activationIds);
238 lastState = context.getCurrentStateId();
239 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && activationIds.size() > 0) {
240 final Object nextActivation = drawWithEpsilonProbabilty(activationIds, valueMap, epsilon, draw);
241
242 stateAndActivations.get(context.getCurrentStateId()).add(nextActivation);
243 logger.debug("Executing new activation: " + nextActivation);
244 context.executeAcitvationId(nextActivation);
245 visualiseCurrentState();
246 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness);
247 if(consistencyCheckResult == true) { continue mainLoop; }
204 248
205 // calculate values for epsilon greedy 249// if (context.isCurrentStateAlreadyTraversed()) {
206 double epsilon = 1.0/count; 250// logger.info("The new state is already visited.");
207 double draw = Math.random(); 251// context.backtrack();
208 count++; 252// } else if (!checkGlobalConstraints()) {
209 this.currentNodeTypeDistance = heuristics.getNodeTypeDistance(); 253// logger.debug("Global contraint is not satisifed.");
210 numNodesToGenerate = model.getMaxNewElements(); 254// context.backtrack();
211// System.out.println("NA distance: " + heuristics.getNADistance()); 255// }
212// System.out.println("MPC distance: " + heuristics.getMPCDistance());
213// System.out.println("Out degree distance:" + heuristics.getOutDegreeDistance());
214// System.out.println("NodeType :" + currentNodeTypeDistance);
215
216
217 //TODO: the number of activations to be checked should be configurasble
218 if(activationIds.size() > 50) {
219 activationIds = activationIds.subList(0, 50);
220 }
221 256
222 valueMap = sortWithWeight(activationIds); 257 int currentSize = model.getNewElements().size();
223 lastState = context.getCurrentStateId(); 258 int targetDiff = targetSize - currentSize;
224 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && activationIds.size() > 0) { 259 boolean shouldFinish = currentSize >= targetSize;
225 final Object nextActivation = drawWithEpsilonProbabilty(activationIds, valueMap, epsilon, draw); 260
226 261 // does not allow must violations
227 stateAndActivations.get(context.getCurrentStateId()).add(nextActivation); 262 if((getNumberOfViolations(mustMatchers) > 0|| getNumberOfViolations(mayMatchers) > targetDiff) && !allowMustViolation && !shouldFinish) {
228 logger.debug("Executing new activation: " + nextActivation); 263 context.backtrack();
229 context.executeAcitvationId(nextActivation); 264 }else {
230 visualiseCurrentState(); 265 final Fitness nextFitness = context.calculateFitness();
231 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness);
232 if(consistencyCheckResult == true) { continue mainLoop; }
233
234 int currentSize = model.getNewElements().size();
235 int targetDiff = targetSize - currentSize;
236 boolean shouldFinish = currentSize >= targetSize;
237 266
238 // does not allow must violations 267 // the only hard objectives are configured in the config file
239 if((getNumberOfViolations(mustMatchers) > 0|| getNumberOfViolations(mayMatchers) > targetDiff) && !allowMustViolation && !shouldFinish) { 268 checkForSolution(nextFitness);
269
270 if (context.getDepth() > configuration.searchSpaceConstraints.maxDepth) {
271 logger.debug("Reached max depth.");
240 context.backtrack(); 272 context.backtrack();
241 }else { 273 continue;
242 final Fitness nextFitness = context.calculateFitness();
243
244 // the only hard objectives are configured in the config file
245 checkForSolution(nextFitness);
246
247 if (context.getDepth() > configuration.searchSpaceConstraints.maxDepth) {
248 logger.debug("Reached max depth.");
249 context.backtrack();
250 continue;
251 }
252
253 //Record value for current trajectory
254 TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness(
255 context.getTrajectory().toArray(), nextFitness);
256 int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size();
257 int violation = getNumberOfViolations(mayMatchers);
258 double currentValue = calculateCurrentStateValue(nodeSize, violation);
259 metricDistance.getLinearModel().feedData(context.getCurrentStateId(), metricDistance.calculateFeature(nodeSize, violation), currentValue, lastState);
260 trajectoiresToExplore.add(nextTrajectoryWithFittness);
261 currentStateValue = currentValue;
262 //Currently, just go to the next state without considering the value of trajectory
263 currentTrajectoryWithFittness = nextTrajectoryWithFittness;
264 continue mainLoop;
265
266 } 274 }
275
276 //Record value for current trajectory
277 TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness(
278 context.getTrajectory().toArray(), nextFitness);
279 int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size();
280 int violation = getNumberOfViolations(mayMatchers);
281 double currentValue = calculateCurrentStateValue(nodeSize, violation);
282 metricDistance.getLinearModel().feedData(context.getCurrentStateId(), metricDistance.calculateFeature(nodeSize, violation), currentValue, lastState);
283 trajectoiresToExplore.add(nextTrajectoryWithFittness);
284 currentStateValue = currentValue;
285 //Currently, just go to the next state without considering the value of trajectory
286 currentTrajectoryWithFittness = nextTrajectoryWithFittness;
287 continue mainLoop;
288
267 } 289 }
268 logger.debug("State is fully traversed.");
269 trajectoiresToExplore.remove(currentTrajectoryWithFittness);
270 currentTrajectoryWithFittness = null;
271 context.backtrack();
272 } 290 }
273 logger.info("Interrupted."); 291 logger.debug("State is fully traversed.");
292 trajectoiresToExplore.remove(currentTrajectoryWithFittness);
293 currentTrajectoryWithFittness = null;
294 context.backtrack();
274 } 295 }
296 logger.info("Interrupted.");
297 }
275 298
276 /** 299 private boolean checkGlobalConstraints() {
277 * 300 long start = System.nanoTime();
278 * @param activationIds 301 boolean result = context.checkGlobalConstraints();
279 * @return: activation to value map 302 globalConstraintEvaluationTime += System.nanoTime() - start;
280 */ 303 return result;
281 private Map<Object, Double> sortWithWeight(List<Object> activationIds){ 304 }
282 Map<Object, Double> valueMap = new HashMap<Object, Double>(); 305
283 Object currentId = context.getCurrentStateId(); 306 private Fitness calculateFitness() {
284 // check for next states 307 long start = System.nanoTime();
285 for(Object id : activationIds) { 308 Fitness fitness = context.calculateFitness();
286 context.executeAcitvationId(id); 309 fitnessCalculationTime += System.nanoTime() - start;
287 int violation = getNumberOfViolations(mayMatchers); 310 return fitness;
311 }
312
313 /**
314 *
315 * @param activationIds
316 * @return: activation to value map
317 */
318 private Map<Object, Double> sortWithWeight(List<Object> activationIds){
319 Map<Object, Double> valueMap = new HashMap<Object, Double>();
320 Object currentId = context.getCurrentStateId();
321 // check for next states
322 for(Object id : activationIds) {
323 context.executeAcitvationId(id);
324 int violation = getNumberOfViolations(mayMatchers);
288 325
289 if(!allowMustViolation && getNumberOfViolations(mustMatchers) > 0) { 326 if(!allowMustViolation && getNumberOfViolations(mustMatchers) > 0) {
290 valueMap.put(id, Double.MAX_VALUE); 327 valueMap.put(id, Double.MAX_VALUE);
291 stateAndActivations.get(currentId).add(id); 328 stateAndActivations.get(currentId).add(id);
292 }else { 329 }else {
293 valueMap.put(id, calculateFutureStateValue(violation)); 330 valueMap.put(id, calculateFutureStateValue(violation));
294 }
295
296
297
298 context.backtrack();
299 } 331 }
332
333
300 334
301 //remove all the elements having large distance 335 context.backtrack();
302 Collections.sort(activationIds, Comparator.comparing(li -> valueMap.get(li)));
303 return valueMap;
304 } 336 }
305 337
306 private double calculateFutureStateValue(int violation) { 338 //remove all the elements having large distance
307 long start = System.nanoTime(); 339 Collections.sort(activationIds, Comparator.comparing(li -> valueMap.get(li)));
308 int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size(); 340 return valueMap;
309 double currentValue = calculateCurrentStateValue(nodeSize,violation); 341 }
310 double[] toPredict = metricDistance.calculateFeature(100, violation); 342
311 if(Math.abs(currentValue - currentStateValue) < 0.001) { 343 private double calculateFutureStateValue(int violation) {
312 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); 344 long start = System.nanoTime();
313 return Double.MAX_VALUE; 345 int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size();
314 } 346 double currentValue = calculateCurrentStateValue(nodeSize,violation);
315 try { 347 double[] toPredict = metricDistance.calculateFeature(100, violation);
316 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); 348 if(Math.abs(currentValue - currentStateValue) < 0.001) {
317 return metricDistance.getLinearModel().getPredictionForNextDataSample(metricDistance.calculateFeature(nodeSize, violation), currentValue, toPredict); 349 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start);
318 }catch(IllegalArgumentException e) { 350 return Double.MAX_VALUE;
319 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); 351 }
320 return currentValue; 352 try {
321 } 353 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start);
322 354 return metricDistance.getLinearModel().getPredictionForNextDataSample(metricDistance.calculateFeature(nodeSize, violation), currentValue, toPredict);
355 }catch(IllegalArgumentException e) {
356 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start);
357 return currentValue;
323 } 358 }
324 private double calculateCurrentStateValue(int factor, int violation) {
325 PartialInterpretation model = (PartialInterpretation) context.getModel();
326 MetricDistanceGroup g = metricDistance.calculateMetricDistanceKS(model);
327 if(configuration.realisticGuidance == RealisticGuidance.MPC) {
328 return g.getMPCDistance();
329 }else if(configuration.realisticGuidance == RealisticGuidance.NodeActivity) {
330 return g.getNADistance();
331 }else if(configuration.realisticGuidance == RealisticGuidance.OutDegree) {
332 return g.getOutDegreeDistance();
333 }else if(configuration.realisticGuidance == RealisticGuidance.NodeType) {
334 return g.getNodeTypeDistance();
335 }else if(configuration.realisticGuidance == RealisticGuidance.Composite) {
336 double consistenceWeights = 5 * factor / (configuration.typeScopes.maxNewElements + 2) * (1- 1.0/(1+violation));
337 if(domain == Domain.Yakindumm) {
338 double unfinishFactor = 50 * (1 - (double)factor / targetSize);
339 double nodeTypeFactor = g.getNodeTypeDistance();
340 double normalFactor = 5;
341 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
342 nodeTypeFactor = 0;
343 normalFactor = 100;
344 unfinishFactor = 0;
345 }
346
347 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
348 }else if (domain == Domain.Ecore) {
349 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
350 double nodeTypeFactor = g.getNodeTypeDistance();
351 double normalFactor = 5;
352 if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) {
353 nodeTypeFactor = 0;
354 normalFactor = 100;
355 unfinishFactor *= 0.5;
356 }
357
358 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
359 }else {
360 double unfinishFactor = context.calculateFitness().get("CompositeUnfinishednessObjective");
361 double nodeTypeFactor = g.getNodeTypeDistance();
362 double normalFactor = 5;
363 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
364 nodeTypeFactor = 0;
365 normalFactor = 100;
366 //unfinishFactor *= 0.5;
367 }
368
369 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + 2*g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
370 }
371 359
372 }else if(configuration.realisticGuidance == RealisticGuidance.Composite_Without_Violations) { 360 }
373 if(domain == Domain.Yakindumm) { 361 private double calculateCurrentStateValue(int factor, int violation) {
374 double unfinishFactor = 50 * (1 - (double)factor / targetSize); 362 PartialInterpretation model = (PartialInterpretation) context.getModel();
375 double nodeTypeFactor = g.getNodeTypeDistance(); 363 MetricDistanceGroup g = metricDistance.calculateMetricDistanceKS(model);
376 double normalFactor = 5; 364 if(configuration.realisticGuidance == RealisticGuidance.MPC) {
377 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) { 365 return g.getMPCDistance();
378 nodeTypeFactor = 0; 366 }else if(configuration.realisticGuidance == RealisticGuidance.NodeActivity) {
379 normalFactor = 100; 367 return g.getNADistance();
380 unfinishFactor = 0; 368 }else if(configuration.realisticGuidance == RealisticGuidance.OutDegree) {
381 } 369 return g.getOutDegreeDistance();
382 370 }else if(configuration.realisticGuidance == RealisticGuidance.NodeType) {
383 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor; 371 return g.getNodeTypeDistance();
384 }else if (domain == Domain.Github) { 372 }else if(configuration.realisticGuidance == RealisticGuidance.Composite) {
385 double unfinishFactor = 100 * (1 - (double)factor / targetSize); 373 double consistenceWeights = 5 * factor / (configuration.typeScopes.maxNewElements + 2) * (1- 1.0/(1+violation));
386 double nodeTypeFactor = g.getNodeTypeDistance(); 374 if(domain == Domain.Yakindumm) {
387 double normalFactor = 5; 375 double unfinishFactor = 50 * (1 - (double)factor / targetSize);
388 if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) { 376 double nodeTypeFactor = g.getNodeTypeDistance();
389 nodeTypeFactor = 0; 377 double normalFactor = 5;
390 normalFactor = 100; 378 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
391 unfinishFactor *= 0.5; 379 nodeTypeFactor = 0;
392 } 380 normalFactor = 100;
393 381 unfinishFactor = 0;
394 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
395 } else {
396 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
397 double nodeTypeFactor = g.getNodeTypeDistance();
398 double normalFactor = 5;
399 if(currentNodeTypeDistance <= 0.20 || numNodesToGenerate == 1) {
400 nodeTypeFactor = 0;
401 normalFactor = 100;
402 unfinishFactor *= 0.5;
403 }
404
405 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
406 } 382 }
383
384 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
385 }else if (domain == Domain.Ecore) {
386 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
387 double nodeTypeFactor = g.getNodeTypeDistance();
388 double normalFactor = 5;
389 if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) {
390 nodeTypeFactor = 0;
391 normalFactor = 100;
392 unfinishFactor *= 0.5;
393 }
394
395 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
407 }else { 396 }else {
408 return violation; 397 double unfinishFactor = context.calculateFitness().get("CompositeUnfinishednessObjective");
409 } 398 double nodeTypeFactor = g.getNodeTypeDistance();
410 } 399 double normalFactor = 5;
411 400 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
412 private int getNumberOfViolations(Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers) { 401 nodeTypeFactor = 0;
413 int violations = matchers.stream().mapToInt(m -> m.countMatches()).sum(); 402 normalFactor = 100;
414 403 //unfinishFactor *= 0.5;
415 return violations; 404 }
416 } 405
417 406 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + 2*g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
418 // Modified epsilon greedy choose for action based on value function
419 // with probability epsilon, choose the state with probability based on the weight
420 // with probability 1 - epsilon, choose the best state
421 // epsilon should decay w.r.t. time
422 private Object drawWithEpsilonProbabilty(List<Object> activationIds, Map<Object, Double> valueMap, double epsilon, double currentDraw) {
423 if(activationIds.size() <= 0) {
424 return null;
425 } 407 }
426 408
427 // if epsilon is smaller than current draw, return greedy choice 409 }else if(configuration.realisticGuidance == RealisticGuidance.Composite_Without_Violations) {
428 if(epsilon < currentDraw) { 410 if(domain == Domain.Yakindumm) {
429 return activationIds.remove(0); 411 double unfinishFactor = 50 * (1 - (double)factor / targetSize);
430 }else { 412 double nodeTypeFactor = g.getNodeTypeDistance();
431 //else return draw with probability of the weights 413 double normalFactor = 5;
432 //find the sum of all 1-weights: the smaller the better 414 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
433 double sum = valueMap.values().stream().mapToDouble(d->1).sum(); 415 nodeTypeFactor = 0;
434 double rand = Math.random() * sum; 416 normalFactor = 100;
435 double iterator = 0.0; 417 unfinishFactor = 0;
436 Object idToReturn = null; 418 }
437 419
438 // draw an item with probability 420 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
439 for(Object o : valueMap.keySet()) { 421 }else if (domain == Domain.Github) {
440 iterator += (1); 422 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
441 if(rand < iterator) { 423 double nodeTypeFactor = g.getNodeTypeDistance();
442 idToReturn = o; 424 double normalFactor = 5;
443 break; 425 if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) {
444 } 426 nodeTypeFactor = 0;
427 normalFactor = 100;
428 unfinishFactor *= 0.5;
429 }
430
431 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
432 } else {
433 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
434 double nodeTypeFactor = g.getNodeTypeDistance();
435 double normalFactor = 5;
436 if(currentNodeTypeDistance <= 0.20 || numNodesToGenerate == 1) {
437 nodeTypeFactor = 0;
438 normalFactor = 100;
439 unfinishFactor *= 0.5;
445 } 440 }
446 441
447 //delete the item from the list 442 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
448 activationIds.remove(idToReturn);
449 valueMap.remove(idToReturn);
450 return idToReturn;
451 } 443 }
444 }else {
445 return violation;
452 } 446 }
447 }
448
449 private int getNumberOfViolations(Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers) {
450 int violations = matchers.stream().mapToInt(m -> m.countMatches()).sum();
453 451
454 private List<Object> selectActivation() { 452 return violations;
455 List<Object> activationIds; 453 }
456 try { 454
457 activationIds = new ArrayList<Object>(context.getCurrentActivationIds()); 455 // Modified epsilon greedy choose for action based on value function
458 if(stateAndActivations.containsKey(context.getCurrentStateId())) { 456 // with probability epsilon, choose the state with probability based on the weight
459 activationIds.removeAll(stateAndActivations.get(context.getCurrentStateId())); 457 // with probability 1 - epsilon, choose the best state
458 // epsilon should decay w.r.t. time
459 private Object drawWithEpsilonProbabilty(List<Object> activationIds, Map<Object, Double> valueMap, double epsilon, double currentDraw) {
460 if(activationIds.size() <= 0) {
461 return null;
462 }
463
464 // if epsilon is smaller than current draw, return greedy choice
465 if(epsilon < currentDraw) {
466 return activationIds.remove(0);
467 }else {
468 //else return draw with probability of the weights
469 //find the sum of all 1-weights: the smaller the better
470 double sum = valueMap.values().stream().mapToDouble(d->1).sum();
471 double rand = Math.random() * sum;
472 double iterator = 0.0;
473 Object idToReturn = null;
474
475 // draw an item with probability
476 for(Object o : valueMap.keySet()) {
477 iterator += (1);
478 if(rand < iterator) {
479 idToReturn = o;
480 break;
460 } 481 }
461 Collections.shuffle(activationIds);
462 } catch (NullPointerException e) {
463 numberOfStatecoderFail++;
464 activationIds = Collections.emptyList();
465 } 482 }
466 return activationIds; 483
484 //delete the item from the list
485 activationIds.remove(idToReturn);
486 valueMap.remove(idToReturn);
487 return idToReturn;
467 } 488 }
489 }
490
491 private List<Object> selectActivation() {
492 List<Object> activationIds;
493 try {
494 activationIds = this.activationSelector.randomizeActivationIDs(context.getUntraversedActivationIds());
495 } catch (NullPointerException e) {
496 numberOfStatecoderFail++;
497 activationIds = Collections.emptyList();
498 }
499 return activationIds;
500 }
468 501
469 private void checkForSolution(final Fitness fittness) { 502 private void checkForSolution(final Fitness fittness) {
470 if (fittness.isSatisifiesHardObjectives()) { 503 if (fittness.isSatisifiesHardObjectives()) {
471 logger.debug("Solution Found!!"); 504 logger.debug("Solution Found!!");
472 logger.debug("# violations: " + (getNumberOfViolations(mustMatchers))); 505 logger.debug("# violations: " + (getNumberOfViolations(mustMatchers)));
473 if (solutionStoreWithDiversityDescriptor.isDifferent(context)) { 506 if (solutionStoreWithDiversityDescriptor.isDifferent(context)) {
474 solutionStoreWithCopy.newSolution(context); 507 solutionStoreWithCopy.newSolution(context);
475 solutionStoreWithDiversityDescriptor.newSolution(context); 508 solutionStoreWithDiversityDescriptor.newSolution(context);
476 solutionStore.newSolution(context); 509 solutionStore.newSolution(context);
477 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolution); 510 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolutions);
478 511
479 logger.debug("Found a solution."); 512 logger.debug("Found a solution.");
480 }
481 } 513 }
482 } 514 }
515 }
516
517 public List<String> times = new LinkedList<String>();
518 private void saveTimes() {
519 long forwardTime = context.getDesignSpaceManager().getForwardTime()/1000000;
520 long backtrackingTime = context.getDesignSpaceManager().getBacktrackingTime()/1000000;
521 long statecoderTime = ((NeighbourhoodBasedPartialInterpretationStateCoder)this.context.getStateCoder()).getStatecoderRuntime()/1000000;
522 long solutionCopy = solutionStoreWithCopy.getSumRuntime()/1000000;
523 long activationSelection = this.activationSelector.getRuntime()/1000000;
524// long numericalSolverSumTime = this.numericSolver.getRuntime()/1000000;
525// long numericalSolverProblemForming = this.numericSolver.getSolverSolvingProblem()/1000000;
526// long numericalSolverSolving = this.numericSolver.getSolverSolvingProblem()/1000000;
527// long numericalSolverInterpreting = this.numericSolver.getSolverSolution()/1000000;
528 long metricCalculationTime = this.method.getStatistics().metricCalculationTime / 1000000;
529 this.times.add(
530 "(TransformationExecutionTime"+method.getStatistics().transformationExecutionTime/1000000+
531 "|ForwardTime:"+forwardTime+
532 "|Backtrackingtime:"+backtrackingTime+
533 "|StateCoderTime:"+statecoderTime+
534 "|SolutionCopyTime:"+solutionCopy+
535 "|ActivationSelectionTime:"+activationSelection+
536 //"|NumericalSolverSumTime:"+numericalSolverSumTime+
537 //"|NumericalSolverProblemFormingTime:"+numericalSolverProblemForming+
538 //"|NumericalSolverSolvingTime:"+numericalSolverSolving+
539 //"|NumericalSolverInterpretingSolution:"+numericalSolverInterpreting+
540 "|MetricCalculationTime:"+metricCalculationTime + ")"
541 );
542
543 }
483 544
484 @Override 545 @Override
485 public void interruptStrategy() { 546 public void interruptStrategy() {
486 isInterrupted = true; 547 isInterrupted = true;
487 } 548 }
488 549
489 550
490 private TrajectoryWithFitness selectState() { 551 private TrajectoryWithFitness selectState() {
491 int randomNumber = random.nextInt(configuration.randomBacktrackChance); 552 int randomNumber = random.nextInt(configuration.randomBacktrackChance);
492 if (randomNumber == 0) { 553 if (randomNumber == 0) {
493 int elements = trajectoiresToExplore.size(); 554 int elements = trajectoiresToExplore.size();
494 int randomElementIndex = random.nextInt(elements); 555 int randomElementIndex = random.nextInt(elements);
495 logger.debug("Randomly backtract to the " + randomElementIndex + " best solution..."); 556 logger.debug("Randomly backtract to the " + randomElementIndex + " best solution...");
496 Iterator<TrajectoryWithFitness> iterator = trajectoiresToExplore.iterator(); 557 Iterator<TrajectoryWithFitness> iterator = trajectoiresToExplore.iterator();
497 while (randomElementIndex != 0) { 558 while (randomElementIndex != 0) {
498 iterator.next(); 559 iterator.next();
499 randomElementIndex--; 560 randomElementIndex--;
500 } 561 }
501 TrajectoryWithFitness res = iterator.next(); 562 TrajectoryWithFitness res = iterator.next();
502 if (res == null) { 563 if (res == null) {
503 return trajectoiresToExplore.element();
504 } else {
505 return res;
506 }
507 } else {
508 return trajectoiresToExplore.element(); 564 return trajectoiresToExplore.element();
565 } else {
566 return res;
509 } 567 }
510 } 568 } else {
511 569 return trajectoiresToExplore.element();
570 }
571 }
572
512// private void logCurrentStateMetric() { 573// private void logCurrentStateMetric() {
513// if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) { 574// if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) {
514// return; 575// return;
@@ -518,77 +579,80 @@ public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements
518// PartialInterpretationMetric.calculateMetric(interpretation, "debug/metric/" + context.getModel().hashCode(), context.getCurrentStateId().toString()); 579// PartialInterpretationMetric.calculateMetric(interpretation, "debug/metric/" + context.getModel().hashCode(), context.getCurrentStateId().toString());
519// } 580// }
520 581
521 public void visualiseCurrentState() { 582 public void visualiseCurrentState() {
522 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugCongiguration.partialInterpretatioVisualiser; 583 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugConfiguration.partialInterpretatioVisualiser;
523 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) { 584 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) {
524 PartialInterpretation p = (PartialInterpretation) (context.getModel()); 585 PartialInterpretation p = (PartialInterpretation) (context.getModel());
525 int id = ++numberOfPrintedModel; 586 int id = ++numberOfPrintedModel;
526 if (id % configuration.debugCongiguration.partalInterpretationVisualisationFrequency == 0) { 587 if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) {
527 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); 588 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p);
528 visualisation.writeToFile(workspace, String.format("state%09d.png", id)); 589 logger.debug("Visualizing state: " + id + " (" + context.getDesignSpaceManager().getCurrentState() + ")");
529 } 590 String name = String.format("state%09d", id);
591 visualisation.writeToFile(workspace, name + ".png");
592 workspace.writeModel((EObject) context.getModel(), name + ".xmi");
530 } 593 }
531 } 594 }
595 }
532 596
533 protected boolean checkConsistency(TrajectoryWithFitness t) { 597 protected boolean checkConsistency(TrajectoryWithFitness t) {
534 LogicReasoner internalIncosnsitencyDetector = configuration.internalConsistencyCheckerConfiguration.internalIncosnsitencyDetector; 598 LogicReasoner internalIncosnsitencyDetector = configuration.internalConsistencyCheckerConfiguration.internalIncosnsitencyDetector;
535 if (internalIncosnsitencyDetector!= null) { 599 if (internalIncosnsitencyDetector!= null) {
536 int id = ++numberOfSolverCalls; 600 int id = ++numberOfSolverCalls;
537 if (id % configuration.internalConsistencyCheckerConfiguration.incternalConsistencyCheckingFrequency == 0) { 601 if (id % configuration.internalConsistencyCheckerConfiguration.incternalConsistencyCheckingFrequency == 0) {
538 try { 602 try {
539 PartialInterpretation interpretation = (PartialInterpretation) (context.getModel()); 603 PartialInterpretation interpretation = (PartialInterpretation) (context.getModel());
540 PartialInterpretation copied = EcoreUtil.copy(interpretation); 604 PartialInterpretation copied = EcoreUtil.copy(interpretation);
541 this.partialInterpretation2Logic.transformPartialIntepretation2Logic(copied.getProblem(), copied); 605 this.partialInterpretation2Logic.transformPartialIntepretation2Logic(copied.getProblem(), copied);
542 LogicProblem newProblem = copied.getProblem(); 606 LogicProblem newProblem = copied.getProblem();
543 607
544 this.configuration.typeScopes.maxNewElements = interpretation.getMaxNewElements(); 608 this.configuration.typeScopes.maxNewElements = interpretation.getMaxNewElements();
545 this.configuration.typeScopes.minNewElements = interpretation.getMinNewElements(); 609 this.configuration.typeScopes.minNewElements = interpretation.getMinNewElements();
546 LogicResult result = internalIncosnsitencyDetector.solve(newProblem, configuration, workspace); 610 LogicResult result = internalIncosnsitencyDetector.solve(newProblem, configuration, workspace);
547 if (result instanceof InconsistencyResult) { 611 if (result instanceof InconsistencyResult) {
548 logger.debug("Solver found an Inconsistency!"); 612 logger.debug("Solver found an Inconsistency!");
549 removeSubtreeFromQueue(t); 613 removeSubtreeFromQueue(t);
550 return true; 614 return true;
551 } else if (result instanceof ModelResult) { 615 } else if (result instanceof ModelResult) {
552 logger.debug("Solver found a model!"); 616 logger.debug("Solver found a model!");
553 solutionStore.newSolution(context); 617 solutionStore.newSolution(context);
554 618
555 this.modelResultByInternalSolver = (ModelResult) result; 619 this.modelResultByInternalSolver = (ModelResult) result;
556 return true; 620 return true;
557 } else { 621 } else {
558 logger.debug("Failed consistency check."); 622 logger.debug("Failed consistency check.");
559 return false;
560 }
561 } catch (Exception e) {
562 logger.debug("Problem with internal consistency checking: "+e.getMessage());
563 e.printStackTrace();
564 return false; 623 return false;
565 } 624 }
625 } catch (Exception e) {
626 logger.debug("Problem with internal consistency checking: "+e.getMessage());
627 e.printStackTrace();
628 return false;
566 } 629 }
567
568 } 630 }
569 return false;
570 }
571 631
572 protected void removeSubtreeFromQueue(TrajectoryWithFitness t) {
573 PriorityQueue<TrajectoryWithFitness> previous = this.trajectoiresToExplore;
574 this.trajectoiresToExplore = new PriorityQueue<>(this.comparator);
575 for (TrajectoryWithFitness trajectoryWithFitness : previous) {
576 if (!containsAsSubstring(trajectoryWithFitness.trajectory, t.trajectory)) {
577 this.trajectoiresToExplore.add(trajectoryWithFitness);
578 } else {
579 logger.debug("State has been excluded due to inherent inconsistency");
580 }
581 }
582 } 632 }
633 return false;
634 }
583 635
584 private boolean containsAsSubstring(Object[] full, Object[] substring) { 636 protected void removeSubtreeFromQueue(TrajectoryWithFitness t) {
585 if (substring.length > full.length) { 637 PriorityQueue<TrajectoryWithFitness> previous = this.trajectoiresToExplore;
586 return false; 638 this.trajectoiresToExplore = new PriorityQueue<>(this.comparator);
587 } else if (substring.length == full.length) { 639 for (TrajectoryWithFitness trajectoryWithFitness : previous) {
588 return Arrays.equals(full, substring); 640 if (!containsAsSubstring(trajectoryWithFitness.trajectory, t.trajectory)) {
641 this.trajectoiresToExplore.add(trajectoryWithFitness);
589 } else { 642 } else {
590 Object[] part = Arrays.copyOfRange(full, 0, substring.length); 643 logger.debug("State has been excluded due to inherent inconsistency");
591 return Arrays.equals(part, substring);
592 } 644 }
593 } 645 }
646 }
647
648 private boolean containsAsSubstring(Object[] full, Object[] substring) {
649 if (substring.length > full.length) {
650 return false;
651 } else if (substring.length == full.length) {
652 return Arrays.equals(full, substring);
653 } else {
654 Object[] part = Arrays.copyOfRange(full, 0, substring.length);
655 return Arrays.equals(part, substring);
656 }
657 }
594} 658}
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 9fc6853c..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,99 +1,123 @@
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
9 13
10//class ViatraReasonerNumbers { 14class ModelGenerationCompositeObjective implements IThreeValuedObjective {
11// public static val scopePriority = 2 15 val IObjective scopeObjective
12// public static val unfinishedMultiplicityPriority = 2
13// public static val unifinshedWFPriority = 2
14// //public static val complexityPriority = 4
15//
16// public static val scopeWeigth = 1.0
17// public static val unfinishedMultiplicityWeigth = 1.5
18// public static val unfinishedWFWeigth = 1.5
19// //public static val complexityWeigth = 0.1
20//
21// public static val useCompositeObjective = true
22// public static val compositePriority = 2
23//}
24
25class ModelGenerationCompositeObjective implements IObjective{
26 val ScopeObjective scopeObjective
27 val List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives 16 val List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives
28 val UnfinishedWFObjective unfinishedWFObjective 17 val UnfinishedWFObjective unfinishedWFObjective
29 var boolean isWFOptional = false; 18 var PartialInterpretation model = null
19 val int scopeWeight
20 val int conaintmentWeight
21 val int nonContainmentWeight
22 val int unfinishedWFWeight
30 23
31 public new( 24 new(
32 ScopeObjective scopeObjective, 25 IObjective scopeObjective,
26 List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives,
27 UnfinishedWFObjective unfinishedWFObjective,
28 ViatraReasonerConfiguration configuration)
29 {
30 this(
31 scopeObjective, unfinishedMultiplicityObjectives, unfinishedWFObjective,
32 configuration.scopeWeight, configuration.conaintmentWeight, configuration.nonContainmentWeight,
33 configuration.unfinishedWFWeight
34 )
35 }
36
37 new(
38 IObjective scopeObjective,
33 List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives, 39 List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives,
34 UnfinishedWFObjective unfinishedWFObjective, 40 UnfinishedWFObjective unfinishedWFObjective,
35 boolean isWFOptional) 41 int scopeWeight, int conaintmentWeight, int nonContainmentWeight, int unfinishedWFWeight)
36 { 42 {
37 this.scopeObjective = scopeObjective 43 this.scopeObjective = scopeObjective
38 this.unfinishedMultiplicityObjectives = unfinishedMultiplicityObjectives 44 this.unfinishedMultiplicityObjectives = unfinishedMultiplicityObjectives
39 this.unfinishedWFObjective = unfinishedWFObjective 45 this.unfinishedWFObjective = unfinishedWFObjective
40 this.isWFOptional = isWFOptional; 46
41 } 47 this.scopeWeight = scopeWeight
42 48 this.conaintmentWeight = conaintmentWeight
43 def getIsWFOptional(){ 49 this.nonContainmentWeight = nonContainmentWeight
44 return this.isWFOptional; 50 this.unfinishedWFWeight = unfinishedWFWeight
45 } 51 }
46 52
47 override init(ThreadContext context) { 53 override init(ThreadContext context) {
54 model = context.model as PartialInterpretation
48 this.scopeObjective.init(context) 55 this.scopeObjective.init(context)
49 this.unfinishedMultiplicityObjectives.forEach[it.init(context)] 56 this.unfinishedMultiplicityObjectives.forEach[it.init(context)]
50 this.unfinishedWFObjective.init(context) 57 this.unfinishedWFObjective.init(context)
51 } 58 }
52 59
53 override createNew() { 60 override createNew() {
54 return new ModelGenerationCompositeObjective( 61 return new ModelGenerationCompositeObjective(
55 this.scopeObjective, this.unfinishedMultiplicityObjectives, this.unfinishedWFObjective, this.isWFOptional) 62 scopeObjective.createNew,
63 ImmutableList.copyOf(unfinishedMultiplicityObjectives.map[createNew as UnfinishedMultiplicityObjective]),
64 unfinishedWFObjective.createNew as UnfinishedWFObjective,
65 scopeWeight, conaintmentWeight, nonContainmentWeight, unfinishedWFWeight
66 )
56 } 67 }
57 68
58 override getComparator() { Comparators.LOWER_IS_BETTER } 69 override getComparator() { Comparators.LOWER_IS_BETTER }
70
59 override getFitness(ThreadContext context) { 71 override getFitness(ThreadContext context) {
60 var sum = 0.0 72
61 val scopeFitnes = scopeObjective.getFitness(context) 73 val scopeFitnes = scopeObjective.getFitness(context)
62 //val unfinishedMultiplicitiesFitneses = unfinishedMultiplicityObjectives.map[x|x.getFitness(context)] 74 val unfinishedWFsFitness = unfinishedWFObjective.getFitness(context)
63 75
64 sum+=scopeFitnes 76 var containmentMultiplicity = 0.0
65 var multiplicity = 0.0 77 var nonContainmentMultiplicity = 0.0
66 for(multiplicityObjective : unfinishedMultiplicityObjectives) { 78 for(multiplicityObjective : unfinishedMultiplicityObjectives) {
67 multiplicity+=multiplicityObjective.getFitness(context)//*0.5 79 val multiplicity = multiplicityObjective.getFitness(context)
80// println(multiplicityObjective.name + "=" + multiplicity)
81 if(multiplicityObjective.containment) {
82 containmentMultiplicity+=multiplicity
83 } else {
84 nonContainmentMultiplicity+=multiplicity
85 }
86
68 } 87 }
69 sum+=multiplicity
70 88
71 // the WF can be optional when generating realistic models 89 var sum = 0.0
72 if(!isWFOptional){ 90 sum += scopeFitnes*scopeWeight
73 val unfinishedWFsFitness = unfinishedWFObjective.getFitness(context) 91 sum += containmentMultiplicity*conaintmentWeight
74 sum += unfinishedWFsFitness//*0.5 92 sum += nonContainmentMultiplicity*nonContainmentWeight
75 } 93 sum += unfinishedWFsFitness*unfinishedWFWeight
76 94
77 //println('''Sum=«sum»|Scope=«scopeFitnes»|Multiplicity=«multiplicity»|WFs=«unfinishedWFsFitness»''') 95// println('''scope=«scopeFitnes», containment=«containmentMultiplicity», nonContainment=«nonContainmentMultiplicity», wf=«unfinishedWFsFitness», sum=«sum»''')
78 96
79 return sum 97 return sum
80 } 98 }
81 99
82 override getLevel() { 2 } 100 override getWorstPossibleFitness(ThreadContext threadContext) {
83 override getName() { "CompositeUnfinishednessObjective"} 101 Double.POSITIVE_INFINITY
84 def getObjective(){
85 return this.unfinishedMultiplicityObjectives;
86 } 102 }
87 103
104 override getBestPossibleFitness(ThreadContext threadContext) {
105 0.0
106 }
107
108 override getLevel() { 2 }
109
110 override getName() { "CompositeUnfinishednessObjective" }
111
88 override isHardObjective() { true } 112 override isHardObjective() { true }
89 override satisifiesHardObjective(Double fitness) { fitness <= 0.001 } 113
90 114 override satisifiesHardObjective(Double fitness) { fitness < 0.01 }
91 115
92 override setComparator(Comparator<Double> comparator) { 116 override setComparator(Comparator<Double> comparator) {
93 throw new UnsupportedOperationException("TODO: auto-generated method stub") 117 throw new UnsupportedOperationException("Model generation objective comparator cannot be set.")
94 } 118 }
119
95 override setLevel(int level) { 120 override setLevel(int level) {
96 throw new UnsupportedOperationException("TODO: auto-generated method stub") 121 throw new UnsupportedOperationException("Model generation objective level cannot be set.")
97 } 122 }
98 123}
99} \ 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
new file mode 100644
index 00000000..70e8e9c2
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend
@@ -0,0 +1,192 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatra2logic.NumericTranslator
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BooleanElement
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.IntegerElement
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PrimitiveElement
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.RealElement
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.StringElement
10import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ModelGenerationMethod
11import java.math.BigDecimal
12import java.util.HashMap
13import java.util.LinkedHashMap
14import java.util.LinkedHashSet
15import java.util.List
16import java.util.Map
17import org.eclipse.emf.ecore.EObject
18import org.eclipse.viatra.dse.base.ThreadContext
19import org.eclipse.viatra.query.runtime.api.IPatternMatch
20import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
21import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint
22
23class NumericSolver {
24 val ModelGenerationMethod method
25 var ThreadContext threadContext
26 val constraint2MustUnitPropagationPrecondition = new HashMap<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>>
27 val constraint2CurrentUnitPropagationPrecondition = new HashMap<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>>
28 NumericTranslator t = new NumericTranslator
29
30 val boolean intermediateConsistencyCheck
31 val boolean caching;
32 Map<LinkedHashMap<PConstraint, Iterable<List<Integer>>>,Boolean> satisfiabilityCache = new HashMap
33
34 var long runtime = 0
35 var long cachingTime = 0
36 var int numberOfSolverCalls = 0
37 var int numberOfCachedSolverCalls = 0
38
39 new(ModelGenerationMethod method, boolean intermediateConsistencyCheck, boolean caching) {
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
49 val engine = threadContext.queryEngine
50 for(entry : method.mustUnitPropagationPreconditions.entrySet) {
51 val constraint = entry.key
52 val querySpec = entry.value
53 val matcher = querySpec.getMatcher(engine);
54 constraint2MustUnitPropagationPrecondition.put(constraint,matcher)
55 }
56 for(entry : method.currentUnitPropagationPreconditions.entrySet) {
57 val constraint = entry.key
58 val querySpec = entry.value
59 val matcher = querySpec.getMatcher(engine);
60 constraint2CurrentUnitPropagationPrecondition.put(constraint,matcher)
61 }
62 }
63
64 def getRuntime(){runtime}
65 def getCachingTime(){cachingTime}
66 def getNumberOfSolverCalls(){numberOfSolverCalls}
67 def getNumberOfCachedSolverCalls(){numberOfCachedSolverCalls}
68 def getSolverFormingProblem(){this.t.formingProblemTime}
69 def getSolverSolvingProblem(){this.t.solvingProblemTime}
70 def getSolverSolution(){this.t.formingSolutionTime}
71
72 def boolean maySatisfiable() {
73 if(intermediateConsistencyCheck) {
74 return isSatisfiable(this.constraint2MustUnitPropagationPrecondition)
75 } else {
76 return true
77 }
78 }
79 def boolean currentSatisfiable() {
80 isSatisfiable(this.constraint2CurrentUnitPropagationPrecondition)
81 }
82
83 private def boolean isSatisfiable(Map<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>> matches) {
84 val start = System.nanoTime
85 var boolean finalResult
86 if(matches.empty){
87 finalResult=true
88 } else {
89 val propagatedConstraints = new HashMap
90 for(entry : matches.entrySet) {
91 val constraint = entry.key
92 //println(constraint)
93 val allMatches = entry.value.allMatches.map[it.toArray]
94 //println(allMatches.toList)
95 propagatedConstraints.put(constraint,allMatches)
96 }
97 if(propagatedConstraints.values.forall[empty]) {
98 finalResult=true
99 } else {
100 if(caching) {
101 val code = getCode(propagatedConstraints)
102 val cachedResult = satisfiabilityCache.get(code)
103 if(cachedResult === null) {
104 // println('''new problem, call solver''')
105 // for(entry : code.entrySet) {
106 // println('''«entry.key» -> «entry.value»''')
107 // }
108 //println(code.hashCode)
109 this.numberOfSolverCalls++
110 val res = t.delegateIsSatisfiable(propagatedConstraints)
111 satisfiabilityCache.put(code,res)
112 finalResult=res
113 } else {
114 //println('''similar problem, answer from cache''')
115 finalResult=cachedResult
116 this.numberOfCachedSolverCalls++
117 }
118 } else {
119 finalResult= t.delegateIsSatisfiable(propagatedConstraints)
120 this.numberOfSolverCalls++
121 }
122 }
123 }
124 this.runtime+=System.nanoTime-start
125 return finalResult
126 }
127
128 def getCode(HashMap<PConstraint, Iterable<Object[]>> propagatedConstraints) {
129 val start = System.nanoTime
130 val involvedObjects = new LinkedHashSet(propagatedConstraints.values.flatten.map[toList].flatten.toList).toList
131 val res = new LinkedHashMap(propagatedConstraints.mapValues[matches | matches.map[objects | objects.map[object | involvedObjects.indexOf(object)].toList]])
132 this.cachingTime += System.nanoTime-start
133 return res
134 }
135
136 def fillSolutionCopy(Map<EObject, EObject> trace) {
137 val model = threadContext.getModel as PartialInterpretation
138 val dataObjects = model.newElements.filter(PrimitiveElement).filter[!model.openWorldElements.contains(it)].toList
139 if(constraint2CurrentUnitPropagationPrecondition.empty) {
140 fillWithDefaultValues(dataObjects,trace)
141 } else {
142 val propagatedConstraints = new HashMap
143 for(entry : constraint2CurrentUnitPropagationPrecondition.entrySet) {
144 val constraint = entry.key
145 val allMatches = entry.value.allMatches.map[it.toArray]
146 propagatedConstraints.put(constraint,allMatches)
147 }
148
149 if(propagatedConstraints.values.forall[empty]) {
150 fillWithDefaultValues(dataObjects,trace)
151 } else {
152 val solution = t.delegateGetSolution(dataObjects,propagatedConstraints)
153 fillWithSolutions(dataObjects,solution,trace)
154 }
155 }
156 }
157
158 def protected fillWithDefaultValues(List<PrimitiveElement> elements, Map<EObject, EObject> trace) {
159 for(element : elements) {
160 if(element.valueSet==false) {
161 val value = getDefaultValue(element)
162 val target = trace.get(element) as PrimitiveElement
163 target.fillWithValue(value)
164 }
165 }
166 }
167
168 def protected dispatch getDefaultValue(BooleanElement e) {false}
169 def protected dispatch getDefaultValue(IntegerElement e) {0}
170 def protected dispatch getDefaultValue(RealElement e) {0.0}
171 def protected dispatch getDefaultValue(StringElement e) {""}
172
173 def protected fillWithSolutions(List<PrimitiveElement> elements, Map<PrimitiveElement, Number> solution, Map<EObject, EObject> trace) {
174 for(element : elements) {
175 if(element.valueSet==false) {
176 if(solution.containsKey(element)) {
177 val value = solution.get(element)
178 val target = trace.get(element) as PrimitiveElement
179 target.fillWithValue(value)
180 } else {
181 val target = trace.get(element) as PrimitiveElement
182 target.fillWithValue(target.defaultValue)
183 }
184 }
185 }
186 }
187
188 def protected dispatch fillWithValue(BooleanElement e, Object value) {e.valueSet=true e.value=value as Boolean}
189 def protected dispatch fillWithValue(IntegerElement e, Object value) {e.valueSet=true e.value=value as Integer}
190 def protected dispatch fillWithValue(RealElement e, Object value) {e.valueSet=true e.value=BigDecimal.valueOf(value as Double) }
191 def protected dispatch fillWithValue(StringElement e, Object value) {e.valueSet=true e.value=value as String}
192} \ 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/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 f61c7333..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
@@ -153,14 +154,70 @@ class PartialModelAsLogicInterpretation implements LogicModelInterpretation{
153 } 154 }
154 155
155 override getAllIntegersInStructure() { 156 override getAllIntegersInStructure() {
156 new TreeSet(this.integerForwardTrace.keySet) 157 new TreeSet(allIntegersWithInterpretation.values)
158 }
159
160 override getAllIntegersWithInterpretation() {
161 val builder = new HashMap
162 for (entry : integerForwardTrace.entrySet) {
163 builder.put(entry.value, entry.key)
164 }
165 for (element : partialInterpretation.newElements) {
166 if (element instanceof IntegerElement) {
167 builder.put(element, element.value)
168 }
169 }
170 builder
157 } 171 }
158 172
159 override getAllRealsInStructure() { 173 override getAllRealsInStructure() {
160 new TreeSet(this.realForwardTrace.keySet) 174 new TreeSet(allRealsWithInterpretation.values)
175 }
176
177 override getAllRealsWithInterpretation() {
178 val builder = new HashMap
179 for (entry : realForwardTrace.entrySet) {
180 builder.put(entry.value, entry.key)
181 }
182 for (element : partialInterpretation.newElements) {
183 if (element instanceof RealElement) {
184 builder.put(element, element.value)
185 }
186 }
187 builder
161 } 188 }
162 189
163 override getAllStringsInStructure() { 190 override getAllStringsInStructure() {
164 new TreeSet(this.stringForwardTrace.keySet) 191 new TreeSet(allStringsWithInterpretation.values)
192 }
193
194 override getAllStringsWithInterpretation() {
195 val builder = new HashMap
196 for (entry : stringForwardTrace.entrySet) {
197 builder.put(entry.value, entry.key)
198 }
199 for (element : partialInterpretation.newElements) {
200 if (element instanceof StringElement) {
201 builder.put(element, element.value)
202 }
203 }
204 builder
205 }
206
207 override getAllBooleansInStructure() {
208 new TreeSet(allBooleansWithInterpretation.values)
209 }
210
211 override getAllBooleansWithInterpretation() {
212 val builder = new HashMap
213 for (entry : booleanForwardTrace.entrySet) {
214 builder.put(entry.value, entry.key)
215 }
216 for (element : partialInterpretation.newElements) {
217 if (element instanceof BooleanElement) {
218 builder.put(element, element.value)
219 }
220 }
221 builder
165 } 222 }
166} \ 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 a8b7301e..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
@@ -25,7 +23,7 @@ class SolutionStoreWithCopy {
25 newSolution(context) 23 newSolution(context)
26 }*/ 24 }*/
27 25
28 def newSolution(ThreadContext context) { 26 def Map<EObject,EObject> newSolution(ThreadContext context) {
29 //print(System.nanoTime-initTime + ";") 27 //print(System.nanoTime-initTime + ";")
30 val copyStart = System.nanoTime 28 val copyStart = System.nanoTime
31 val solution = context.model as PartialInterpretation 29 val solution = context.model as PartialInterpretation
@@ -36,6 +34,7 @@ class SolutionStoreWithCopy {
36 copyTraces.add(copier) 34 copyTraces.add(copier)
37 runtime += System.nanoTime - copyStart 35 runtime += System.nanoTime - copyStart
38 solutionTimes.add(System.nanoTime-sartTime) 36 solutionTimes.add(System.nanoTime-sartTime)
37 return copier
39 } 38 }
40 def getSumRuntime() { 39 def getSumRuntime() {
41 return runtime 40 return runtime
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 aad9a448..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,9 +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 }
37
38 def isContainment() {
39 return this.unfinishedMultiplicity.containment
36 } 40 }
37} \ 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}