diff options
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronScopePropagator.xtend')
-rw-r--r-- | Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronScopePropagator.xtend | 106 |
1 files changed, 84 insertions, 22 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronScopePropagator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronScopePropagator.xtend index 7c05e818..51dba244 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronScopePropagator.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronScopePropagator.xtend | |||
@@ -1,5 +1,7 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality | 1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality |
2 | 2 | ||
3 | import com.google.common.cache.Cache | ||
4 | import com.google.common.cache.CacheBuilder | ||
3 | import com.google.common.collect.ImmutableList | 5 | import com.google.common.collect.ImmutableList |
4 | import com.google.common.collect.ImmutableMap | 6 | import com.google.common.collect.ImmutableMap |
5 | import com.google.common.collect.ImmutableSet | 7 | import com.google.common.collect.ImmutableSet |
@@ -15,6 +17,7 @@ import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.par | |||
15 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope | 17 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope |
16 | import java.util.ArrayDeque | 18 | import java.util.ArrayDeque |
17 | import java.util.ArrayList | 19 | import java.util.ArrayList |
20 | import java.util.Collection | ||
18 | import java.util.HashMap | 21 | import java.util.HashMap |
19 | import java.util.HashSet | 22 | import java.util.HashSet |
20 | import java.util.List | 23 | import java.util.List |
@@ -29,26 +32,33 @@ import org.eclipse.viatra.query.runtime.emf.EMFScope | |||
29 | import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor | 32 | import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor |
30 | 33 | ||
31 | class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { | 34 | class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { |
35 | static val CACHE_SIZE = 10000 | ||
36 | |||
37 | val boolean updateHeuristic | ||
32 | val Map<Scope, LinearBoundedExpression> scopeBounds | 38 | val Map<Scope, LinearBoundedExpression> scopeBounds |
33 | val LinearBoundedExpression topLevelBounds | 39 | val LinearBoundedExpression topLevelBounds |
34 | val Polyhedron polyhedron | 40 | val Polyhedron polyhedron |
35 | val PolyhedronSaturationOperator operator | 41 | val PolyhedronSaturationOperator operator |
36 | val Set<Relation> relevantRelations | 42 | val Set<Relation> relevantRelations |
43 | val Cache<PolyhedronSignature, PolyhedronSignature> cache = CacheBuilder.newBuilder.maximumSize(CACHE_SIZE).build | ||
37 | List<RelationConstraintUpdater> updaters = emptyList | 44 | List<RelationConstraintUpdater> updaters = emptyList |
38 | 45 | ||
39 | new(PartialInterpretation p, ModelGenerationStatistics statistics, Set<? extends Type> possibleNewDynamicTypes, | 46 | new(PartialInterpretation p, ModelGenerationStatistics statistics, Set<? extends Type> possibleNewDynamicTypes, |
40 | Map<RelationMultiplicityConstraint, UnifinishedMultiplicityQueries> unfinishedMultiplicityQueries, | 47 | Map<RelationMultiplicityConstraint, UnifinishedMultiplicityQueries> unfinishedMultiplicityQueries, |
41 | IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hasElementInContainmentQuery, | 48 | IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hasElementInContainmentQuery, |
42 | PolyhedronSolver solver, boolean propagateRelations) { | 49 | Map<String, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> allPatternsByName, |
50 | Collection<LinearTypeConstraintHint> hints, PolyhedronSolver solver, boolean propagateRelations, | ||
51 | boolean updateHeuristic) { | ||
43 | super(p, statistics) | 52 | super(p, statistics) |
53 | this.updateHeuristic = updateHeuristic | ||
44 | val builder = new PolyhedronBuilder(p) | 54 | val builder = new PolyhedronBuilder(p) |
45 | builder.buildPolyhedron(possibleNewDynamicTypes) | 55 | builder.buildPolyhedron(possibleNewDynamicTypes) |
46 | scopeBounds = builder.scopeBounds | 56 | scopeBounds = builder.scopeBounds |
47 | topLevelBounds = builder.topLevelBounds | 57 | topLevelBounds = builder.topLevelBounds |
48 | polyhedron = builder.polyhedron | 58 | polyhedron = builder.polyhedron |
49 | operator = solver.createSaturationOperator(polyhedron) | 59 | operator = solver.createSaturationOperator(polyhedron) |
60 | propagateAllScopeConstraints() | ||
50 | if (propagateRelations) { | 61 | if (propagateRelations) { |
51 | propagateAllScopeConstraints() | ||
52 | val maximumNumberOfNewNodes = topLevelBounds.upperBound | 62 | val maximumNumberOfNewNodes = topLevelBounds.upperBound |
53 | if (maximumNumberOfNewNodes === null) { | 63 | if (maximumNumberOfNewNodes === null) { |
54 | throw new IllegalStateException("Could not determine maximum number of new nodes, it may be unbounded") | 64 | throw new IllegalStateException("Could not determine maximum number of new nodes, it may be unbounded") |
@@ -57,7 +67,7 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { | |||
57 | throw new IllegalStateException("Maximum number of new nodes is not positive") | 67 | throw new IllegalStateException("Maximum number of new nodes is not positive") |
58 | } | 68 | } |
59 | builder.buildMultiplicityConstraints(unfinishedMultiplicityQueries, hasElementInContainmentQuery, | 69 | builder.buildMultiplicityConstraints(unfinishedMultiplicityQueries, hasElementInContainmentQuery, |
60 | maximumNumberOfNewNodes) | 70 | allPatternsByName, hints, maximumNumberOfNewNodes) |
61 | relevantRelations = builder.relevantRelations | 71 | relevantRelations = builder.relevantRelations |
62 | updaters = builder.updaters | 72 | updaters = builder.updaters |
63 | } else { | 73 | } else { |
@@ -66,21 +76,40 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { | |||
66 | } | 76 | } |
67 | 77 | ||
68 | override void doPropagateAllScopeConstraints() { | 78 | override void doPropagateAllScopeConstraints() { |
79 | super.doPropagateAllScopeConstraints() | ||
69 | resetBounds() | 80 | resetBounds() |
70 | populatePolyhedronFromScope() | 81 | populatePolyhedronFromScope() |
71 | // println(polyhedron) | 82 | // println(polyhedron) |
72 | val result = operator.saturate() | 83 | val signature = polyhedron.createSignature |
73 | // println(polyhedron) | 84 | val cachedSignature = cache.getIfPresent(signature) |
74 | if (result == PolyhedronSaturationResult.EMPTY) { | 85 | switch (cachedSignature) { |
75 | setScopesInvalid() | 86 | case null: { |
76 | } else { | 87 | statistics.incrementScopePropagationSolverCount |
77 | populateScopesFromPolyhedron() | 88 | val result = operator.saturate() |
78 | if (result != PolyhedronSaturationResult.SATURATED) { | 89 | if (result == PolyhedronSaturationResult.EMPTY) { |
79 | super.propagateAllScopeConstraints() | 90 | cache.put(signature, PolyhedronSignature.EMPTY) |
91 | setScopesInvalid() | ||
92 | } else { | ||
93 | val resultSignature = polyhedron.createSignature | ||
94 | cache.put(signature, resultSignature) | ||
95 | populateScopesFromPolyhedron() | ||
96 | } | ||
80 | } | 97 | } |
98 | case PolyhedronSignature.EMPTY: | ||
99 | setScopesInvalid() | ||
100 | PolyhedronSignature.Bounds: { | ||
101 | polyhedron.applySignature(signature) | ||
102 | populateScopesFromPolyhedron() | ||
103 | } | ||
104 | default: | ||
105 | throw new IllegalStateException("Unknown polyhedron signature: " + signature) | ||
106 | } | ||
107 | // println(polyhedron) | ||
108 | if (updateHeuristic) { | ||
109 | copyScopeBoundsToHeuristic() | ||
81 | } | 110 | } |
82 | } | 111 | } |
83 | 112 | ||
84 | override propagateAdditionToRelation(Relation r) { | 113 | override propagateAdditionToRelation(Relation r) { |
85 | super.propagateAdditionToRelation(r) | 114 | super.propagateAdditionToRelation(r) |
86 | if (relevantRelations.contains(r)) { | 115 | if (relevantRelations.contains(r)) { |
@@ -186,7 +215,7 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { | |||
186 | } | 215 | } |
187 | 216 | ||
188 | @FinalFieldsConstructor | 217 | @FinalFieldsConstructor |
189 | private static class PolyhedronBuilder { | 218 | private static class PolyhedronBuilder implements LinearTypeExpressionBuilderFactory { |
190 | static val INFINITY_SCALE = 10 | 219 | static val INFINITY_SCALE = 10 |
191 | 220 | ||
192 | val PartialInterpretation p | 221 | val PartialInterpretation p |
@@ -197,6 +226,7 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { | |||
197 | Map<Type, LinearBoundedExpression> typeBounds | 226 | Map<Type, LinearBoundedExpression> typeBounds |
198 | int infinity | 227 | int infinity |
199 | ViatraQueryEngine queryEngine | 228 | ViatraQueryEngine queryEngine |
229 | Map<String, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> allPatternsByName | ||
200 | ImmutableList.Builder<RelationConstraintUpdater> updatersBuilder | 230 | ImmutableList.Builder<RelationConstraintUpdater> updatersBuilder |
201 | 231 | ||
202 | Map<Scope, LinearBoundedExpression> scopeBounds | 232 | Map<Scope, LinearBoundedExpression> scopeBounds |
@@ -222,9 +252,11 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { | |||
222 | def buildMultiplicityConstraints( | 252 | def buildMultiplicityConstraints( |
223 | Map<RelationMultiplicityConstraint, UnifinishedMultiplicityQueries> constraints, | 253 | Map<RelationMultiplicityConstraint, UnifinishedMultiplicityQueries> constraints, |
224 | IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hasElementInContainmentQuery, | 254 | IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hasElementInContainmentQuery, |
225 | int maximumNuberOfNewNodes) { | 255 | Map<String, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> allPatternsByName, |
256 | Collection<LinearTypeConstraintHint> hints, int maximumNuberOfNewNodes) { | ||
226 | infinity = maximumNuberOfNewNodes * INFINITY_SCALE | 257 | infinity = maximumNuberOfNewNodes * INFINITY_SCALE |
227 | queryEngine = ViatraQueryEngine.on(new EMFScope(p)) | 258 | queryEngine = ViatraQueryEngine.on(new EMFScope(p)) |
259 | this.allPatternsByName = allPatternsByName | ||
228 | updatersBuilder = ImmutableList.builder | 260 | updatersBuilder = ImmutableList.builder |
229 | val containmentConstraints = constraints.entrySet.filter[key.containment].groupBy[key.targetType] | 261 | val containmentConstraints = constraints.entrySet.filter[key.containment].groupBy[key.targetType] |
230 | for (pair : containmentConstraints.entrySet) { | 262 | for (pair : containmentConstraints.entrySet) { |
@@ -238,10 +270,13 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { | |||
238 | } | 270 | } |
239 | } | 271 | } |
240 | buildRelevantRelations(constraints.keySet) | 272 | buildRelevantRelations(constraints.keySet) |
273 | for (hint : hints) { | ||
274 | updatersBuilder.add(hint.createConstraintUpdater(this)) | ||
275 | } | ||
241 | updaters = updatersBuilder.build | 276 | updaters = updatersBuilder.build |
242 | addCachedConstraintsToPolyhedron() | 277 | addCachedConstraintsToPolyhedron() |
243 | } | 278 | } |
244 | 279 | ||
245 | private def buildRelevantRelations(Set<RelationMultiplicityConstraint> constraints) { | 280 | private def buildRelevantRelations(Set<RelationMultiplicityConstraint> constraints) { |
246 | val builder = ImmutableSet.builder | 281 | val builder = ImmutableSet.builder |
247 | for (constraint : constraints) { | 282 | for (constraint : constraints) { |
@@ -345,7 +380,7 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { | |||
345 | } | 380 | } |
346 | } | 381 | } |
347 | 382 | ||
348 | private def addCoefficients(Map<Dimension, Integer> accumulator, int scale, Map<Dimension, Integer> a) { | 383 | private static def addCoefficients(Map<Dimension, Integer> accumulator, int scale, Map<Dimension, Integer> a) { |
349 | for (pair : a.entrySet) { | 384 | for (pair : a.entrySet) { |
350 | val dimension = pair.key | 385 | val dimension = pair.key |
351 | val currentValue = accumulator.get(pair.key) ?: 0 | 386 | val currentValue = accumulator.get(pair.key) ?: 0 |
@@ -411,14 +446,41 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { | |||
411 | } | 446 | } |
412 | scopeBoundsBuilder.build | 447 | scopeBoundsBuilder.build |
413 | } | 448 | } |
449 | |||
450 | override createMatcher(String queryName) { | ||
451 | val querySpecification = allPatternsByName.get(queryName) | ||
452 | if (querySpecification === null) { | ||
453 | throw new IllegalArgumentException("Unknown pattern: " + queryName) | ||
454 | } | ||
455 | querySpecification.getMatcher(queryEngine) | ||
456 | } | ||
457 | |||
458 | override createBuilder() { | ||
459 | new PolyhedronBuilderLinearTypeExpressionBuilder(this) | ||
460 | } | ||
414 | } | 461 | } |
415 | 462 | ||
416 | private static interface RelationConstraintUpdater { | 463 | @FinalFieldsConstructor |
417 | def void update(PartialInterpretation p) | 464 | private static class PolyhedronBuilderLinearTypeExpressionBuilder implements LinearTypeExpressionBuilder { |
465 | val PolyhedronBuilder polyhedronBuilder | ||
466 | val Map<Dimension, Integer> coefficients = new HashMap | ||
467 | |||
468 | override add(int scale, Type type) { | ||
469 | val typeCoefficients = polyhedronBuilder.subtypeDimensions.get(type) | ||
470 | if (typeCoefficients === null) { | ||
471 | throw new IllegalArgumentException("Unknown type: " + type) | ||
472 | } | ||
473 | PolyhedronBuilder.addCoefficients(coefficients, scale, typeCoefficients) | ||
474 | this | ||
475 | } | ||
476 | |||
477 | override build() { | ||
478 | polyhedronBuilder.toExpression(coefficients) | ||
479 | } | ||
418 | } | 480 | } |
419 | 481 | ||
420 | @FinalFieldsConstructor | 482 | @FinalFieldsConstructor |
421 | static class ContainmentConstraintUpdater implements RelationConstraintUpdater { | 483 | private static class ContainmentConstraintUpdater implements RelationConstraintUpdater { |
422 | val String name | 484 | val String name |
423 | val LinearBoundedExpression orphansLowerBound | 485 | val LinearBoundedExpression orphansLowerBound |
424 | val LinearBoundedExpression orphansUpperBound | 486 | val LinearBoundedExpression orphansUpperBound |
@@ -460,7 +522,7 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { | |||
460 | } | 522 | } |
461 | 523 | ||
462 | @FinalFieldsConstructor | 524 | @FinalFieldsConstructor |
463 | static class ContainmentRootConstraintUpdater implements RelationConstraintUpdater { | 525 | private static class ContainmentRootConstraintUpdater implements RelationConstraintUpdater { |
464 | val LinearBoundedExpression typeCardinality | 526 | val LinearBoundedExpression typeCardinality |
465 | val ViatraQueryMatcher<? extends IPatternMatch> hasElementInContainmentMatcher | 527 | val ViatraQueryMatcher<? extends IPatternMatch> hasElementInContainmentMatcher |
466 | 528 | ||
@@ -479,7 +541,7 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { | |||
479 | } | 541 | } |
480 | 542 | ||
481 | @FinalFieldsConstructor | 543 | @FinalFieldsConstructor |
482 | static class UnfinishedMultiplicityConstraintUpdater implements RelationConstraintUpdater { | 544 | private static class UnfinishedMultiplicityConstraintUpdater implements RelationConstraintUpdater { |
483 | val String name | 545 | val String name |
484 | val LinearBoundedExpression availableMultiplicityExpression | 546 | val LinearBoundedExpression availableMultiplicityExpression |
485 | val ViatraQueryMatcher<? extends IPatternMatch> unfinishedMultiplicityMatcher | 547 | val ViatraQueryMatcher<? extends IPatternMatch> unfinishedMultiplicityMatcher |
@@ -500,7 +562,7 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { | |||
500 | } | 562 | } |
501 | 563 | ||
502 | @FinalFieldsConstructor | 564 | @FinalFieldsConstructor |
503 | static class UnrepairableMultiplicityConstraintUpdater implements RelationConstraintUpdater { | 565 | private static class UnrepairableMultiplicityConstraintUpdater implements RelationConstraintUpdater { |
504 | val String name | 566 | val String name |
505 | val LinearBoundedExpression targetCardinalityExpression | 567 | val LinearBoundedExpression targetCardinalityExpression |
506 | val ViatraQueryMatcher<? extends IPatternMatch> unrepairableMultiplicityMatcher | 568 | val ViatraQueryMatcher<? extends IPatternMatch> unrepairableMultiplicityMatcher |