diff options
author | Kristóf Marussy <marussy@mit.bme.hu> | 2020-06-25 19:55:10 +0200 |
---|---|---|
committer | Kristóf Marussy <marussy@mit.bme.hu> | 2020-06-25 19:55:10 +0200 |
commit | c3a6d4b9cf3657070d180aa65ddbf0459e880329 (patch) | |
tree | 780c4fc61578dcb309af53fb0c164c7627e51676 /Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit | |
parent | New configuration language parser WIP (diff) | |
parent | Scope unsat benchmarks (diff) | |
download | VIATRA-Generator-c3a6d4b9cf3657070d180aa65ddbf0459e880329.tar.gz VIATRA-Generator-c3a6d4b9cf3657070d180aa65ddbf0459e880329.tar.zst VIATRA-Generator-c3a6d4b9cf3657070d180aa65ddbf0459e880329.zip |
Merge branch 'kris'
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit')
29 files changed, 1604 insertions, 418 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..9ef5e091 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,11 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner | 1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner |
2 | 2 | ||
3 | import org.eclipse.viatra.dse.objectives.IGlobalConstraint | 3 | import org.eclipse.viatra.dse.objectives.IGlobalConstraint |
4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod | 4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod |
5 | 5 | ||
6 | abstract class ModelGenerationMethodBasedGlobalConstraint implements IGlobalConstraint { | 6 | abstract class ModelGenerationMethodBasedGlobalConstraint implements IGlobalConstraint { |
7 | val protected ModelGenerationMethod method | 7 | val protected ModelGenerationMethod method |
8 | new(ModelGenerationMethod method) { | 8 | new(ModelGenerationMethod method) { |
9 | this.method = method | 9 | this.method = method |
10 | } | 10 | } |
11 | } \ No newline at end of file | 11 | } |
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 0411ccdd..3033eca7 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 | |||
@@ -1,5 +1,7 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner | 1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner |
2 | 2 | ||
3 | import com.google.common.collect.ImmutableList | ||
4 | import com.google.common.collect.Lists | ||
3 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel | 5 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel |
4 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner | 6 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner |
5 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasonerException | 7 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasonerException |
@@ -10,19 +12,28 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicproblemPackage | |||
10 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicresultFactory | 12 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicresultFactory |
11 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult | 13 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult |
12 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethodProvider | 14 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethodProvider |
13 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator | 15 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy |
14 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser | 16 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser |
15 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | 17 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation |
16 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage | 18 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage |
19 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.AbstractNeighbourhoodBasedStateCoderFactory | ||
17 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory | 20 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory |
18 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedStateCoderFactory | 21 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedHashStateCoderFactory |
22 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.PairwiseNeighbourhoodBasedStateCoderFactory | ||
23 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BasicScopeGlobalConstraint | ||
19 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BestFirstStrategyForModelGeneration | 24 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BestFirstStrategyForModelGeneration |
25 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityChecker | ||
26 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.InconsistentScopeGlobalConstraint | ||
27 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.LoggerSolutionFoundHandler | ||
20 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ModelGenerationCompositeObjective | 28 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ModelGenerationCompositeObjective |
21 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PartialModelAsLogicInterpretation | 29 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PartialModelAsLogicInterpretation |
22 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ScopeObjective | 30 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ScopeObjective |
31 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.SurelyViolatedObjectiveGlobalConstraint | ||
23 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.UnfinishedMultiplicityObjective | 32 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.UnfinishedMultiplicityObjective |
24 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.UnfinishedWFObjective | 33 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ViatraReasonerSolutionSaver |
25 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.WF2ObjectiveConverter | 34 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.WF2ObjectiveConverter |
35 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ThreeValuedCostElement | ||
36 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ThreeValuedCostObjective | ||
26 | import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace | 37 | import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace |
27 | import java.util.List | 38 | import java.util.List |
28 | import java.util.Map | 39 | import java.util.Map |
@@ -31,114 +42,159 @@ import org.eclipse.viatra.dse.api.DesignSpaceExplorer | |||
31 | import org.eclipse.viatra.dse.api.DesignSpaceExplorer.DseLoggingLevel | 42 | import org.eclipse.viatra.dse.api.DesignSpaceExplorer.DseLoggingLevel |
32 | import org.eclipse.viatra.dse.solutionstore.SolutionStore | 43 | import org.eclipse.viatra.dse.solutionstore.SolutionStore |
33 | import org.eclipse.viatra.dse.statecode.IStateCoderFactory | 44 | import org.eclipse.viatra.dse.statecode.IStateCoderFactory |
45 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.NumericSolver | ||
34 | 46 | ||
35 | class ViatraReasoner extends LogicReasoner{ | 47 | class ViatraReasoner extends LogicReasoner { |
36 | val PartialInterpretationInitialiser initialiser = new PartialInterpretationInitialiser() | 48 | val PartialInterpretationInitialiser initialiser = new PartialInterpretationInitialiser() |
37 | val ModelGenerationMethodProvider modelGenerationMethodProvider = new ModelGenerationMethodProvider | 49 | val ModelGenerationMethodProvider modelGenerationMethodProvider = new ModelGenerationMethodProvider |
38 | val extension LogicresultFactory factory = LogicresultFactory.eINSTANCE | 50 | val extension LogicresultFactory factory = LogicresultFactory.eINSTANCE |
39 | val WF2ObjectiveConverter wf2ObjectiveConverter = new WF2ObjectiveConverter | 51 | val WF2ObjectiveConverter wf2ObjectiveConverter = new WF2ObjectiveConverter |
40 | 52 | ||
41 | 53 | override solve(LogicProblem problem, LogicSolverConfiguration configuration, | |
42 | override solve(LogicProblem problem, LogicSolverConfiguration configuration, ReasonerWorkspace workspace) throws LogicReasonerException { | 54 | ReasonerWorkspace workspace) throws LogicReasonerException { |
43 | val viatraConfig = configuration.asConfig | 55 | val viatraConfig = configuration.asConfig |
44 | 56 | ||
45 | if(viatraConfig.debugCongiguration.logging) { | 57 | if (viatraConfig.documentationLevel == DocumentationLevel.FULL) { |
46 | DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.VERBOSE_FULL) | 58 | DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.VERBOSE_FULL) |
47 | } else { | 59 | } else { |
48 | DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.WARN) | 60 | DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.WARN) |
49 | } | 61 | } |
50 | 62 | ||
51 | val DesignSpaceExplorer dse = new DesignSpaceExplorer(); | 63 | val DesignSpaceExplorer dse = new DesignSpaceExplorer(); |
52 | 64 | ||
53 | dse.addMetaModelPackage(LogiclanguagePackage.eINSTANCE) | 65 | dse.addMetaModelPackage(LogiclanguagePackage.eINSTANCE) |
54 | dse.addMetaModelPackage(LogicproblemPackage.eINSTANCE) | 66 | dse.addMetaModelPackage(LogicproblemPackage.eINSTANCE) |
55 | dse.addMetaModelPackage(PartialinterpretationPackage.eINSTANCE) | 67 | dse.addMetaModelPackage(PartialinterpretationPackage.eINSTANCE) |
56 | 68 | ||
57 | val transformationStartTime = System.nanoTime | 69 | val transformationStartTime = System.nanoTime |
58 | 70 | val emptySolution = initialiser.initialisePartialInterpretation(problem, viatraConfig.typeScopes).output | |
59 | 71 | if ((viatraConfig.documentationLevel == DocumentationLevel::FULL || | |
60 | val emptySolution = initialiser.initialisePartialInterpretation(problem,viatraConfig.typeScopes).output | 72 | viatraConfig.documentationLevel == DocumentationLevel::NORMAL) && workspace !== null) { |
61 | if((viatraConfig.documentationLevel == DocumentationLevel::FULL || viatraConfig.documentationLevel == DocumentationLevel::NORMAL) && workspace !== null) { | 73 | workspace.writeModel(emptySolution, "init.partialmodel") |
62 | workspace.writeModel(emptySolution,"init.partialmodel") | 74 | } |
63 | } | 75 | |
64 | emptySolution.problemConainer = problem | 76 | emptySolution.problemConainer = problem |
65 | 77 | var BasicScopeGlobalConstraint basicScopeGlobalConstraint = null | |
66 | val ScopePropagator scopePropagator = new ScopePropagator(emptySolution) | 78 | if (viatraConfig.scopePropagatorStrategy == ScopePropagatorStrategy.None) { |
67 | scopePropagator.propagateAllScopeConstraints | 79 | basicScopeGlobalConstraint = new BasicScopeGlobalConstraint(emptySolution) |
68 | 80 | emptySolution.scopes.clear | |
81 | } | ||
82 | |||
69 | val method = modelGenerationMethodProvider.createModelGenerationMethod( | 83 | val method = modelGenerationMethodProvider.createModelGenerationMethod( |
70 | problem, | 84 | problem, |
71 | emptySolution, | 85 | emptySolution, |
72 | workspace, | 86 | workspace, |
73 | viatraConfig.nameNewElements, | 87 | viatraConfig.nameNewElements, |
74 | viatraConfig.typeInferenceMethod, | 88 | viatraConfig.typeInferenceMethod, |
75 | scopePropagator, | 89 | viatraConfig.scopePropagatorStrategy, |
76 | viatraConfig.documentationLevel, | 90 | viatraConfig.hints, |
77 | viatraConfig.calculateObjectCreationCosts | 91 | viatraConfig.documentationLevel |
78 | ) | 92 | ) |
79 | //println("parsed") | 93 | |
80 | |||
81 | dse.addObjective(new ModelGenerationCompositeObjective( | 94 | dse.addObjective(new ModelGenerationCompositeObjective( |
82 | new ScopeObjective, | 95 | basicScopeGlobalConstraint ?: new ScopeObjective, |
83 | method.unfinishedMultiplicities.map[new UnfinishedMultiplicityObjective(it)], | 96 | method.unfinishedMultiplicities.map[new UnfinishedMultiplicityObjective(it)], |
84 | new UnfinishedWFObjective(method.unfinishedWF), | 97 | wf2ObjectiveConverter.createCompletenessObjective(method.unfinishedWF), |
85 | viatraConfig | 98 | viatraConfig |
86 | )) | 99 | )) |
87 | 100 | ||
88 | dse.addGlobalConstraint(wf2ObjectiveConverter.createInvalidationObjective(method.invalidWF)) | 101 | val extremalObjectives = Lists.newArrayListWithExpectedSize(viatraConfig.costObjectives.size) |
89 | for(additionalConstraint : viatraConfig.searchSpaceConstraints.additionalGlobalConstraints) { | 102 | for (entry : viatraConfig.costObjectives.indexed) { |
103 | val objectiveName = '''costObjective«entry.key»''' | ||
104 | val objectiveConfig = entry.value | ||
105 | val elementsBuilder = ImmutableList.builder | ||
106 | for (elementConfig : objectiveConfig.elements) { | ||
107 | val relationName = elementConfig.patternQualifiedName | ||
108 | val modalQueries = method.modalRelationQueries.get(relationName) | ||
109 | if (modalQueries === null) { | ||
110 | throw new IllegalArgumentException("Unknown relation: " + relationName) | ||
111 | } | ||
112 | elementsBuilder.add(new ThreeValuedCostElement( | ||
113 | modalQueries.currentQuery, | ||
114 | modalQueries.mayQuery, | ||
115 | modalQueries.mustQuery, | ||
116 | elementConfig.weight | ||
117 | )) | ||
118 | } | ||
119 | val costElements = elementsBuilder.build | ||
120 | val costObjective = new ThreeValuedCostObjective(objectiveName, costElements, objectiveConfig.kind, | ||
121 | objectiveConfig.threshold, 3) | ||
122 | dse.addObjective(costObjective) | ||
123 | if (objectiveConfig.findExtremum) { | ||
124 | extremalObjectives += costObjective | ||
125 | } | ||
126 | } | ||
127 | |||
128 | val numberOfRequiredSolutions = configuration.solutionScope.numberOfRequiredSolutions | ||
129 | val solutionStore = if (extremalObjectives.empty) { | ||
130 | new SolutionStore(numberOfRequiredSolutions) | ||
131 | } else { | ||
132 | new SolutionStore() | ||
133 | } | ||
134 | solutionStore.registerSolutionFoundHandler(new LoggerSolutionFoundHandler(viatraConfig)) | ||
135 | val diversityChecker = DiversityChecker.of(viatraConfig.diversityRequirement) | ||
136 | val numericSolver = new NumericSolver(method, viatraConfig.runIntermediateNumericalConsistencyChecks, false) | ||
137 | val solutionSaver = new ViatraReasonerSolutionSaver(newArrayList(extremalObjectives), numberOfRequiredSolutions, | ||
138 | diversityChecker, numericSolver) | ||
139 | val solutionCopier = solutionSaver.solutionCopier | ||
140 | solutionStore.withSolutionSaver(solutionSaver) | ||
141 | dse.solutionStore = solutionStore | ||
142 | |||
143 | dse.addGlobalConstraint(wf2ObjectiveConverter.createInvalidationGlobalConstraint(method.invalidWF)) | ||
144 | dse.addGlobalConstraint(new SurelyViolatedObjectiveGlobalConstraint(solutionSaver)) | ||
145 | dse.addGlobalConstraint(new InconsistentScopeGlobalConstraint) | ||
146 | if (basicScopeGlobalConstraint !== null) { | ||
147 | dse.addGlobalConstraint(basicScopeGlobalConstraint) | ||
148 | } | ||
149 | for (additionalConstraint : viatraConfig.searchSpaceConstraints.additionalGlobalConstraints) { | ||
90 | dse.addGlobalConstraint(additionalConstraint.apply(method)) | 150 | dse.addGlobalConstraint(additionalConstraint.apply(method)) |
91 | } | 151 | } |
92 | 152 | ||
93 | dse.setInitialModel(emptySolution,false) | 153 | dse.setInitialModel(emptySolution, false) |
94 | 154 | ||
95 | val IStateCoderFactory statecoder = if(viatraConfig.stateCoderStrategy == StateCoderStrategy.Neighbourhood) { | 155 | val IStateCoderFactory statecoder = switch (viatraConfig.stateCoderStrategy) { |
96 | new NeighbourhoodBasedStateCoderFactory | 156 | case Neighbourhood: |
97 | } else { | 157 | new NeighbourhoodBasedHashStateCoderFactory |
98 | new IdentifierBasedStateCoderFactory | 158 | case PairwiseNeighbourhood: |
159 | new PairwiseNeighbourhoodBasedStateCoderFactory | ||
160 | default: | ||
161 | new IdentifierBasedStateCoderFactory | ||
99 | } | 162 | } |
100 | dse.stateCoderFactory = statecoder | 163 | dse.stateCoderFactory = statecoder |
101 | 164 | ||
102 | dse.maxNumberOfThreads = 1 | 165 | dse.maxNumberOfThreads = 1 |
103 | 166 | ||
104 | val solutionStore = new SolutionStore(configuration.solutionScope.numberOfRequiredSolution) | 167 | for (rule : method.relationRefinementRules) { |
105 | dse.solutionStore = solutionStore | ||
106 | |||
107 | for(rule : method.relationRefinementRules) { | ||
108 | dse.addTransformationRule(rule) | 168 | dse.addTransformationRule(rule) |
109 | } | 169 | } |
110 | for(rule : method.objectRefinementRules) { | 170 | for (rule : method.objectRefinementRules) { |
111 | dse.addTransformationRule(rule) | 171 | dse.addTransformationRule(rule) |
112 | } | 172 | } |
113 | 173 | ||
114 | val strategy = new BestFirstStrategyForModelGeneration(workspace,viatraConfig,method) | 174 | val strategy = new BestFirstStrategyForModelGeneration(workspace, viatraConfig, method, solutionSaver, numericSolver) |
115 | viatraConfig.progressMonitor.workedForwardTransformation | 175 | viatraConfig.progressMonitor.workedForwardTransformation |
116 | val transformationFinished = System.nanoTime | 176 | val transformationFinished = System.nanoTime |
117 | val transformationTime = transformationFinished - transformationStartTime | 177 | val transformationTime = transformationFinished - transformationStartTime |
118 | |||
119 | val solverStartTime = System.nanoTime | 178 | val solverStartTime = System.nanoTime |
120 | 179 | ||
121 | var boolean stoppedByTimeout | 180 | var boolean stoppedByTimeout |
122 | var boolean stoppedByException | 181 | try { |
123 | try{ | 182 | stoppedByTimeout = dse.startExplorationWithTimeout(strategy, configuration.runtimeLimit * 1000); |
124 | stoppedByTimeout = dse.startExplorationWithTimeout(strategy,configuration.runtimeLimit*1000); | ||
125 | stoppedByException = false | ||
126 | } catch (NullPointerException npe) { | 183 | } catch (NullPointerException npe) { |
127 | stoppedByTimeout = false | 184 | stoppedByTimeout = false |
128 | stoppedByException = true | ||
129 | } | 185 | } |
130 | val solverTime = System.nanoTime - solverStartTime | 186 | val solverTime = System.nanoTime - solverStartTime |
131 | viatraConfig.progressMonitor.workedSearchFinished | 187 | viatraConfig.progressMonitor.workedSearchFinished |
132 | 188 | ||
133 | //additionalMatches = strategy.solutionStoreWithCopy.additionalMatches | 189 | // additionalMatches = strategy.solutionStoreWithCopy.additionalMatches |
134 | val statistics = createStatistics => [ | 190 | val statistics = createStatistics => [ |
135 | //it.solverTime = viatraConfig.runtimeLimit | 191 | // it.solverTime = viatraConfig.runtimeLimit |
136 | it.solverTime = (solverTime/1000000) as int | 192 | it.solverTime = (solverTime / 1000000) as int |
137 | it.transformationTime = (transformationTime/1000000) as int | 193 | it.transformationTime = (transformationTime / 1000000) as int |
138 | for(x : 0..<strategy.solutionStoreWithCopy.allRuntimes.size) { | 194 | for (pair : solutionCopier.getAllCopierRuntimes(true).indexed) { |
139 | it.entries += createIntStatisticEntry => [ | 195 | it.entries += createIntStatisticEntry => [ |
140 | it.name = '''Solution«x+1»FoundAt''' | 196 | it.name = '''_Solution«pair.key»FoundAt''' |
141 | it.value = (strategy.solutionStoreWithCopy.allRuntimes.get(x)/1000000) as int | 197 | it.value = (pair.value / 1000000) as int |
142 | ] | 198 | ] |
143 | } | 199 | } |
144 | for(x: 0..<strategy.times.size) { | 200 | for(x: 0..<strategy.times.size) { |
@@ -151,16 +207,32 @@ class ViatraReasoner extends LogicReasoner{ | |||
151 | it.name = "ExplorationInitializationTime" it.value = ((strategy.explorationStarted-transformationFinished)/1000000) as int | 207 | it.name = "ExplorationInitializationTime" it.value = ((strategy.explorationStarted-transformationFinished)/1000000) as int |
152 | ] | 208 | ] |
153 | it.entries += createIntStatisticEntry => [ | 209 | it.entries += createIntStatisticEntry => [ |
154 | it.name = "TransformationExecutionTime" it.value = (method.statistics.transformationExecutionTime/1000000) as int | 210 | it.name = "TransformationExecutionTime" |
211 | it.value = (method.statistics.transformationExecutionTime / 1000000) as int | ||
212 | ] | ||
213 | it.entries += createIntStatisticEntry => [ | ||
214 | it.name = "ScopePropagationTime" | ||
215 | it.value = (method.statistics.scopePropagationTime / 1000000) as int | ||
155 | ] | 216 | ] |
156 | it.entries += createIntStatisticEntry => [ | 217 | it.entries += createIntStatisticEntry => [ |
157 | it.name = "TypeAnalysisTime" it.value = (method.statistics.PreliminaryTypeAnalisisTime/1000000) as int | 218 | it.name = "TypeAnalysisTime" |
219 | it.value = (method.statistics.preliminaryTypeAnalisisTime / 1000000) as int | ||
158 | ] | 220 | ] |
159 | it.entries += createIntStatisticEntry => [ | 221 | it.entries += createIntStatisticEntry => [ |
160 | it.name = "StateCoderTime" it.value = (statecoder.runtime/1000000) as int | 222 | it.name = "StateCoderTime" |
223 | it.value = (statecoder.runtime / 1000000) as int | ||
161 | ] | 224 | ] |
162 | it.entries += createIntStatisticEntry => [ | 225 | it.entries += createIntStatisticEntry => [ |
163 | it.name = "StateCoderFailCount" it.value = strategy.numberOfStatecoderFail | 226 | it.name = "StateCoderFailCount" |
227 | it.value = strategy.numberOfStatecoderFail | ||
228 | ] | ||
229 | it.entries += createIntStatisticEntry => [ | ||
230 | it.name = "SolutionCopyTime" | ||
231 | it.value = (solutionCopier.getTotalCopierRuntime / 1000000) as int | ||
232 | ] | ||
233 | it.entries += createIntStatisticEntry => [ | ||
234 | it.name = "States" | ||
235 | it.value = dse.numberOfStates as int | ||
164 | ] | 236 | ] |
165 | it.entries += createIntStatisticEntry => [ | 237 | it.entries += createIntStatisticEntry => [ |
166 | it.name = "ForwardTime" it.value = (strategy.forwardTime/1000000) as int | 238 | it.name = "ForwardTime" it.value = (strategy.forwardTime/1000000) as int |
@@ -175,12 +247,28 @@ class ViatraReasoner extends LogicReasoner{ | |||
175 | it.name = "FitnessCalculationTime" it.value = (strategy.fitnessCalculationTime/1000000) as int | 247 | it.name = "FitnessCalculationTime" it.value = (strategy.fitnessCalculationTime/1000000) as int |
176 | ] | 248 | ] |
177 | it.entries += createIntStatisticEntry => [ | 249 | it.entries += createIntStatisticEntry => [ |
178 | it.name = "SolutionCopyTime" it.value = (strategy.solutionStoreWithCopy.sumRuntime/1000000) as int | 250 | it.name = "SolutionCopyTime" it.value = (solutionSaver.totalCopierRuntime/1000000) as int |
179 | ] | 251 | ] |
180 | it.entries += createIntStatisticEntry => [ | 252 | it.entries += createIntStatisticEntry => [ |
181 | it.name = "ActivationSelectionTime" it.value = (strategy.activationSelector.runtime/1000000) as int | 253 | it.name = "ActivationSelectionTime" it.value = (strategy.activationSelector.runtime/1000000) as int |
182 | ] | 254 | ] |
183 | it.entries += createIntStatisticEntry => [ | 255 | it.entries += createIntStatisticEntry => [ |
256 | it.name = "Decisions" | ||
257 | it.value = method.statistics.decisionsTried | ||
258 | ] | ||
259 | it.entries += createIntStatisticEntry => [ | ||
260 | it.name = "Transformations" | ||
261 | it.value = method.statistics.transformationInvocations | ||
262 | ] | ||
263 | it.entries += createIntStatisticEntry => [ | ||
264 | it.name = "ScopePropagations" | ||
265 | it.value = method.statistics.scopePropagatorInvocations | ||
266 | ] | ||
267 | it.entries += createIntStatisticEntry => [ | ||
268 | it.name = "ScopePropagationsSolverCalls" | ||
269 | it.value = method.statistics.scopePropagatorSolverInvocations | ||
270 | ] | ||
271 | it.entries += createIntStatisticEntry => [ | ||
184 | it.name = "NumericalSolverSumTime" it.value = (strategy.numericSolver.runtime/1000000) as int | 272 | it.name = "NumericalSolverSumTime" it.value = (strategy.numericSolver.runtime/1000000) as int |
185 | ] | 273 | ] |
186 | it.entries += createIntStatisticEntry => [ | 274 | it.entries += createIntStatisticEntry => [ |
@@ -201,61 +289,67 @@ class ViatraReasoner extends LogicReasoner{ | |||
201 | it.entries += createIntStatisticEntry => [ | 289 | it.entries += createIntStatisticEntry => [ |
202 | it.name = "NumericalSolverCachedAnswerNumber" it.value = strategy.numericSolver.numberOfCachedSolverCalls | 290 | it.name = "NumericalSolverCachedAnswerNumber" it.value = strategy.numericSolver.numberOfCachedSolverCalls |
203 | ] | 291 | ] |
204 | if(strategy.solutionStoreWithDiversityDescriptor.isActive) { | 292 | if(diversityChecker.active) { |
205 | it.entries += createIntStatisticEntry => [ | 293 | it.entries += createIntStatisticEntry => [ |
206 | it.name = "SolutionDiversityCheckTime" it.value = (strategy.solutionStoreWithDiversityDescriptor.sumRuntime/1000000) as int | 294 | it.name = "SolutionDiversityCheckTime" |
295 | it.value = (diversityChecker.totalRuntime / 1000000) as int | ||
207 | ] | 296 | ] |
208 | it.entries += createRealStatisticEntry => [ | 297 | it.entries += createRealStatisticEntry => [ |
209 | it.name = "SolutionDiversitySuccessRate" it.value = strategy.solutionStoreWithDiversityDescriptor.successRate | 298 | it.name = "SolutionDiversitySuccessRate" |
299 | it.value = diversityChecker.successRate | ||
210 | ] | 300 | ] |
211 | } | 301 | } |
212 | ] | 302 | ] |
213 | 303 | ||
214 | viatraConfig.progressMonitor.workedBackwardTransformationFinished | 304 | viatraConfig.progressMonitor.workedBackwardTransformationFinished |
215 | 305 | ||
216 | if(stoppedByTimeout) { | 306 | if (stoppedByTimeout) { |
217 | return createInsuficientResourcesResult=>[ | 307 | return createInsuficientResourcesResult => [ |
218 | it.problem = problem | 308 | it.problem = problem |
219 | it.resourceName="time" | 309 | it.resourceName = "time" |
220 | it.representation += strategy.solutionStoreWithCopy.solutions | 310 | it.representation += solutionCopier.getPartialInterpretations(true) |
221 | it.statistics = statistics | 311 | it.statistics = statistics |
222 | ] | 312 | ] |
223 | } else { | 313 | } else { |
224 | if(solutionStore.solutions.empty) { | 314 | if (solutionStore.solutions.empty) { |
225 | return createInconsistencyResult => [ | 315 | return createInconsistencyResult => [ |
226 | it.problem = problem | 316 | it.problem = problem |
227 | it.representation += strategy.solutionStoreWithCopy.solutions | 317 | it.representation += solutionCopier.getPartialInterpretations(true) |
228 | it.statistics = statistics | 318 | it.statistics = statistics |
229 | ] | 319 | ] |
230 | } else { | 320 | } else { |
231 | return createModelResult => [ | 321 | return createModelResult => [ |
232 | it.problem = problem | 322 | it.problem = problem |
233 | it.trace = strategy.solutionStoreWithCopy.copyTraces | 323 | it.trace = solutionCopier.getTraces(true) |
234 | it.representation += strategy.solutionStoreWithCopy.solutions | 324 | it.representation += solutionCopier.getPartialInterpretations(true) |
235 | it.statistics = statistics | 325 | it.statistics = statistics |
236 | ] | 326 | ] |
237 | } | 327 | } |
238 | } | 328 | } |
239 | } | 329 | } |
240 | 330 | ||
241 | private def dispatch long runtime(NeighbourhoodBasedStateCoderFactory sc) { | 331 | private def dispatch long runtime(AbstractNeighbourhoodBasedStateCoderFactory sc) { |
242 | sc.sumStatecoderRuntime | 332 | sc.sumStatecoderRuntime |
243 | } | 333 | } |
244 | 334 | ||
245 | private def dispatch long runtime(IdentifierBasedStateCoderFactory sc) { | 335 | private def dispatch long runtime(IdentifierBasedStateCoderFactory sc) { |
246 | sc.sumStatecoderRuntime | 336 | sc.sumStatecoderRuntime |
247 | } | 337 | } |
248 | 338 | ||
249 | override getInterpretations(ModelResult modelResult) { | 339 | override getInterpretations(ModelResult modelResult) { |
250 | val indexes = 0..<modelResult.representation.size | 340 | val indexes = 0 ..< modelResult.representation.size |
251 | val traces = modelResult.trace as List<Map<EObject, EObject>>; | 341 | val traces = modelResult.trace as List<Map<EObject, EObject>>; |
252 | val res = indexes.map[i | new PartialModelAsLogicInterpretation(modelResult.representation.get(i) as PartialInterpretation,traces.get(i))].toList | 342 | val res = indexes.map [ i | |
343 | new PartialModelAsLogicInterpretation(modelResult.representation.get(i) as PartialInterpretation, | ||
344 | traces.get(i)) | ||
345 | ].toList | ||
253 | return res | 346 | return res |
254 | } | 347 | } |
255 | 348 | ||
256 | private def ViatraReasonerConfiguration asConfig(LogicSolverConfiguration configuration) { | 349 | private def ViatraReasonerConfiguration asConfig(LogicSolverConfiguration configuration) { |
257 | if(configuration instanceof ViatraReasonerConfiguration) { | 350 | if (configuration instanceof ViatraReasonerConfiguration) { |
258 | return configuration | 351 | return configuration |
259 | } else throw new IllegalArgumentException('''Wrong configuration. Expected: «ViatraReasonerConfiguration.name», but got: «configuration.class.name»"''') | 352 | } else |
353 | throw new IllegalArgumentException('''Wrong configuration. Expected: «ViatraReasonerConfiguration.name», but got: «configuration.class.name»"''') | ||
260 | } | 354 | } |
261 | } | 355 | } |
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 6e3c5235..ddd25aac 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 | |||
@@ -6,19 +6,28 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration | |||
6 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration | 6 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration |
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod | 7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod |
8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeInferenceMethod | 8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeInferenceMethod |
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedralScopePropagatorConstraints | ||
10 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedralScopePropagatorSolver | ||
11 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy | ||
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser | 12 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser |
13 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveKind | ||
14 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold | ||
10 | import java.util.LinkedList | 15 | import java.util.LinkedList |
11 | import java.util.List | 16 | import java.util.List |
12 | import java.util.Set | 17 | import java.util.Set |
13 | import org.eclipse.xtext.xbase.lib.Functions.Function1 | 18 | import org.eclipse.xtext.xbase.lib.Functions.Function1 |
19 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeConstraintHint | ||
14 | 20 | ||
15 | public enum StateCoderStrategy { | 21 | enum StateCoderStrategy { |
16 | Neighbourhood, NeighbourhoodWithEquivalence, IDBased, DefinedByDiversity | 22 | Neighbourhood, |
23 | PairwiseNeighbourhood, | ||
24 | NeighbourhoodWithEquivalence, | ||
25 | IDBased, | ||
26 | DefinedByDiversity | ||
17 | } | 27 | } |
18 | 28 | ||
19 | class ViatraReasonerConfiguration extends LogicSolverConfiguration{ | 29 | class ViatraReasonerConfiguration extends LogicSolverConfiguration { |
20 | //public var Iterable<PQuery> existingQueries | 30 | // public var Iterable<PQuery> existingQueries |
21 | |||
22 | public var nameNewElements = false | 31 | public var nameNewElements = false |
23 | public var StateCoderStrategy stateCoderStrategy = StateCoderStrategy.Neighbourhood | 32 | public var StateCoderStrategy stateCoderStrategy = StateCoderStrategy.Neighbourhood |
24 | public var TypeInferenceMethod typeInferenceMethod = TypeInferenceMethod.PreliminaryAnalysis | 33 | public var TypeInferenceMethod typeInferenceMethod = TypeInferenceMethod.PreliminaryAnalysis |
@@ -26,7 +35,7 @@ class ViatraReasonerConfiguration extends LogicSolverConfiguration{ | |||
26 | * Once per 1/randomBacktrackChance the search selects a random state. | 35 | * Once per 1/randomBacktrackChance the search selects a random state. |
27 | */ | 36 | */ |
28 | public var int randomBacktrackChance = 20; | 37 | public var int randomBacktrackChance = 20; |
29 | 38 | ||
30 | /** | 39 | /** |
31 | * Describes the required diversity between the solutions. | 40 | * Describes the required diversity between the solutions. |
32 | * Null means that the solutions have to have different state codes only. | 41 | * Null means that the solutions have to have different state codes only. |
@@ -40,7 +49,7 @@ class ViatraReasonerConfiguration extends LogicSolverConfiguration{ | |||
40 | /** | 49 | /** |
41 | * Configuration for debugging support. | 50 | * Configuration for debugging support. |
42 | */ | 51 | */ |
43 | public var DebugConfiguration debugCongiguration = new DebugConfiguration | 52 | public var DebugConfiguration debugConfiguration = new DebugConfiguration |
44 | /** | 53 | /** |
45 | * Configuration for cutting search space. | 54 | * Configuration for cutting search space. |
46 | */ | 55 | */ |
@@ -54,10 +63,15 @@ class ViatraReasonerConfiguration extends LogicSolverConfiguration{ | |||
54 | public var nonContainmentWeight = 1 | 63 | public var nonContainmentWeight = 1 |
55 | public var unfinishedWFWeight = 1 | 64 | public var unfinishedWFWeight = 1 |
56 | 65 | ||
57 | public var calculateObjectCreationCosts = false | 66 | public var ScopePropagatorStrategy scopePropagatorStrategy = new ScopePropagatorStrategy.Polyhedral( |
67 | PolyhedralScopePropagatorConstraints.Relational, PolyhedralScopePropagatorSolver.Clp) | ||
68 | |||
69 | public var List<LinearTypeConstraintHint> hints = newArrayList | ||
70 | |||
71 | public var List<CostObjectiveConfiguration> costObjectives = newArrayList | ||
58 | } | 72 | } |
59 | 73 | ||
60 | public class DiversityDescriptor { | 74 | class DiversityDescriptor { |
61 | public var ensureDiversity = false | 75 | public var ensureDiversity = false |
62 | public static val FixPointRange = -1 | 76 | public static val FixPointRange = -1 |
63 | public var int range = FixPointRange | 77 | public var int range = FixPointRange |
@@ -67,20 +81,31 @@ public class DiversityDescriptor { | |||
67 | public var Set<RelationDeclaration> relevantRelations = null | 81 | public var Set<RelationDeclaration> relevantRelations = null |
68 | } | 82 | } |
69 | 83 | ||
70 | public class DebugConfiguration { | 84 | class DebugConfiguration { |
71 | public var logging = false | 85 | public var PartialInterpretationVisualiser partialInterpretatioVisualiser = null |
72 | public var PartialInterpretationVisualiser partialInterpretatioVisualiser = null; | ||
73 | public var partalInterpretationVisualisationFrequency = 1 | 86 | public var partalInterpretationVisualisationFrequency = 1 |
74 | } | 87 | } |
75 | 88 | ||
76 | public class InternalConsistencyCheckerConfiguration { | 89 | class InternalConsistencyCheckerConfiguration { |
77 | public var LogicReasoner internalIncosnsitencyDetector = null | 90 | public var LogicReasoner internalIncosnsitencyDetector = null |
78 | public var LogicSolverConfiguration internalInconsistencDetectorConfiguration = null | 91 | public var LogicSolverConfiguration internalInconsistencDetectorConfiguration = null |
79 | public var incternalConsistencyCheckingFrequency = 1 | 92 | public var incternalConsistencyCheckingFrequency = 1 |
80 | } | 93 | } |
81 | 94 | ||
82 | public class SearchSpaceConstraint { | 95 | class SearchSpaceConstraint { |
83 | public static val UNLIMITED_MAXDEPTH = Integer.MAX_VALUE | 96 | public static val UNLIMITED_MAXDEPTH = Integer.MAX_VALUE |
84 | public var int maxDepth = UNLIMITED_MAXDEPTH | 97 | public var int maxDepth = UNLIMITED_MAXDEPTH |
85 | public var List<Function1<ModelGenerationMethod, ModelGenerationMethodBasedGlobalConstraint>> additionalGlobalConstraints = new LinkedList | 98 | public var List<Function1<ModelGenerationMethod, ModelGenerationMethodBasedGlobalConstraint>> additionalGlobalConstraints = new LinkedList |
86 | } \ No newline at end of file | 99 | } |
100 | |||
101 | class CostObjectiveConfiguration { | ||
102 | public var List<CostObjectiveElementConfiguration> elements = newArrayList | ||
103 | public var ObjectiveKind kind | ||
104 | public var ObjectiveThreshold threshold | ||
105 | public var boolean findExtremum | ||
106 | } | ||
107 | |||
108 | class CostObjectiveElementConfiguration { | ||
109 | public var String patternQualifiedName | ||
110 | public var int weight | ||
111 | } | ||
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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | ||
5 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation | ||
6 | import java.util.Comparator | ||
7 | import java.util.List | ||
8 | import org.eclipse.viatra.dse.base.ThreadContext | ||
9 | import org.eclipse.viatra.dse.objectives.Comparators | ||
10 | import org.eclipse.viatra.dse.objectives.IGlobalConstraint | ||
11 | import org.eclipse.viatra.dse.objectives.IObjective | ||
12 | import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor | ||
13 | |||
14 | class 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 e3603af3..e529892c 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,34 +9,25 @@ | |||
9 | *******************************************************************************/ | 9 | *******************************************************************************/ |
10 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse; | 10 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse; |
11 | 11 | ||
12 | import java.io.BufferedReader; | ||
13 | import java.io.IOException; | ||
14 | import java.io.InputStreamReader; | ||
15 | import java.util.ArrayList; | ||
16 | import java.util.Arrays; | 12 | import java.util.Arrays; |
17 | import java.util.Collection; | ||
18 | import java.util.Collections; | 13 | import java.util.Collections; |
19 | import java.util.Comparator; | 14 | import java.util.Comparator; |
20 | import java.util.Iterator; | 15 | import java.util.Iterator; |
21 | import java.util.LinkedList; | 16 | import java.util.LinkedList; |
22 | import java.util.List; | 17 | import java.util.List; |
23 | import java.util.Map; | ||
24 | import java.util.PriorityQueue; | 18 | import java.util.PriorityQueue; |
25 | import java.util.Random; | 19 | import java.util.Random; |
26 | 20 | ||
27 | import org.apache.log4j.Logger; | 21 | import org.apache.log4j.Logger; |
28 | import org.eclipse.emf.ecore.EObject; | 22 | import org.eclipse.emf.ecore.EObject; |
29 | import org.eclipse.emf.ecore.util.EcoreUtil; | 23 | import org.eclipse.emf.ecore.util.EcoreUtil; |
24 | import org.eclipse.viatra.dse.api.SolutionTrajectory; | ||
30 | import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; | 25 | import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; |
31 | import org.eclipse.viatra.dse.base.ThreadContext; | 26 | import org.eclipse.viatra.dse.base.ThreadContext; |
32 | import org.eclipse.viatra.dse.objectives.Fitness; | 27 | import org.eclipse.viatra.dse.objectives.Fitness; |
33 | import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper; | 28 | import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper; |
29 | import org.eclipse.viatra.dse.solutionstore.ISolutionFoundHandler; | ||
34 | import org.eclipse.viatra.dse.solutionstore.SolutionStore; | 30 | import org.eclipse.viatra.dse.solutionstore.SolutionStore; |
35 | import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine; | ||
36 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
37 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
38 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
39 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher; | ||
40 | 31 | ||
41 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel; | 32 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel; |
42 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner; | 33 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner; |
@@ -44,7 +35,6 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem; | |||
44 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult; | 35 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult; |
45 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult; | 36 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult; |
46 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult; | 37 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult; |
47 | import hu.bme.mit.inf.dslreasoner.viatra2logic.NumericProblemSolver; | ||
48 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod; | 38 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod; |
49 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic; | 39 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic; |
50 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation; | 40 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation; |
@@ -83,14 +73,13 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
83 | // Running | 73 | // Running |
84 | private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore; | 74 | private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore; |
85 | private SolutionStore solutionStore; | 75 | private SolutionStore solutionStore; |
86 | private SolutionStoreWithCopy solutionStoreWithCopy; | ||
87 | private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor; | ||
88 | private volatile boolean isInterrupted = false; | 76 | private volatile boolean isInterrupted = false; |
89 | private ModelResult modelResultByInternalSolver = null; | 77 | private ModelResult modelResultByInternalSolver = null; |
90 | private Random random = new Random(); | 78 | private Random random = new Random(); |
91 | //private Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers; | 79 | //private Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers; |
92 | public ActivationSelector activationSelector = new EvenActivationSelector(random); | 80 | public ActivationSelector activationSelector = new EvenActivationSelector(random); |
93 | public NumericSolver numericSolver = null; | 81 | public ViatraReasonerSolutionSaver solutionSaver; |
82 | public NumericSolver numericSolver; | ||
94 | // Statistics | 83 | // Statistics |
95 | private int numberOfStatecoderFail = 0; | 84 | private int numberOfStatecoderFail = 0; |
96 | private int numberOfPrintedModel = 0; | 85 | private int numberOfPrintedModel = 0; |
@@ -103,19 +92,17 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
103 | public BestFirstStrategyForModelGeneration( | 92 | public BestFirstStrategyForModelGeneration( |
104 | ReasonerWorkspace workspace, | 93 | ReasonerWorkspace workspace, |
105 | ViatraReasonerConfiguration configuration, | 94 | ViatraReasonerConfiguration configuration, |
106 | ModelGenerationMethod method) | 95 | ModelGenerationMethod method, |
107 | { | 96 | ViatraReasonerSolutionSaver solutionSaver, |
97 | NumericSolver numericSolver) { | ||
108 | this.workspace = workspace; | 98 | this.workspace = workspace; |
109 | this.configuration = configuration; | 99 | this.configuration = configuration; |
110 | this.method = method; | 100 | this.method = method; |
101 | this.solutionSaver = solutionSaver; | ||
102 | this.numericSolver = numericSolver; | ||
103 | //logger.setLevel(Level.DEBUG); | ||
111 | } | 104 | } |
112 | 105 | ||
113 | public SolutionStoreWithCopy getSolutionStoreWithCopy() { | ||
114 | return solutionStoreWithCopy; | ||
115 | } | ||
116 | public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() { | ||
117 | return solutionStoreWithDiversityDescriptor; | ||
118 | } | ||
119 | public int getNumberOfStatecoderFail() { | 106 | public int getNumberOfStatecoderFail() { |
120 | return numberOfStatecoderFail; | 107 | return numberOfStatecoderFail; |
121 | } | 108 | } |
@@ -125,22 +112,35 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
125 | public long getBacktrackingTime() { | 112 | public long getBacktrackingTime() { |
126 | return context.getDesignSpaceManager().getBacktrackingTime(); | 113 | return context.getDesignSpaceManager().getBacktrackingTime(); |
127 | } | 114 | } |
128 | //LinkedList<ViatraQueryMatcher<? extends IPatternMatch>> matchers; | 115 | |
129 | @Override | 116 | @Override |
130 | public void initStrategy(ThreadContext context) { | 117 | public void initStrategy(ThreadContext context) { |
131 | this.context = context; | 118 | this.context = context; |
132 | this.solutionStore = context.getGlobalContext().getSolutionStore(); | 119 | this.solutionStore = context.getGlobalContext().getSolutionStore(); |
120 | solutionStore.registerSolutionFoundHandler(new ISolutionFoundHandler() { | ||
121 | |||
122 | @Override | ||
123 | public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) { | ||
124 | // Ignore. | ||
125 | } | ||
126 | |||
127 | @Override | ||
128 | public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) { | ||
129 | configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolutions); | ||
130 | saveTimes(); | ||
131 | logger.debug("Found a solution."); | ||
132 | } | ||
133 | }); | ||
134 | numericSolver.init(context); | ||
133 | 135 | ||
134 | // ViatraQueryEngine engine = context.getQueryEngine(); | 136 | // ViatraQueryEngine engine = context.getQueryEngine(); |
135 | // // TODO: visualisation | ||
136 | // matchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>(); | 137 | // matchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>(); |
137 | // for(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> p : this.method.getAllPatterns()) { | 138 | // for(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> p : this.method.getAllPatterns()) { |
138 | // //System.out.println(p.getSimpleName()); | 139 | // //System.out.println(p.getSimpleName()); |
139 | // ViatraQueryMatcher<? extends IPatternMatch> matcher = p.getMatcher(engine); | 140 | // ViatraQueryMatcher<? extends IPatternMatch> matcher = p.getMatcher(engine); |
140 | // matchers.add(matcher); | 141 | // matchers.add(matcher); |
141 | // } | 142 | // } |
142 | this.solutionStoreWithCopy = new SolutionStoreWithCopy(); | 143 | |
143 | this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement); | ||
144 | final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); | 144 | final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); |
145 | this.comparator = new Comparator<TrajectoryWithFitness>() { | 145 | this.comparator = new Comparator<TrajectoryWithFitness>() { |
146 | @Override | 146 | @Override |
@@ -148,8 +148,6 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
148 | return objectiveComparatorHelper.compare(o2.fitness, o1.fitness); | 148 | return objectiveComparatorHelper.compare(o2.fitness, o1.fitness); |
149 | } | 149 | } |
150 | }; | 150 | }; |
151 | |||
152 | this.numericSolver = new NumericSolver(context, method, this.configuration.runIntermediateNumericalConsistencyChecks, false); | ||
153 | 151 | ||
154 | trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11, comparator); | 152 | trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11, comparator); |
155 | } | 153 | } |
@@ -176,14 +174,13 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
176 | return; | 174 | return; |
177 | } | 175 | } |
178 | 176 | ||
179 | final Fitness firstFittness = calculateFitness(); | 177 | final Fitness firstFitness = calculateFitness(); |
180 | checkForSolution(firstFittness); | 178 | checkForSolution(firstFitness); |
181 | 179 | ||
182 | final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); | 180 | final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); |
183 | final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]); | 181 | final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]); |
184 | TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness); | 182 | TrajectoryWithFitness currentTrajectoryWithFitness = new TrajectoryWithFitness(firstTrajectory, firstFitness); |
185 | trajectoiresToExplore.add(currentTrajectoryWithFittness); | 183 | trajectoiresToExplore.add(currentTrajectoryWithFitness); |
186 | |||
187 | //if(configuration) | 184 | //if(configuration) |
188 | visualiseCurrentState(); | 185 | visualiseCurrentState(); |
189 | // for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) { | 186 | // for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) { |
@@ -197,22 +194,22 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
197 | 194 | ||
198 | mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) { | 195 | mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) { |
199 | 196 | ||
200 | if (currentTrajectoryWithFittness == null) { | 197 | if (currentTrajectoryWithFitness == null) { |
201 | if (trajectoiresToExplore.isEmpty()) { | 198 | if (trajectoiresToExplore.isEmpty()) { |
202 | logger.debug("State space is fully traversed."); | 199 | logger.debug("State space is fully traversed."); |
203 | return; | 200 | return; |
204 | } else { | 201 | } else { |
205 | currentTrajectoryWithFittness = selectState(); | 202 | currentTrajectoryWithFitness = selectState(); |
206 | if (logger.isDebugEnabled()) { | 203 | if (logger.isDebugEnabled()) { |
207 | logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray())); | 204 | logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray())); |
208 | logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness); | 205 | logger.debug("New trajectory is chosen: " + currentTrajectoryWithFitness); |
209 | } | 206 | } |
210 | context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory); | 207 | context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFitness.trajectory); |
211 | } | 208 | } |
212 | } | 209 | } |
213 | 210 | ||
214 | // visualiseCurrentState(); | 211 | // visualiseCurrentState(); |
215 | // boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness); | 212 | // boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithfitness); |
216 | // if(consistencyCheckResult == true) { | 213 | // if(consistencyCheckResult == true) { |
217 | // continue mainLoop; | 214 | // continue mainLoop; |
218 | // } | 215 | // } |
@@ -224,10 +221,11 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
224 | final Object nextActivation = iterator.next(); | 221 | final Object nextActivation = iterator.next(); |
225 | // if (!iterator.hasNext()) { | 222 | // if (!iterator.hasNext()) { |
226 | // logger.debug("Last untraversed activation of the state."); | 223 | // logger.debug("Last untraversed activation of the state."); |
227 | // trajectoiresToExplore.remove(currentTrajectoryWithFittness); | 224 | // trajectoiresToExplore.remove(currentTrajectoryWithfitness); |
228 | // } | 225 | // } |
229 | logger.debug("Executing new activation: " + nextActivation); | 226 | logger.debug("Executing new activation: " + nextActivation); |
230 | context.executeAcitvationId(nextActivation); | 227 | context.executeAcitvationId(nextActivation); |
228 | method.getStatistics().incrementDecisionCount(); | ||
231 | 229 | ||
232 | visualiseCurrentState(); | 230 | visualiseCurrentState(); |
233 | // for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) { | 231 | // for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) { |
@@ -238,7 +236,7 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
238 | // | 236 | // |
239 | // } | 237 | // } |
240 | 238 | ||
241 | boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness); | 239 | boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFitness); |
242 | if(consistencyCheckResult == true) { continue mainLoop; } | 240 | if(consistencyCheckResult == true) { continue mainLoop; } |
243 | 241 | ||
244 | if (context.isCurrentStateAlreadyTraversed()) { | 242 | if (context.isCurrentStateAlreadyTraversed()) { |
@@ -251,7 +249,7 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
251 | logger.debug("Numeric constraints are not satisifed."); | 249 | logger.debug("Numeric constraints are not satisifed."); |
252 | context.backtrack(); | 250 | context.backtrack(); |
253 | } else { | 251 | } else { |
254 | final Fitness nextFitness = calculateFitness(); | 252 | final Fitness nextFitness = context.calculateFitness(); |
255 | checkForSolution(nextFitness); | 253 | checkForSolution(nextFitness); |
256 | if (context.getDepth() > configuration.searchSpaceConstraints.maxDepth) { | 254 | if (context.getDepth() > configuration.searchSpaceConstraints.maxDepth) { |
257 | logger.debug("Reached max depth."); | 255 | logger.debug("Reached max depth."); |
@@ -259,31 +257,31 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
259 | continue; | 257 | continue; |
260 | } | 258 | } |
261 | 259 | ||
262 | TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness( | 260 | TrajectoryWithFitness nextTrajectoryWithfitness = new TrajectoryWithFitness( |
263 | context.getTrajectory().toArray(), nextFitness); | 261 | context.getTrajectory().toArray(), nextFitness); |
264 | trajectoiresToExplore.add(nextTrajectoryWithFittness); | 262 | trajectoiresToExplore.add(nextTrajectoryWithfitness); |
265 | 263 | ||
266 | int compare = objectiveComparatorHelper.compare(currentTrajectoryWithFittness.fitness, | 264 | int compare = objectiveComparatorHelper.compare(currentTrajectoryWithFitness.fitness, |
267 | nextTrajectoryWithFittness.fitness); | 265 | nextTrajectoryWithfitness.fitness); |
268 | if (compare < 0) { | 266 | if (compare < 0) { |
269 | logger.debug("Better fitness, moving on: " + nextFitness); | 267 | logger.debug("Better fitness, moving on: " + nextFitness); |
270 | currentTrajectoryWithFittness = nextTrajectoryWithFittness; | 268 | currentTrajectoryWithFitness = nextTrajectoryWithfitness; |
271 | continue mainLoop; | 269 | continue mainLoop; |
272 | } else if (compare == 0) { | 270 | } else if (compare == 0) { |
273 | logger.debug("Equally good fitness, moving on: " + nextFitness); | 271 | logger.debug("Equally good fitness, moving on: " + nextFitness); |
274 | currentTrajectoryWithFittness = nextTrajectoryWithFittness; | 272 | currentTrajectoryWithFitness = nextTrajectoryWithfitness; |
275 | continue mainLoop; | 273 | continue mainLoop; |
276 | } else { | 274 | } else { |
277 | logger.debug("Worse fitness."); | 275 | logger.debug("Worse fitness."); |
278 | currentTrajectoryWithFittness = null; | 276 | currentTrajectoryWithFitness = null; |
279 | continue mainLoop; | 277 | continue mainLoop; |
280 | } | 278 | } |
281 | } | 279 | } |
282 | } | 280 | } |
283 | 281 | ||
284 | logger.debug("State is fully traversed."); | 282 | logger.debug("State is fully traversed."); |
285 | trajectoiresToExplore.remove(currentTrajectoryWithFittness); | 283 | trajectoiresToExplore.remove(currentTrajectoryWithFitness); |
286 | currentTrajectoryWithFittness = null; | 284 | currentTrajectoryWithFitness = null; |
287 | 285 | ||
288 | } | 286 | } |
289 | logger.info("Interrupted."); | 287 | logger.info("Interrupted."); |
@@ -308,6 +306,7 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
308 | try { | 306 | try { |
309 | activationIds = this.activationSelector.randomizeActivationIDs(context.getUntraversedActivationIds()); | 307 | activationIds = this.activationSelector.randomizeActivationIDs(context.getUntraversedActivationIds()); |
310 | } catch (NullPointerException e) { | 308 | } catch (NullPointerException e) { |
309 | // logger.warn("Unexpected state code: " + context.getDesignSpaceManager().getCurrentState()); | ||
311 | numberOfStatecoderFail++; | 310 | numberOfStatecoderFail++; |
312 | activationIds = Collections.emptyList(); | 311 | activationIds = Collections.emptyList(); |
313 | } | 312 | } |
@@ -315,27 +314,16 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
315 | } | 314 | } |
316 | 315 | ||
317 | private void checkForSolution(final Fitness fittness) { | 316 | private void checkForSolution(final Fitness fittness) { |
318 | if (fittness.isSatisifiesHardObjectives()) { | 317 | solutionStore.newSolution(context); |
319 | if (solutionStoreWithDiversityDescriptor.isDifferent(context)) { | ||
320 | if(numericSolver.currentSatisfiable()) { | ||
321 | Map<EObject, EObject> trace = solutionStoreWithCopy.newSolution(context); | ||
322 | numericSolver.fillSolutionCopy(trace); | ||
323 | solutionStoreWithDiversityDescriptor.newSolution(context); | ||
324 | solutionStore.newSolution(context); | ||
325 | configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolution); | ||
326 | saveTimes(); | ||
327 | logger.debug("Found a solution."); | ||
328 | } | ||
329 | } | ||
330 | } | ||
331 | } | 318 | } |
319 | |||
332 | public List<String> times = new LinkedList<String>(); | 320 | public List<String> times = new LinkedList<String>(); |
333 | private void saveTimes() { | 321 | private void saveTimes() { |
334 | long statecoderTime = ((NeighbourhoodBasedPartialInterpretationStateCoder)this.context.getStateCoder()).getStatecoderRuntime()/1000000; | 322 | long statecoderTime = ((NeighbourhoodBasedPartialInterpretationStateCoder<?, ?>)this.context.getStateCoder()).getStatecoderRuntime()/1000000; |
335 | long forwardTime = context.getDesignSpaceManager().getForwardTime()/1000000; | 323 | long forwardTime = context.getDesignSpaceManager().getForwardTime()/1000000; |
336 | long backtrackingTime = context.getDesignSpaceManager().getBacktrackingTime()/1000000; | 324 | long backtrackingTime = context.getDesignSpaceManager().getBacktrackingTime()/1000000; |
337 | long solutionCopy = solutionStoreWithCopy.getSumRuntime()/1000000; | ||
338 | long activationSelection = this.activationSelector.getRuntime()/1000000; | 325 | long activationSelection = this.activationSelector.getRuntime()/1000000; |
326 | long solutionCopierTime = this.solutionSaver.getTotalCopierRuntime()/1000000; | ||
339 | long numericalSolverSumTime = this.numericSolver.getRuntime()/1000000; | 327 | long numericalSolverSumTime = this.numericSolver.getRuntime()/1000000; |
340 | long numericalSolverProblemForming = this.numericSolver.getSolverSolvingProblem()/1000000; | 328 | long numericalSolverProblemForming = this.numericSolver.getSolverSolvingProblem()/1000000; |
341 | long numericalSolverSolving = this.numericSolver.getSolverSolvingProblem()/1000000; | 329 | long numericalSolverSolving = this.numericSolver.getSolverSolvingProblem()/1000000; |
@@ -347,8 +335,8 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
347 | "|Backtrackingtime:"+backtrackingTime+ | 335 | "|Backtrackingtime:"+backtrackingTime+ |
348 | "|GlobalConstraintEvaluationTime:"+(globalConstraintEvaluationTime/1000000)+ | 336 | "|GlobalConstraintEvaluationTime:"+(globalConstraintEvaluationTime/1000000)+ |
349 | "|FitnessCalculationTime:"+(fitnessCalculationTime/1000000)+ | 337 | "|FitnessCalculationTime:"+(fitnessCalculationTime/1000000)+ |
350 | "|SolutionCopyTime:"+solutionCopy+ | ||
351 | "|ActivationSelectionTime:"+activationSelection+ | 338 | "|ActivationSelectionTime:"+activationSelection+ |
339 | "|SolutionCopyTime:"+solutionCopierTime+ | ||
352 | "|NumericalSolverSumTime:"+numericalSolverSumTime+ | 340 | "|NumericalSolverSumTime:"+numericalSolverSumTime+ |
353 | "|NumericalSolverProblemFormingTime:"+numericalSolverProblemForming+ | 341 | "|NumericalSolverProblemFormingTime:"+numericalSolverProblemForming+ |
354 | "|NumericalSolverSolvingTime:"+numericalSolverSolving+ | 342 | "|NumericalSolverSolvingTime:"+numericalSolverSolving+ |
@@ -385,13 +373,16 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { | |||
385 | } | 373 | } |
386 | 374 | ||
387 | public void visualiseCurrentState() { | 375 | public void visualiseCurrentState() { |
388 | PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugCongiguration.partialInterpretatioVisualiser; | 376 | PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugConfiguration.partialInterpretatioVisualiser; |
389 | if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) { | 377 | if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) { |
390 | PartialInterpretation p = (PartialInterpretation) (context.getModel()); | 378 | PartialInterpretation p = (PartialInterpretation) (context.getModel()); |
391 | int id = ++numberOfPrintedModel; | 379 | int id = ++numberOfPrintedModel; |
392 | if (id % configuration.debugCongiguration.partalInterpretationVisualisationFrequency == 0) { | 380 | if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) { |
393 | PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); | 381 | PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); |
394 | visualisation.writeToFile(workspace, String.format("state%09d.png", id)); | 382 | logger.debug("Visualizing state: " + id + " (" + context.getDesignSpaceManager().getCurrentState() + ")"); |
383 | String name = String.format("state%09d", id); | ||
384 | visualisation.writeToFile(workspace, name + ".png"); | ||
385 | workspace.writeModel((EObject) context.getModel(), name + ".xmi"); | ||
395 | } | 386 | } |
396 | } | 387 | } |
397 | } | 388 | } |
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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse | ||
2 | |||
3 | import com.google.common.collect.HashMultiset | ||
4 | import com.google.common.collect.ImmutableSet | ||
5 | import com.google.common.collect.Multiset | ||
6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor | ||
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodWithTraces | ||
8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice | ||
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | ||
10 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.DiversityDescriptor | ||
11 | import java.util.Collection | ||
12 | import java.util.HashSet | ||
13 | import java.util.Map | ||
14 | import java.util.Set | ||
15 | import org.eclipse.viatra.dse.base.ThreadContext | ||
16 | import org.eclipse.xtend.lib.annotations.Accessors | ||
17 | |||
18 | interface 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 | |||
54 | abstract 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 | |||
101 | class 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 | |||
144 | class 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.IThreeValuedObjective | ||
4 | import org.eclipse.viatra.dse.base.ThreadContext | ||
5 | import org.eclipse.viatra.dse.objectives.Comparators | ||
6 | import org.eclipse.viatra.dse.objectives.Fitness | ||
7 | import org.eclipse.viatra.dse.objectives.IObjective | ||
8 | |||
9 | final 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/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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse | ||
2 | |||
3 | import org.eclipse.viatra.dse.objectives.IGlobalConstraint | ||
4 | import org.eclipse.viatra.dse.base.ThreadContext | ||
5 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | ||
6 | |||
7 | class 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration | ||
4 | import org.apache.log4j.Logger | ||
5 | import org.eclipse.viatra.dse.api.SolutionTrajectory | ||
6 | import org.eclipse.viatra.dse.base.ThreadContext | ||
7 | import org.eclipse.viatra.dse.solutionstore.ISolutionFoundHandler | ||
8 | import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor | ||
9 | |||
10 | @FinalFieldsConstructor | ||
11 | class LoggerSolutionFoundHandler implements ISolutionFoundHandler { | ||
12 | val ViatraReasonerConfiguration configuration | ||
13 | |||
14 | val logger = Logger.getLogger(SolutionCopier) | ||
15 | |||
16 | override solutionFound(ThreadContext context, SolutionTrajectory trajectory) { | ||
17 | configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolutions) | ||
18 | logger.debug("Found a solution.") | ||
19 | } | ||
20 | |||
21 | override solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) { | ||
22 | // We are not interested in invalid solutions, ignore. | ||
23 | } | ||
24 | } | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend index a10530c7..d2faaa65 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,34 +1,20 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse | 1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse |
2 | 2 | ||
3 | import com.google.common.collect.ImmutableList | ||
4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | ||
5 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration | ||
6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.IThreeValuedObjective | ||
3 | import java.util.Comparator | 7 | import java.util.Comparator |
4 | import java.util.List | 8 | import java.util.List |
5 | import org.eclipse.viatra.dse.base.ThreadContext | 9 | import org.eclipse.viatra.dse.base.ThreadContext |
6 | import org.eclipse.viatra.dse.objectives.Comparators | 10 | import org.eclipse.viatra.dse.objectives.Comparators |
7 | import org.eclipse.viatra.dse.objectives.IObjective | 11 | import org.eclipse.viatra.dse.objectives.IObjective |
8 | import org.eclipse.viatra.dse.objectives.impl.BaseObjective | ||
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | ||
10 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration | ||
11 | 12 | ||
12 | //class ViatraReasonerNumbers { | 13 | class ModelGenerationCompositeObjective implements IThreeValuedObjective { |
13 | // public static val scopePriority = 2 | 14 | val IObjective scopeObjective |
14 | // public static val unfinishedMultiplicityPriority = 2 | ||
15 | // public static val unifinshedWFPriority = 2 | ||
16 | // //public static val complexityPriority = 4 | ||
17 | // | ||
18 | // public static val scopeWeigth = 1.0 | ||
19 | // public static val unfinishedMultiplicityWeigth = 1.5 | ||
20 | // public static val unfinishedWFWeigth = 1.5 | ||
21 | // //public static val complexityWeigth = 0.1 | ||
22 | // | ||
23 | // public static val useCompositeObjective = true | ||
24 | // public static val compositePriority = 2 | ||
25 | //} | ||
26 | |||
27 | class ModelGenerationCompositeObjective implements IObjective{ | ||
28 | val ScopeObjective scopeObjective | ||
29 | val List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives | 15 | val List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives |
30 | val UnfinishedWFObjective unfinishedWFObjective | 16 | val UnfinishedWFObjective unfinishedWFObjective |
31 | var PartialInterpretation model=null; | 17 | var PartialInterpretation model = null |
32 | val boolean punishSize | 18 | val boolean punishSize |
33 | val int scopeWeight | 19 | val int scopeWeight |
34 | val int conaintmentWeight | 20 | val int conaintmentWeight |
@@ -36,23 +22,20 @@ class ModelGenerationCompositeObjective implements IObjective{ | |||
36 | val int unfinishedWFWeight | 22 | val int unfinishedWFWeight |
37 | 23 | ||
38 | new( | 24 | new( |
39 | ScopeObjective scopeObjective, | 25 | IObjective scopeObjective, |
40 | List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives, | 26 | List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives, |
41 | UnfinishedWFObjective unfinishedWFObjective, | 27 | UnfinishedWFObjective unfinishedWFObjective, |
42 | ViatraReasonerConfiguration configuration) | 28 | ViatraReasonerConfiguration configuration) |
43 | { | 29 | { |
44 | this.scopeObjective = scopeObjective | 30 | this( |
45 | this.unfinishedMultiplicityObjectives = unfinishedMultiplicityObjectives | 31 | scopeObjective, unfinishedMultiplicityObjectives, unfinishedWFObjective, configuration.punishSize, |
46 | this.unfinishedWFObjective = unfinishedWFObjective | 32 | configuration.scopeWeight, configuration.conaintmentWeight, configuration.nonContainmentWeight, |
47 | 33 | configuration.unfinishedWFWeight | |
48 | this.punishSize = configuration.punishSize | 34 | ) |
49 | this.scopeWeight = configuration.scopeWeight | ||
50 | this.conaintmentWeight = configuration.conaintmentWeight | ||
51 | this.nonContainmentWeight = configuration.nonContainmentWeight | ||
52 | this.unfinishedWFWeight = configuration.unfinishedWFWeight | ||
53 | } | 35 | } |
36 | |||
54 | new( | 37 | new( |
55 | ScopeObjective scopeObjective, | 38 | IObjective scopeObjective, |
56 | List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives, | 39 | List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives, |
57 | UnfinishedWFObjective unfinishedWFObjective, | 40 | UnfinishedWFObjective unfinishedWFObjective, |
58 | boolean punishSize, int scopeWeight, int conaintmentWeight, int nonContainmentWeight, int unfinishedWFWeight) | 41 | boolean punishSize, int scopeWeight, int conaintmentWeight, int nonContainmentWeight, int unfinishedWFWeight) |
@@ -74,18 +57,21 @@ class ModelGenerationCompositeObjective implements IObjective{ | |||
74 | this.unfinishedMultiplicityObjectives.forEach[it.init(context)] | 57 | this.unfinishedMultiplicityObjectives.forEach[it.init(context)] |
75 | this.unfinishedWFObjective.init(context) | 58 | this.unfinishedWFObjective.init(context) |
76 | } | 59 | } |
77 | 60 | ||
78 | override createNew() { | 61 | override createNew() { |
79 | return new ModelGenerationCompositeObjective( | 62 | return new ModelGenerationCompositeObjective( |
80 | this.scopeObjective, this.unfinishedMultiplicityObjectives, this.unfinishedWFObjective, | 63 | scopeObjective.createNew, |
81 | this.punishSize, this.scopeWeight, this.conaintmentWeight, this.nonContainmentWeight, this.unfinishedWFWeight) | 64 | ImmutableList.copyOf(unfinishedMultiplicityObjectives.map[createNew as UnfinishedMultiplicityObjective]), |
65 | unfinishedWFObjective.createNew as UnfinishedWFObjective, | ||
66 | punishSize, scopeWeight, conaintmentWeight, nonContainmentWeight, unfinishedWFWeight | ||
67 | ) | ||
82 | } | 68 | } |
83 | 69 | ||
84 | override getComparator() { Comparators.LOWER_IS_BETTER } | 70 | override getComparator() { Comparators.LOWER_IS_BETTER } |
71 | |||
85 | override getFitness(ThreadContext context) { | 72 | override getFitness(ThreadContext context) { |
86 | 73 | ||
87 | val scopeFitnes = scopeObjective.getFitness(context) | 74 | val scopeFitnes = scopeObjective.getFitness(context) |
88 | //val unfinishedMultiplicitiesFitneses = unfinishedMultiplicityObjectives.map[x|x.getFitness(context)] | ||
89 | val unfinishedWFsFitness = unfinishedWFObjective.getFitness(context) | 75 | val unfinishedWFsFitness = unfinishedWFObjective.getFitness(context) |
90 | 76 | ||
91 | var containmentMultiplicity = 0.0 | 77 | var containmentMultiplicity = 0.0 |
@@ -109,24 +95,30 @@ class ModelGenerationCompositeObjective implements IObjective{ | |||
109 | sum += nonContainmentMultiplicity*nonContainmentWeight | 95 | sum += nonContainmentMultiplicity*nonContainmentWeight |
110 | sum += unfinishedWFsFitness*unfinishedWFWeight | 96 | sum += unfinishedWFsFitness*unfinishedWFWeight |
111 | sum+=size | 97 | sum+=size |
112 | |||
113 | //println('''Sum=«sum»|Scope=«scopeFitnes»|ContainmentMultiplicity=«containmentMultiplicity»|NonContainmentMultiplicity=«nonContainmentMultiplicity»|WFs=«unfinishedWFsFitness»''') | ||
114 | |||
115 | return sum | 98 | return sum |
116 | } | 99 | } |
117 | 100 | ||
118 | override getLevel() { 2 } | 101 | override getWorstPossibleFitness(ThreadContext threadContext) { |
119 | override getName() { "CompositeUnfinishednessObjective"} | 102 | Double.POSITIVE_INFINITY |
103 | } | ||
120 | 104 | ||
105 | override getBestPossibleFitness(ThreadContext threadContext) { | ||
106 | 0.0 | ||
107 | } | ||
108 | |||
109 | override getLevel() { 2 } | ||
110 | |||
111 | override getName() { "CompositeUnfinishednessObjective" } | ||
112 | |||
121 | override isHardObjective() { true } | 113 | override isHardObjective() { true } |
122 | override satisifiesHardObjective(Double fitness) { fitness < 0.95 } | 114 | |
123 | 115 | override satisifiesHardObjective(Double fitness) { fitness <= 0.001 } | |
124 | 116 | ||
125 | override setComparator(Comparator<Double> comparator) { | 117 | override setComparator(Comparator<Double> comparator) { |
126 | throw new UnsupportedOperationException("TODO: auto-generated method stub") | 118 | throw new UnsupportedOperationException("Model generation objective comparator cannot be set.") |
127 | } | 119 | } |
120 | |||
128 | override setLevel(int level) { | 121 | override setLevel(int level) { |
129 | throw new UnsupportedOperationException("TODO: auto-generated method stub") | 122 | throw new UnsupportedOperationException("Model generation objective level cannot be set.") |
130 | } | 123 | } |
131 | 124 | } | |
132 | } \ No newline at end of file | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend index 0b0feb1a..066040a0 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend | |||
@@ -21,7 +21,8 @@ import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | |||
21 | import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint | 21 | import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint |
22 | 22 | ||
23 | class NumericSolver { | 23 | class NumericSolver { |
24 | val ThreadContext threadContext; | 24 | val ModelGenerationMethod method |
25 | var ThreadContext threadContext | ||
25 | val constraint2MustUnitPropagationPrecondition = new HashMap<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>> | 26 | val constraint2MustUnitPropagationPrecondition = new HashMap<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>> |
26 | val constraint2CurrentUnitPropagationPrecondition = new HashMap<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>> | 27 | val constraint2CurrentUnitPropagationPrecondition = new HashMap<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>> |
27 | NumericTranslator t = new NumericTranslator | 28 | NumericTranslator t = new NumericTranslator |
@@ -35,8 +36,16 @@ class NumericSolver { | |||
35 | var int numberOfSolverCalls = 0 | 36 | var int numberOfSolverCalls = 0 |
36 | var int numberOfCachedSolverCalls = 0 | 37 | var int numberOfCachedSolverCalls = 0 |
37 | 38 | ||
38 | new(ThreadContext threadContext, ModelGenerationMethod method, boolean intermediateConsistencyCheck, boolean caching) { | 39 | new(ModelGenerationMethod method, boolean intermediateConsistencyCheck, boolean caching) { |
39 | this.threadContext = threadContext | 40 | this.method = method |
41 | this.intermediateConsistencyCheck = intermediateConsistencyCheck | ||
42 | this.caching = caching | ||
43 | } | ||
44 | |||
45 | def init(ThreadContext context) { | ||
46 | // This makes the NumericSolver single-threaded, | ||
47 | // but that's not a problem, because we only use the solver on a single thread anyways. | ||
48 | this.threadContext = context | ||
40 | val engine = threadContext.queryEngine | 49 | val engine = threadContext.queryEngine |
41 | for(entry : method.mustUnitPropagationPreconditions.entrySet) { | 50 | for(entry : method.mustUnitPropagationPreconditions.entrySet) { |
42 | val constraint = entry.key | 51 | val constraint = entry.key |
@@ -50,8 +59,6 @@ class NumericSolver { | |||
50 | val matcher = querySpec.getMatcher(engine); | 59 | val matcher = querySpec.getMatcher(engine); |
51 | constraint2CurrentUnitPropagationPrecondition.put(constraint,matcher) | 60 | constraint2CurrentUnitPropagationPrecondition.put(constraint,matcher) |
52 | } | 61 | } |
53 | this.intermediateConsistencyCheck = intermediateConsistencyCheck | ||
54 | this.caching = caching | ||
55 | } | 62 | } |
56 | 63 | ||
57 | def getRuntime(){runtime} | 64 | def getRuntime(){runtime} |
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend index efc2ef36..cfd11816 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 | |||
@@ -219,4 +219,4 @@ class PartialModelAsLogicInterpretation implements LogicModelInterpretation{ | |||
219 | } | 219 | } |
220 | builder | 220 | builder |
221 | } | 221 | } |
222 | } \ No newline at end of file | 222 | } |
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..69a734f8 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..38c8f5a1 --- /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,86 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | ||
5 | import java.util.LinkedHashMap | ||
6 | import java.util.List | ||
7 | import java.util.Map | ||
8 | import org.eclipse.emf.ecore.EObject | ||
9 | import org.eclipse.emf.ecore.util.EcoreUtil | ||
10 | import org.eclipse.viatra.dse.base.ThreadContext | ||
11 | import org.eclipse.xtend.lib.annotations.Accessors | ||
12 | import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor | ||
13 | |||
14 | @FinalFieldsConstructor | ||
15 | class 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 | */ | ||
28 | class SolutionCopier { | ||
29 | val NumericSolver numericSolver | ||
30 | val copiedSolutions = new LinkedHashMap<Object, CopiedSolution> | ||
31 | |||
32 | long startTime = System.nanoTime | ||
33 | @Accessors(PUBLIC_GETTER) long totalCopierRuntime = 0 | ||
34 | |||
35 | new(NumericSolver numericSolver) { | ||
36 | this.numericSolver = numericSolver | ||
37 | } | ||
38 | |||
39 | def void copySolution(ThreadContext context, Object solutionId) { | ||
40 | val existingCopy = copiedSolutions.get(solutionId) | ||
41 | if (existingCopy === null) { | ||
42 | val copyStart = System.nanoTime | ||
43 | val solution = context.model as PartialInterpretation | ||
44 | val copier = new EcoreUtil.Copier | ||
45 | val copiedPartialInterpretation = copier.copy(solution) as PartialInterpretation | ||
46 | copier.copyReferences | ||
47 | totalCopierRuntime += System.nanoTime - copyStart | ||
48 | val copierRuntime = System.nanoTime - startTime | ||
49 | val copiedSolution = new CopiedSolution(copiedPartialInterpretation, copier, copierRuntime) | ||
50 | numericSolver.fillSolutionCopy(copiedSolution.trace) | ||
51 | copiedSolutions.put(solutionId, copiedSolution) | ||
52 | } else { | ||
53 | existingCopy.current = true | ||
54 | } | ||
55 | } | ||
56 | |||
57 | def void markAsObsolete(Object solutionId) { | ||
58 | val copiedSolution = copiedSolutions.get(solutionId) | ||
59 | if (copiedSolution === null) { | ||
60 | throw new IllegalStateException("No solution to mark as obsolete for state code: " + solutionId) | ||
61 | } | ||
62 | copiedSolution.current = false | ||
63 | } | ||
64 | |||
65 | def List<PartialInterpretation> getPartialInterpretations(boolean currentOnly) { | ||
66 | getListOfCopiedSolutions(currentOnly).map[partialInterpretations] | ||
67 | } | ||
68 | |||
69 | def List<Map<EObject, EObject>> getTraces(boolean currentOnly) { | ||
70 | getListOfCopiedSolutions(currentOnly).map[trace] | ||
71 | } | ||
72 | |||
73 | def List<Long> getAllCopierRuntimes(boolean currentOnly) { | ||
74 | getListOfCopiedSolutions(currentOnly).map[copierRuntime] | ||
75 | } | ||
76 | |||
77 | def List<CopiedSolution> getListOfCopiedSolutions(boolean currentOnly) { | ||
78 | val values = copiedSolutions.values | ||
79 | val filteredSolutions = if (currentOnly) { | ||
80 | values.filter[current] | ||
81 | } else { | ||
82 | values | ||
83 | } | ||
84 | ImmutableList.copyOf(filteredSolutions) | ||
85 | } | ||
86 | } | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend index 21867a4e..4bd2c349 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend | |||
@@ -1,14 +1,12 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse | 1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse |
2 | 2 | ||
3 | import java.util.List | ||
4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | 3 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation |
5 | import java.util.LinkedList | 4 | import java.util.LinkedList |
6 | import org.eclipse.emf.ecore.EObject | 5 | import java.util.List |
7 | import java.util.Map | 6 | import java.util.Map |
7 | import org.eclipse.emf.ecore.EObject | ||
8 | import org.eclipse.emf.ecore.util.EcoreUtil | 8 | import org.eclipse.emf.ecore.util.EcoreUtil |
9 | import org.eclipse.viatra.dse.base.ThreadContext | 9 | import org.eclipse.viatra.dse.base.ThreadContext |
10 | import java.util.TreeMap | ||
11 | import java.util.SortedMap | ||
12 | 10 | ||
13 | class SolutionStoreWithCopy { | 11 | class SolutionStoreWithCopy { |
14 | 12 | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend deleted file mode 100644 index 1e7f18a8..00000000 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend +++ /dev/null | |||
@@ -1,120 +0,0 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice | ||
4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | ||
5 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.DiversityDescriptor | ||
6 | import java.util.LinkedList | ||
7 | import java.util.List | ||
8 | import org.eclipse.viatra.dse.base.ThreadContext | ||
9 | import java.util.HashSet | ||
10 | import java.util.Set | ||
11 | |||
12 | enum DiversityGranularity { | ||
13 | Nodewise, Graphwise | ||
14 | } | ||
15 | |||
16 | class 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse | ||
2 | |||
3 | import org.eclipse.viatra.dse.base.ThreadContext | ||
4 | import org.eclipse.viatra.dse.objectives.IGlobalConstraint | ||
5 | import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor | ||
6 | |||
7 | @FinalFieldsConstructor | ||
8 | class SurelyViolatedObjectiveGlobalConstraint implements IGlobalConstraint { | ||
9 | val ViatraReasonerSolutionSaver solutionSaver | ||
10 | |||
11 | override init(ThreadContext context) { | ||
12 | // Nothing to initialize. | ||
13 | } | ||
14 | |||
15 | override createNew() { | ||
16 | this | ||
17 | } | ||
18 | |||
19 | override getName() { | ||
20 | class.name | ||
21 | } | ||
22 | |||
23 | override checkGlobalConstraint(ThreadContext context) { | ||
24 | val bestFitness = DseUtils.caclulateBestPossibleFitness(context) | ||
25 | bestFitness.satisifiesHardObjectives && solutionSaver.fitnessMayBeSaved(bestFitness) | ||
26 | } | ||
27 | } | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend index 2b0807d6..e1582d3b 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend | |||
@@ -1,15 +1,15 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse | 1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse |
2 | 2 | ||
3 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.MultiplicityGoalConstraintCalculator | 3 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.MultiplicityGoalConstraintCalculator |
4 | import java.util.Comparator | 4 | import java.util.Comparator |
5 | import org.eclipse.viatra.dse.base.ThreadContext | 5 | import org.eclipse.viatra.dse.base.ThreadContext |
6 | import org.eclipse.viatra.dse.objectives.IObjective | ||
7 | import org.eclipse.viatra.dse.objectives.Comparators | 6 | import org.eclipse.viatra.dse.objectives.Comparators |
7 | import org.eclipse.viatra.dse.objectives.IObjective | ||
8 | 8 | ||
9 | class UnfinishedMultiplicityObjective implements IObjective { | 9 | class UnfinishedMultiplicityObjective implements IObjective { |
10 | val MultiplicityGoalConstraintCalculator unfinishedMultiplicity; | 10 | val MultiplicityGoalConstraintCalculator unfinishedMultiplicity |
11 | 11 | ||
12 | public new(MultiplicityGoalConstraintCalculator unfinishedMultiplicity) { | 12 | new(MultiplicityGoalConstraintCalculator unfinishedMultiplicity) { |
13 | this.unfinishedMultiplicity = unfinishedMultiplicity | 13 | this.unfinishedMultiplicity = unfinishedMultiplicity |
14 | } | 14 | } |
15 | 15 | ||
@@ -29,12 +29,13 @@ class UnfinishedMultiplicityObjective implements IObjective { | |||
29 | override satisifiesHardObjective(Double fitness) { return fitness <=0.01 } | 29 | override satisifiesHardObjective(Double fitness) { return fitness <=0.01 } |
30 | 30 | ||
31 | override setComparator(Comparator<Double> comparator) { | 31 | override setComparator(Comparator<Double> comparator) { |
32 | throw new UnsupportedOperationException("TODO: auto-generated method stub") | 32 | throw new UnsupportedOperationException |
33 | } | 33 | } |
34 | override setLevel(int level) { | 34 | override setLevel(int level) { |
35 | throw new UnsupportedOperationException("TODO: auto-generated method stub") | 35 | throw new UnsupportedOperationException |
36 | } | 36 | } |
37 | |||
37 | def isContainment() { | 38 | def isContainment() { |
38 | return this.unfinishedMultiplicity.containment | 39 | return this.unfinishedMultiplicity.containment |
39 | } | 40 | } |
40 | } \ No newline at end of file | 41 | } |
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend index e0111cf6..1b61ffa5 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend | |||
@@ -1,56 +1,64 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse | 1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse |
2 | 2 | ||
3 | import org.eclipse.viatra.dse.objectives.IObjective | 3 | import java.util.ArrayList |
4 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
5 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
6 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification | ||
7 | import java.util.Collection | 4 | import java.util.Collection |
8 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine | 5 | import java.util.Comparator |
9 | import org.eclipse.viatra.query.runtime.emf.EMFScope | ||
10 | import org.eclipse.viatra.dse.base.ThreadContext | ||
11 | import java.util.List | 6 | import java.util.List |
7 | import org.eclipse.viatra.dse.base.ThreadContext | ||
12 | import org.eclipse.viatra.dse.objectives.Comparators | 8 | import org.eclipse.viatra.dse.objectives.Comparators |
13 | import java.util.ArrayList | 9 | import org.eclipse.viatra.dse.objectives.IObjective |
14 | import java.util.Comparator | 10 | import org.eclipse.viatra.query.runtime.api.IPatternMatch |
11 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification | ||
12 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
15 | 13 | ||
16 | class UnfinishedWFObjective implements IObjective { | 14 | class 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..d879d4cc --- /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,150 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse | ||
2 | |||
3 | import java.util.HashMap | ||
4 | import java.util.Map | ||
5 | import org.eclipse.viatra.dse.api.DSEException | ||
6 | import org.eclipse.viatra.dse.api.Solution | ||
7 | import org.eclipse.viatra.dse.api.SolutionTrajectory | ||
8 | import org.eclipse.viatra.dse.base.ThreadContext | ||
9 | import org.eclipse.viatra.dse.objectives.Fitness | ||
10 | import org.eclipse.viatra.dse.objectives.IObjective | ||
11 | import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper | ||
12 | import org.eclipse.viatra.dse.solutionstore.SolutionStore.ISolutionSaver | ||
13 | import org.eclipse.xtend.lib.annotations.Accessors | ||
14 | |||
15 | /** | ||
16 | * Based on {@link SolutionStore.BestSolutionSaver}. | ||
17 | * | ||
18 | * Will also automatically fill any missing numerical values in the saved solutions | ||
19 | * using the supplied {@link NumericSolver}. | ||
20 | */ | ||
21 | class ViatraReasonerSolutionSaver implements ISolutionSaver { | ||
22 | @Accessors val SolutionCopier solutionCopier | ||
23 | @Accessors val DiversityChecker diversityChecker | ||
24 | val boolean hasExtremalObjectives | ||
25 | val int numberOfRequiredSolutions | ||
26 | val ObjectiveComparatorHelper comparatorHelper | ||
27 | val Map<SolutionTrajectory, Fitness> trajectories = new HashMap | ||
28 | |||
29 | @Accessors(PUBLIC_SETTER) var Map<Object, Solution> solutionsCollection | ||
30 | |||
31 | new(IObjective[][] leveledExtremalObjectives, int numberOfRequiredSolutions, DiversityChecker diversityChecker, NumericSolver numericSolver) { | ||
32 | this.diversityChecker = diversityChecker | ||
33 | comparatorHelper = new ObjectiveComparatorHelper(leveledExtremalObjectives) | ||
34 | hasExtremalObjectives = leveledExtremalObjectives.exists[!empty] | ||
35 | this.numberOfRequiredSolutions = numberOfRequiredSolutions | ||
36 | this.solutionCopier = new SolutionCopier(numericSolver) | ||
37 | } | ||
38 | |||
39 | override saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) { | ||
40 | if (hasExtremalObjectives) { | ||
41 | saveBestSolutionOnly(context, id, solutionTrajectory) | ||
42 | } else { | ||
43 | saveAnyDiverseSolution(context, id, solutionTrajectory) | ||
44 | } | ||
45 | } | ||
46 | |||
47 | private def saveBestSolutionOnly(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) { | ||
48 | val fitness = context.lastFitness | ||
49 | if (!shouldSaveSolution(fitness, context)) { | ||
50 | return false | ||
51 | } | ||
52 | val dominatedTrajectories = newArrayList | ||
53 | for (entry : trajectories.entrySet) { | ||
54 | val isLastFitnessBetter = comparatorHelper.compare(fitness, entry.value) | ||
55 | if (isLastFitnessBetter < 0) { | ||
56 | // Found a trajectory that dominates the current one, no need to save | ||
57 | return false | ||
58 | } | ||
59 | if (isLastFitnessBetter > 0) { | ||
60 | dominatedTrajectories += entry.key | ||
61 | } | ||
62 | } | ||
63 | if (dominatedTrajectories.size == 0 && !needsMoreSolutionsWithSameFitness) { | ||
64 | return false | ||
65 | } | ||
66 | if (!diversityChecker.newSolution(context, id, dominatedTrajectories.map[solution.stateCode])) { | ||
67 | return false | ||
68 | } | ||
69 | // We must save the new trajectory before removing dominated trajectories | ||
70 | // to avoid removing the current solution when it is reachable only via dominated trajectories. | ||
71 | val solutionSaved = basicSaveSolution(context, id, solutionTrajectory, fitness) | ||
72 | for (dominatedTrajectory : dominatedTrajectories) { | ||
73 | trajectories -= dominatedTrajectory | ||
74 | val dominatedSolution = dominatedTrajectory.solution | ||
75 | if (!dominatedSolution.trajectories.remove(dominatedTrajectory)) { | ||
76 | throw new DSEException( | ||
77 | "Dominated solution is not reachable from dominated trajectory. This should never happen!") | ||
78 | } | ||
79 | if (dominatedSolution.trajectories.empty) { | ||
80 | val dominatedSolutionId = dominatedSolution.stateCode | ||
81 | solutionCopier.markAsObsolete(dominatedSolutionId) | ||
82 | solutionsCollection -= dominatedSolutionId | ||
83 | } | ||
84 | } | ||
85 | solutionSaved | ||
86 | } | ||
87 | |||
88 | private def saveAnyDiverseSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) { | ||
89 | val fitness = context.lastFitness | ||
90 | if (!shouldSaveSolution(fitness, context)) { | ||
91 | return false | ||
92 | } | ||
93 | if (!diversityChecker.newSolution(context, id, emptyList)) { | ||
94 | return false | ||
95 | } | ||
96 | basicSaveSolution(context, id, solutionTrajectory, fitness) | ||
97 | } | ||
98 | |||
99 | private def shouldSaveSolution(Fitness fitness, ThreadContext context) { | ||
100 | return fitness.satisifiesHardObjectives | ||
101 | } | ||
102 | |||
103 | private def basicSaveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory, | ||
104 | Fitness fitness) { | ||
105 | var boolean solutionSaved = false | ||
106 | var dseSolution = solutionsCollection.get(id) | ||
107 | if (dseSolution === null) { | ||
108 | solutionCopier.copySolution(context, id) | ||
109 | dseSolution = new Solution(id, solutionTrajectory) | ||
110 | solutionsCollection.put(id, dseSolution) | ||
111 | solutionSaved = true | ||
112 | } else { | ||
113 | solutionSaved = dseSolution.trajectories.add(solutionTrajectory) | ||
114 | } | ||
115 | if (solutionSaved) { | ||
116 | solutionTrajectory.solution = dseSolution | ||
117 | trajectories.put(solutionTrajectory, fitness) | ||
118 | } | ||
119 | solutionSaved | ||
120 | } | ||
121 | |||
122 | def fitnessMayBeSaved(Fitness fitness) { | ||
123 | if (!hasExtremalObjectives) { | ||
124 | return true | ||
125 | } | ||
126 | var boolean mayDominate | ||
127 | for (existingFitness : trajectories.values) { | ||
128 | val isNewFitnessBetter = comparatorHelper.compare(fitness, existingFitness) | ||
129 | if (isNewFitnessBetter < 0) { | ||
130 | return false | ||
131 | } | ||
132 | if (isNewFitnessBetter > 0) { | ||
133 | mayDominate = true | ||
134 | } | ||
135 | } | ||
136 | mayDominate || needsMoreSolutionsWithSameFitness | ||
137 | } | ||
138 | |||
139 | private def boolean needsMoreSolutionsWithSameFitness() { | ||
140 | if (solutionsCollection === null) { | ||
141 | // The solutions collection will only be initialized upon saving the first solution. | ||
142 | return true | ||
143 | } | ||
144 | solutionsCollection.size < numberOfRequiredSolutions | ||
145 | } | ||
146 | |||
147 | def getTotalCopierRuntime() { | ||
148 | solutionCopier.totalCopierRuntime | ||
149 | } | ||
150 | } | ||
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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse | 1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse |
2 | 2 | ||
3 | import com.google.common.collect.ImmutableList | ||
3 | import java.util.ArrayList | 4 | import java.util.ArrayList |
4 | import java.util.Collection | 5 | import java.util.Collection |
5 | import org.eclipse.viatra.dse.objectives.Comparators | 6 | import org.eclipse.viatra.dse.objectives.Comparators |
@@ -12,25 +13,33 @@ import org.eclipse.viatra.query.runtime.api.IQuerySpecification | |||
12 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | 13 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher |
13 | 14 | ||
14 | class WF2ObjectiveConverter { | 15 | class 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import org.eclipse.viatra.dse.base.ThreadContext | ||
4 | |||
5 | abstract 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import java.util.Collection | ||
5 | import org.eclipse.viatra.dse.base.ThreadContext | ||
6 | |||
7 | class CompositeDirectionalThresholdObjective extends DirectionalThresholdObjective { | ||
8 | val Collection<DirectionalThresholdObjective> objectives | ||
9 | |||
10 | new(String name, Collection<DirectionalThresholdObjective> objectives) { | ||
11 | this(name, objectives, getKind(objectives), getThreshold(objectives), getLevel(objectives)) | ||
12 | } | ||
13 | |||
14 | new(String name, DirectionalThresholdObjective... objectives) { | ||
15 | this(name, objectives as Collection<DirectionalThresholdObjective>) | ||
16 | } | ||
17 | |||
18 | protected new(String name, Iterable<DirectionalThresholdObjective> objectives, ObjectiveKind kind, | ||
19 | ObjectiveThreshold threshold, int level) { | ||
20 | super(name, kind, threshold, level) | ||
21 | this.objectives = ImmutableList.copyOf(objectives) | ||
22 | } | ||
23 | |||
24 | override createNew() { | ||
25 | new CompositeDirectionalThresholdObjective(name, objectives.map[createNew as DirectionalThresholdObjective], | ||
26 | kind, threshold, level) | ||
27 | } | ||
28 | |||
29 | override init(ThreadContext context) { | ||
30 | for (objective : objectives) { | ||
31 | objective.init(context) | ||
32 | } | ||
33 | } | ||
34 | |||
35 | override protected getRawFitness(ThreadContext context) { | ||
36 | var double fitness = 0 | ||
37 | for (objective : objectives) { | ||
38 | fitness += objective.getFitness(context) | ||
39 | } | ||
40 | fitness | ||
41 | } | ||
42 | |||
43 | private static def getKind(Collection<DirectionalThresholdObjective> objectives) { | ||
44 | val kinds = objectives.map[kind].toSet | ||
45 | if (kinds.size != 1) { | ||
46 | throw new IllegalArgumentException("Passed objectives must have the same kind") | ||
47 | } | ||
48 | kinds.head | ||
49 | } | ||
50 | |||
51 | private static def getThreshold(Collection<DirectionalThresholdObjective> objectives) { | ||
52 | objectives.map[threshold].reduce[a, b|a.merge(b)] | ||
53 | } | ||
54 | |||
55 | private static def int getLevel(Collection<DirectionalThresholdObjective> objectives) { | ||
56 | val levels = objectives.map[level].toSet | ||
57 | if (levels.size != 1) { | ||
58 | throw new IllegalArgumentException("Passed objectives must have the same level") | ||
59 | } | ||
60 | levels.head | ||
61 | } | ||
62 | } | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend new file mode 100644 index 00000000..376e3d1a --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend | |||
@@ -0,0 +1,164 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import java.util.Comparator | ||
4 | import org.eclipse.viatra.dse.base.ThreadContext | ||
5 | import org.eclipse.viatra.dse.objectives.IObjective | ||
6 | import org.eclipse.xtend.lib.annotations.Accessors | ||
7 | import org.eclipse.xtend.lib.annotations.Data | ||
8 | import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor | ||
9 | |||
10 | abstract class ObjectiveThreshold { | ||
11 | public static val NO_THRESHOLD = new ObjectiveThreshold { | ||
12 | override isHard() { | ||
13 | false | ||
14 | } | ||
15 | |||
16 | override satisfiesThreshold(double cost, Comparator<Double> comparator) { | ||
17 | true | ||
18 | } | ||
19 | |||
20 | override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) { | ||
21 | cost | ||
22 | } | ||
23 | |||
24 | override ObjectiveThreshold merge(ObjectiveThreshold other) { | ||
25 | if (other == NO_THRESHOLD) { | ||
26 | NO_THRESHOLD | ||
27 | } else { | ||
28 | throw new IllegalArgumentException("Merged thresholds must have the same type") | ||
29 | } | ||
30 | } | ||
31 | } | ||
32 | |||
33 | private new() { | ||
34 | } | ||
35 | |||
36 | def boolean isHard() { | ||
37 | true | ||
38 | } | ||
39 | |||
40 | def boolean satisfiesThreshold(double cost, ObjectiveKind kind) { | ||
41 | satisfiesThreshold(cost, kind.comparator) | ||
42 | } | ||
43 | |||
44 | def boolean satisfiesThreshold(double cost, Comparator<Double> comparator) | ||
45 | |||
46 | def double postProcessCost(double cost, ObjectiveKind kind) { | ||
47 | if (satisfiesThreshold(cost, kind)) { | ||
48 | postProcessSatisfactoryCost(cost, kind) | ||
49 | } else { | ||
50 | cost | ||
51 | } | ||
52 | } | ||
53 | |||
54 | protected def double postProcessSatisfactoryCost(double cost, ObjectiveKind kind) | ||
55 | |||
56 | def ObjectiveThreshold merge(ObjectiveThreshold other) | ||
57 | |||
58 | @Data | ||
59 | static class Exclusive extends ObjectiveThreshold { | ||
60 | static val EPSILON = 0.1 | ||
61 | |||
62 | val double threshold | ||
63 | val boolean clampToThreshold | ||
64 | |||
65 | @FinalFieldsConstructor | ||
66 | new() { | ||
67 | } | ||
68 | |||
69 | new(double threshold) { | ||
70 | this(threshold, true) | ||
71 | } | ||
72 | |||
73 | override satisfiesThreshold(double cost, Comparator<Double> comparator) { | ||
74 | comparator.compare(threshold, cost) < 0 | ||
75 | } | ||
76 | |||
77 | override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) { | ||
78 | if (clampToThreshold) { | ||
79 | threshold + Math.signum(kind.satisfiedValue) * EPSILON | ||
80 | } else { | ||
81 | cost | ||
82 | } | ||
83 | } | ||
84 | |||
85 | override ObjectiveThreshold merge(ObjectiveThreshold other) { | ||
86 | if (other instanceof Exclusive) { | ||
87 | new Exclusive(threshold + other.threshold) | ||
88 | } else { | ||
89 | throw new IllegalArgumentException("Merged thresholds must have the same type") | ||
90 | } | ||
91 | } | ||
92 | } | ||
93 | |||
94 | @Data | ||
95 | static class Inclusive extends ObjectiveThreshold { | ||
96 | val double threshold | ||
97 | val boolean clampToThreshold | ||
98 | |||
99 | @FinalFieldsConstructor | ||
100 | new() { | ||
101 | } | ||
102 | |||
103 | new(double threshold) { | ||
104 | this(threshold, true) | ||
105 | } | ||
106 | |||
107 | override satisfiesThreshold(double cost, Comparator<Double> comparator) { | ||
108 | comparator.compare(threshold, cost) <= 0 | ||
109 | } | ||
110 | |||
111 | override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) { | ||
112 | if (clampToThreshold) { | ||
113 | threshold | ||
114 | } else { | ||
115 | cost | ||
116 | } | ||
117 | } | ||
118 | |||
119 | override ObjectiveThreshold merge(ObjectiveThreshold other) { | ||
120 | if (other instanceof Inclusive) { | ||
121 | new Inclusive(threshold + other.threshold) | ||
122 | } else { | ||
123 | throw new IllegalArgumentException("Merged thresholds must have the same type") | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | |||
129 | abstract class DirectionalThresholdObjective implements IObjective { | ||
130 | @Accessors val String name | ||
131 | @Accessors ObjectiveKind kind | ||
132 | @Accessors ObjectiveThreshold threshold | ||
133 | @Accessors int level | ||
134 | |||
135 | protected new(String name, ObjectiveKind kind, ObjectiveThreshold threshold, int level) { | ||
136 | this.name = name | ||
137 | this.kind = kind | ||
138 | this.threshold = threshold | ||
139 | this.level = level | ||
140 | } | ||
141 | |||
142 | override isHardObjective() { | ||
143 | threshold.hard | ||
144 | } | ||
145 | |||
146 | override satisifiesHardObjective(Double fitness) { | ||
147 | threshold.satisfiesThreshold(fitness, comparator) | ||
148 | } | ||
149 | |||
150 | override getComparator() { | ||
151 | kind.comparator | ||
152 | } | ||
153 | |||
154 | override setComparator(Comparator<Double> comparator) { | ||
155 | kind = ObjectiveKind.fromComparator(comparator) | ||
156 | } | ||
157 | |||
158 | override getFitness(ThreadContext context) { | ||
159 | val fitness = getRawFitness(context) | ||
160 | threshold.postProcessCost(fitness, kind) | ||
161 | } | ||
162 | |||
163 | protected def double getRawFitness(ThreadContext context) | ||
164 | } | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import org.eclipse.viatra.dse.base.ThreadContext | ||
4 | import org.eclipse.viatra.dse.objectives.IObjective | ||
5 | |||
6 | interface 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import java.util.Collection | ||
5 | import org.eclipse.viatra.dse.base.ThreadContext | ||
6 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
7 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification | ||
8 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
9 | import org.eclipse.xtend.lib.annotations.Data | ||
10 | |||
11 | @Data | ||
12 | class MatchCostElement { | ||
13 | val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification | ||
14 | val double weight | ||
15 | } | ||
16 | |||
17 | class MatchCostObjective extends DirectionalThresholdObjective { | ||
18 | val Collection<MatchCostElement> costElements | ||
19 | Collection<CostElementMatcher> matchers | ||
20 | |||
21 | new(String name, Collection<MatchCostElement> costElements, ObjectiveKind kind, ObjectiveThreshold threshold, | ||
22 | int level) { | ||
23 | super(name, kind, threshold, level) | ||
24 | this.costElements = costElements | ||
25 | } | ||
26 | |||
27 | override createNew() { | ||
28 | new MatchCostObjective(name, costElements, kind, threshold, level) | ||
29 | } | ||
30 | |||
31 | override init(ThreadContext context) { | ||
32 | val queryEngine = context.queryEngine | ||
33 | matchers = ImmutableList.copyOf(costElements.map [ | ||
34 | val matcher = querySpecification.getMatcher(queryEngine) | ||
35 | new CostElementMatcher(matcher, weight) | ||
36 | ]) | ||
37 | } | ||
38 | |||
39 | override protected getRawFitness(ThreadContext context) { | ||
40 | var double cost = 0 | ||
41 | for (it : matchers) { | ||
42 | cost += weight * matcher.countMatches | ||
43 | } | ||
44 | cost | ||
45 | } | ||
46 | |||
47 | @Data | ||
48 | private static class CostElementMatcher { | ||
49 | val ViatraQueryMatcher<? extends IPatternMatch> matcher | ||
50 | val double weight | ||
51 | } | ||
52 | } | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization; | ||
2 | |||
3 | import java.util.Comparator; | ||
4 | |||
5 | import org.eclipse.viatra.dse.objectives.Comparators; | ||
6 | |||
7 | public 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import org.eclipse.viatra.dse.base.ThreadContext | ||
4 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
5 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification | ||
6 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
7 | |||
8 | class QueryBasedObjective extends DirectionalThresholdObjective { | ||
9 | val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification | ||
10 | ViatraQueryMatcher<? extends IPatternMatch> matcher | ||
11 | |||
12 | new(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification, | ||
13 | ObjectiveKind kind, ObjectiveThreshold threshold, int level) { | ||
14 | super(querySpecification.simpleName + " objective", kind, threshold, level) | ||
15 | if (querySpecification.parameters.size != 1) { | ||
16 | throw new IllegalArgumentException("Objective query must have a single parameter") | ||
17 | } | ||
18 | this.querySpecification = querySpecification | ||
19 | } | ||
20 | |||
21 | override createNew() { | ||
22 | new QueryBasedObjective(querySpecification, kind, threshold, level) | ||
23 | } | ||
24 | |||
25 | override init(ThreadContext context) { | ||
26 | matcher = querySpecification.getMatcher(context.queryEngine) | ||
27 | } | ||
28 | |||
29 | override protected getRawFitness(ThreadContext context) { | ||
30 | val iterator = matcher.allMatches.iterator | ||
31 | if (!iterator.hasNext) { | ||
32 | return invalidValue | ||
33 | } | ||
34 | val value = iterator.next.get(0) | ||
35 | if (iterator.hasNext) { | ||
36 | throw new IllegalStateException("Multiple matches for objective query") | ||
37 | } | ||
38 | if (value instanceof Number) { | ||
39 | value.doubleValue | ||
40 | } else { | ||
41 | throw new IllegalStateException("Objective value is not an instance of Number") | ||
42 | } | ||
43 | } | ||
44 | |||
45 | private def getInvalidValue() { | ||
46 | kind.invalidValue | ||
47 | } | ||
48 | } | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend new file mode 100644 index 00000000..0a6fd55b --- /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,85 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import java.util.Collection | ||
5 | import org.eclipse.viatra.dse.base.ThreadContext | ||
6 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
7 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification | ||
8 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
9 | import org.eclipse.xtend.lib.annotations.Data | ||
10 | |||
11 | @Data | ||
12 | class ThreeValuedCostElement { | ||
13 | val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> currentMatchQuery | ||
14 | val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> mayMatchQuery | ||
15 | val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> mustMatchQuery | ||
16 | val int weight | ||
17 | } | ||
18 | |||
19 | class ThreeValuedCostObjective extends AbstractThreeValuedObjective { | ||
20 | val Collection<ThreeValuedCostElement> costElements | ||
21 | Collection<CostElementMatchers> matchers | ||
22 | |||
23 | new(String name, Collection<ThreeValuedCostElement> costElements, ObjectiveKind kind, ObjectiveThreshold threshold, | ||
24 | int level) { | ||
25 | super(name, kind, threshold, level) | ||
26 | this.costElements = costElements | ||
27 | } | ||
28 | |||
29 | override createNew() { | ||
30 | new ThreeValuedCostObjective(name, costElements, kind, threshold, level) | ||
31 | } | ||
32 | |||
33 | override init(ThreadContext context) { | ||
34 | val queryEngine = context.queryEngine | ||
35 | matchers = ImmutableList.copyOf(costElements.map [ element | | ||
36 | new CostElementMatchers( | ||
37 | queryEngine.getMatcher(element.currentMatchQuery), | ||
38 | queryEngine.getMatcher(element.mayMatchQuery), | ||
39 | queryEngine.getMatcher(element.mustMatchQuery), | ||
40 | element.weight | ||
41 | ) | ||
42 | ]) | ||
43 | } | ||
44 | |||
45 | override getRawFitness(ThreadContext context) { | ||
46 | var int cost = 0 | ||
47 | for (matcher : matchers) { | ||
48 | cost += matcher.weight * matcher.currentMatcher.countMatches | ||
49 | } | ||
50 | cost as double | ||
51 | } | ||
52 | |||
53 | override getLowestPossibleFitness(ThreadContext threadContext) { | ||
54 | var int cost = 0 | ||
55 | for (matcher : matchers) { | ||
56 | if (matcher.weight >= 0) { | ||
57 | cost += matcher.weight * matcher.mustMatcher.countMatches | ||
58 | } else if (matcher.mayMatcher.countMatches > 0) { | ||
59 | // TODO Count may matches. | ||
60 | return Double.NEGATIVE_INFINITY | ||
61 | } | ||
62 | } | ||
63 | cost as double | ||
64 | } | ||
65 | |||
66 | override getHighestPossibleFitness(ThreadContext threadContext) { | ||
67 | var int cost = 0 | ||
68 | for (matcher : matchers) { | ||
69 | if (matcher.weight <= 0) { | ||
70 | cost += matcher.weight * matcher.mustMatcher.countMatches | ||
71 | } else if (matcher.mayMatcher.countMatches > 0) { | ||
72 | return Double.POSITIVE_INFINITY | ||
73 | } | ||
74 | } | ||
75 | cost as double | ||
76 | } | ||
77 | |||
78 | @Data | ||
79 | private static class CostElementMatchers { | ||
80 | val ViatraQueryMatcher<? extends IPatternMatch> currentMatcher | ||
81 | val ViatraQueryMatcher<? extends IPatternMatch> mayMatcher | ||
82 | val ViatraQueryMatcher<? extends IPatternMatch> mustMatcher | ||
83 | val int weight | ||
84 | } | ||
85 | } | ||