From 07ae9155ce0ab9407566b075356f9b7220ee8380 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Sun, 28 Jun 2020 20:33:48 +0200 Subject: Fix scope + numerical solver interaction --- .../.ApplicationConfigurationIdeModule.xtendbin | Bin 1701 -> 1701 bytes .../ide/.ApplicationConfigurationIdeSetup.xtendbin | Bin 2526 -> 2526 bytes .../.SolverSemanticHighlightCalculator.xtendbin | Bin 5334 -> 5334 bytes .../.SolverSemanticTextAttributeProvider.xtendbin | Bin 4902 -> 4902 bytes .../validation/.SolverLanguageValidator.xtendbin | Bin 1717 -> 1717 bytes ....SolverLanguageTokenDefInjectingParser.xtendbin | Bin 2742 -> 2742 bytes ...nguageSyntheticTokenSyntacticSequencer.xtendbin | Bin 2758 -> 2758 bytes .../ModelGenerationMethodProvider.xtend | 6 + .../MultiplicityGoalConstraintCalculator.xtend | 22 +- .../cardinality/PolyhedronScopePropagator.xtend | 133 +- .../cardinality/RelationConstraintCalculator.xtend | 33 +- .../RemainingMultiplicityCalculator.xtend | 111 + .../logic2viatra/cardinality/ScopePropagator.xtend | 5 + .../logic2viatra/patterns/PatternProvider.xtend | 11 +- .../logic2viatra/patterns/UnfinishedIndexer.xtend | 189 +- .../rules/GoalConstraintProvider.xtend | 5 +- .../viatrasolver/reasoner/ViatraReasoner.xtend | 2 +- .../model/TaxationWithRoot.aird | 10302 +++++++++---------- 18 files changed, 5436 insertions(+), 5383 deletions(-) create mode 100644 Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RemainingMultiplicityCalculator.xtend diff --git a/Application/hu.bme.mit.inf.dslreasoner.application.ide/xtend-gen/hu/bme/mit/inf/dslreasoner/application/ide/.ApplicationConfigurationIdeModule.xtendbin b/Application/hu.bme.mit.inf.dslreasoner.application.ide/xtend-gen/hu/bme/mit/inf/dslreasoner/application/ide/.ApplicationConfigurationIdeModule.xtendbin index 94c786eb..11aee788 100644 Binary files a/Application/hu.bme.mit.inf.dslreasoner.application.ide/xtend-gen/hu/bme/mit/inf/dslreasoner/application/ide/.ApplicationConfigurationIdeModule.xtendbin and b/Application/hu.bme.mit.inf.dslreasoner.application.ide/xtend-gen/hu/bme/mit/inf/dslreasoner/application/ide/.ApplicationConfigurationIdeModule.xtendbin differ diff --git a/Application/hu.bme.mit.inf.dslreasoner.application.ide/xtend-gen/hu/bme/mit/inf/dslreasoner/application/ide/.ApplicationConfigurationIdeSetup.xtendbin b/Application/hu.bme.mit.inf.dslreasoner.application.ide/xtend-gen/hu/bme/mit/inf/dslreasoner/application/ide/.ApplicationConfigurationIdeSetup.xtendbin index 46ab9b95..d0ad3ab3 100644 Binary files a/Application/hu.bme.mit.inf.dslreasoner.application.ide/xtend-gen/hu/bme/mit/inf/dslreasoner/application/ide/.ApplicationConfigurationIdeSetup.xtendbin and b/Application/hu.bme.mit.inf.dslreasoner.application.ide/xtend-gen/hu/bme/mit/inf/dslreasoner/application/ide/.ApplicationConfigurationIdeSetup.xtendbin differ diff --git a/Application/org.eclipse.viatra.solver.language.ui/xtend-gen/org/eclipse/viatra/solver/language/ui/syntaxcoloring/.SolverSemanticHighlightCalculator.xtendbin b/Application/org.eclipse.viatra.solver.language.ui/xtend-gen/org/eclipse/viatra/solver/language/ui/syntaxcoloring/.SolverSemanticHighlightCalculator.xtendbin index 27dc1dd4..173a7c4d 100644 Binary files a/Application/org.eclipse.viatra.solver.language.ui/xtend-gen/org/eclipse/viatra/solver/language/ui/syntaxcoloring/.SolverSemanticHighlightCalculator.xtendbin and b/Application/org.eclipse.viatra.solver.language.ui/xtend-gen/org/eclipse/viatra/solver/language/ui/syntaxcoloring/.SolverSemanticHighlightCalculator.xtendbin differ diff --git a/Application/org.eclipse.viatra.solver.language.ui/xtend-gen/org/eclipse/viatra/solver/language/ui/syntaxcoloring/.SolverSemanticTextAttributeProvider.xtendbin b/Application/org.eclipse.viatra.solver.language.ui/xtend-gen/org/eclipse/viatra/solver/language/ui/syntaxcoloring/.SolverSemanticTextAttributeProvider.xtendbin index d71f4f21..ad60e239 100644 Binary files a/Application/org.eclipse.viatra.solver.language.ui/xtend-gen/org/eclipse/viatra/solver/language/ui/syntaxcoloring/.SolverSemanticTextAttributeProvider.xtendbin and b/Application/org.eclipse.viatra.solver.language.ui/xtend-gen/org/eclipse/viatra/solver/language/ui/syntaxcoloring/.SolverSemanticTextAttributeProvider.xtendbin differ diff --git a/Application/org.eclipse.viatra.solver.language.ui/xtend-gen/org/eclipse/viatra/solver/language/validation/.SolverLanguageValidator.xtendbin b/Application/org.eclipse.viatra.solver.language.ui/xtend-gen/org/eclipse/viatra/solver/language/validation/.SolverLanguageValidator.xtendbin index 801783da..01242ec7 100644 Binary files a/Application/org.eclipse.viatra.solver.language.ui/xtend-gen/org/eclipse/viatra/solver/language/validation/.SolverLanguageValidator.xtendbin and b/Application/org.eclipse.viatra.solver.language.ui/xtend-gen/org/eclipse/viatra/solver/language/validation/.SolverLanguageValidator.xtendbin differ diff --git a/Application/org.eclipse.viatra.solver.language/xtend-gen/org/eclipse/viatra/solver/language/parser/antlr/.SolverLanguageTokenDefInjectingParser.xtendbin b/Application/org.eclipse.viatra.solver.language/xtend-gen/org/eclipse/viatra/solver/language/parser/antlr/.SolverLanguageTokenDefInjectingParser.xtendbin index 30c2ff9e..1bdcce7f 100644 Binary files a/Application/org.eclipse.viatra.solver.language/xtend-gen/org/eclipse/viatra/solver/language/parser/antlr/.SolverLanguageTokenDefInjectingParser.xtendbin and b/Application/org.eclipse.viatra.solver.language/xtend-gen/org/eclipse/viatra/solver/language/parser/antlr/.SolverLanguageTokenDefInjectingParser.xtendbin differ diff --git a/Application/org.eclipse.viatra.solver.language/xtend-gen/org/eclipse/viatra/solver/language/serializer/.SolverLanguageSyntheticTokenSyntacticSequencer.xtendbin b/Application/org.eclipse.viatra.solver.language/xtend-gen/org/eclipse/viatra/solver/language/serializer/.SolverLanguageSyntheticTokenSyntacticSequencer.xtendbin index 261f466c..2c9fbbb2 100644 Binary files a/Application/org.eclipse.viatra.solver.language/xtend-gen/org/eclipse/viatra/solver/language/serializer/.SolverLanguageSyntheticTokenSyntacticSequencer.xtendbin and b/Application/org.eclipse.viatra.solver.language/xtend-gen/org/eclipse/viatra/solver/language/serializer/.SolverLanguageSyntheticTokenSyntacticSequencer.xtendbin differ diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/ModelGenerationMethodProvider.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/ModelGenerationMethodProvider.xtend index 6fbbc779..78eda150 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/ModelGenerationMethodProvider.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/ModelGenerationMethodProvider.xtend @@ -24,9 +24,12 @@ import java.util.Collection import java.util.List import java.util.Map import java.util.Set +import org.eclipse.viatra.query.runtime.api.GenericQueryGroup import org.eclipse.viatra.query.runtime.api.IPatternMatch import org.eclipse.viatra.query.runtime.api.IQuerySpecification +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher +import org.eclipse.viatra.query.runtime.emf.EMFScope import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule @@ -122,6 +125,9 @@ class ModelGenerationMethodProvider { val relationConstraints = relationConstraintCalculator.calculateRelationConstraints(logicProblem) val queries = patternProvider.generateQueries(logicProblem, emptySolution, statistics, existingQueries, workspace, typeInferenceMethod, scopePropagatorStrategy, relationConstraints, hints, writeFiles) + val queryEngine = ViatraQueryEngine.on(new EMFScope(emptySolution)) + GenericQueryGroup.of(queries.allQueries).prepare(queryEngine) + val scopePropagator = createScopePropagator(scopePropagatorStrategy, emptySolution, hints, queries, statistics) scopePropagator.propagateAllScopeConstraints val objectRefinementRules = refinementRuleProvider.createObjectRefinementRules(logicProblem, emptySolution, diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/MultiplicityGoalConstraintCalculator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/MultiplicityGoalConstraintCalculator.xtend index b28cd584..392ab3ee 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/MultiplicityGoalConstraintCalculator.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/MultiplicityGoalConstraintCalculator.xtend @@ -3,29 +3,31 @@ package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality import org.eclipse.emf.common.notify.Notifier import org.eclipse.viatra.query.runtime.api.IQuerySpecification import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine -import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher import org.eclipse.viatra.query.runtime.emf.EMFScope class MultiplicityGoalConstraintCalculator { val String targetRelationName val IQuerySpecification querySpecification - var ViatraQueryMatcher matcher + var MultiplicityCalculator calculator val boolean containment + val int lowerBound val int cost - public new(String targetRelationName, IQuerySpecification querySpecification, boolean containment, int cost) { + new(String targetRelationName, IQuerySpecification querySpecification, boolean containment, int lowerBound, int cost) { this.targetRelationName = targetRelationName this.querySpecification = querySpecification - this.matcher = null + this.calculator = null this.containment = containment + this.lowerBound = lowerBound this.cost = cost } new(MultiplicityGoalConstraintCalculator other) { this.targetRelationName = other.targetRelationName this.querySpecification = other.querySpecification - this.matcher = null + this.calculator = null this.containment = other.containment + this.lowerBound = other.lowerBound this.cost = other.cost } @@ -39,16 +41,12 @@ class MultiplicityGoalConstraintCalculator { def init(Notifier notifier) { val engine = ViatraQueryEngine.on(new EMFScope(notifier)) - matcher = querySpecification.getMatcher(engine) + val matcher = querySpecification.getMatcher(engine) + calculator = RemainingMultiplicityCalculator.of(matcher, lowerBound) } def calculateValue() { - var res = 0 - val allMatches = this.matcher.allMatches - for(match : allMatches) { - val missingMultiplicity = match.get(2) as Integer - res += missingMultiplicity - } + val res = calculator.multiplicity // if(res>0) // println(targetRelationName+ " all missing multiplicities: "+res + "*"+cost+"="+res*cost) return res*cost 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 9b4dff0f..db22b95c 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 @@ -33,7 +33,7 @@ import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { static val CACHE_SIZE = 10000 - + val boolean updateHeuristic val Map scopeBounds val LinearBoundedExpression topLevelBounds @@ -185,22 +185,6 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { if (bounds.upperBound !== null && bounds.upperBound < 0) { throw new IllegalArgumentException("Negative upper bound: " + bounds) } - } - - private static def getCalculatedMultiplicity(ViatraQueryMatcher matcher, - PartialInterpretation p) { - val match = matcher.newEmptyMatch - match.set(0, p.problem) - match.set(1, p) - val iterator = matcher.streamAllMatches(match).iterator - if (!iterator.hasNext) { - return null - } - val value = iterator.next.get(2) as Integer - if (iterator.hasNext) { - throw new IllegalArgumentException("Multiplicity calculation query has more than one match") - } - value } @FinalFieldsConstructor @@ -243,7 +227,12 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { IQuerySpecification> hasElementInContainmentQuery, Map>> allPatternsByName, Collection hints, int maximumNuberOfNewNodes) { - infinity = maximumNuberOfNewNodes * INFINITY_SCALE + infinity = if (maximumNuberOfNewNodes <= Integer.MAX_VALUE / INFINITY_SCALE) { + maximumNuberOfNewNodes * INFINITY_SCALE + } else { + Integer.MAX_VALUE + } + queryEngine = ViatraQueryEngine.on(new EMFScope(p)) this.allPatternsByName = allPatternsByName updatersBuilder = ImmutableList.builder @@ -254,7 +243,7 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { buildConstainmentRootConstraints(containmentConstraints.keySet, hasElementInContainmentQuery) for (pair : constraints.entrySet) { val constraint = pair.key - if (!constraint.containment) { + if (!constraint.containment && !constraint.container) { buildNonContainmentConstraints(constraint, pair.value) } } @@ -289,8 +278,8 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { val typeCoefficients = subtypeDimensions.get(containedType) val orphansLowerBoundCoefficients = new HashMap(typeCoefficients) val orphansUpperBoundCoefficients = new HashMap(typeCoefficients) - val unfinishedMultiplicitiesMatchersBuilder = ImmutableList.builder - val remainingContentsQueriesBuilder = ImmutableList.builder + val unfinishedMultiplicitiesBuilder = ImmutableList.builder + val remainingContentsBuilder = ImmutableList.builder for (pair : constraints) { val constraint = pair.key val containerCoefficients = subtypeDimensions.get(constraint.sourceType) @@ -301,23 +290,21 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { } orphansUpperBoundCoefficients.addCoefficients(-constraint.lowerBound, containerCoefficients) val queries = pair.value - if (constraint.constrainsUnfinished) { - if (queries.unfinishedMultiplicityQuery === null) { - throw new IllegalArgumentException( - "Containment constraints need unfinished multiplicity queries") + if (queries.existingMultiplicityQuery !== null) { + val matcher = queries.existingMultiplicityQuery.getMatcher(queryEngine) + if (constraint.constrainsUnfinished) { + unfinishedMultiplicitiesBuilder.add( + RemainingMultiplicityCalculator.of(matcher, constraint.lowerBound)) } - unfinishedMultiplicitiesMatchersBuilder.add( - queries.unfinishedMultiplicityQuery.getMatcher(queryEngine)) - } - if (queries.remainingContentsQuery === null) { - throw new IllegalArgumentException("Containment constraints need remaining contents queries") + remainingContentsBuilder.add(RemainingMultiplicityCalculator.of(matcher, constraint.upperBound)) + } else if (constraint.constrainsUnfinished) { + throw new IllegalArgumentException("Containment constraints need multiplicity queries") } - remainingContentsQueriesBuilder.add(queries.remainingContentsQuery.getMatcher(queryEngine)) } val orphanLowerBound = orphansLowerBoundCoefficients.toExpression val orphanUpperBound = orphansUpperBoundCoefficients.toExpression - val updater = new ContainmentConstraintUpdater(containedType.name, orphanLowerBound, orphanUpperBound, - unfinishedMultiplicitiesMatchersBuilder.build, remainingContentsQueriesBuilder.build) + val updater = new ContainmentConstraintUpdater(orphanLowerBound, orphanUpperBound, + unfinishedMultiplicitiesBuilder.build, remainingContentsBuilder.build) updatersBuilder.add(updater) } @@ -336,17 +323,21 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { private def buildNonContainmentConstraints(RelationMultiplicityConstraint constraint, UnifinishedMultiplicityQueries queries) { + if (!constraint.reference) { + return + } if (constraint.constrainsRemainingInverse) { - if (queries.unfinishedMultiplicityQuery === null) { - throw new IllegalArgumentException("Reference constraints need unfinished multiplicity queries") - } - val unfinishedMultiplicityMatcher = queries.unfinishedMultiplicityQuery.getMatcher(queryEngine) - if (queries.remainingInverseMultiplicityQuery === null) { - throw new IllegalArgumentException( - "Reference constraints need remaining inverse multiplicity queries") + if (queries.getExistingMultiplicityQuery === null) { + throw new IllegalArgumentException("Reference constraints need unfinished multiplicity queries: " + + constraint.relation) } - val remainingInverseMultiplicityMatcher = queries.remainingInverseMultiplicityQuery.getMatcher( + val existingMultiplicityMatcher = queries.getExistingMultiplicityQuery.getMatcher(queryEngine) + val unfinishedMultiplicityCalculator = RemainingMultiplicityCalculator.of(existingMultiplicityMatcher, + constraint.lowerBound) + val existingInverseMultiplicityMatcher = queries.existingInverseMultiplicityQuery.getMatcher( queryEngine) + val remainingInverseMultiplicityCalculator = new RemainingInverseMultiplicityCalculator( + existingInverseMultiplicityMatcher, constraint.upperBound) val availableMultiplicityCoefficients = new HashMap availableMultiplicityCoefficients.addCoefficients(constraint.inverseUpperBound, subtypeDimensions.get(constraint.targetType)) @@ -354,18 +345,18 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { subtypeDimensions.get(constraint.targetType)) val availableMultiplicity = availableMultiplicityCoefficients.toExpression updatersBuilder.add( - new UnfinishedMultiplicityConstraintUpdater(constraint.relation.name, availableMultiplicity, - unfinishedMultiplicityMatcher, remainingInverseMultiplicityMatcher)) + new UnfinishedMultiplicityConstraintUpdater(availableMultiplicity, unfinishedMultiplicityCalculator, + remainingInverseMultiplicityCalculator)) } if (constraint.constrainsUnrepairable) { - if (queries.unrepairableMultiplicityQuery === null) { - throw new IllegalArgumentException("Reference constraints need unrepairable multiplicity queries") + if (queries.existingMultiplicityQuery.parameters.size < 5) { + throw new IllegalArgumentException("Reference constraints need repairable multiplicity queries: " + + constraint.relation) } - val unrepairableMultiplicityMatcher = queries.unrepairableMultiplicityQuery.getMatcher(queryEngine) + val matcher = queries.existingMultiplicityQuery.getMatcher(queryEngine) + val calculator = new UnrepairableMultiplicityCalculator(matcher, constraint.lowerBound) val targetTypeCardinality = typeBounds.get(constraint.targetType) - updatersBuilder.add( - new UnrepairableMultiplicityConstraintUpdater(constraint.relation.name, targetTypeCardinality, - unrepairableMultiplicityMatcher)) + updatersBuilder.add(new UnrepairableMultiplicityConstraintUpdater(targetTypeCardinality, calculator)) } } @@ -470,11 +461,10 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { @FinalFieldsConstructor private static class ContainmentConstraintUpdater implements RelationConstraintUpdater { - val String name val LinearBoundedExpression orphansLowerBound val LinearBoundedExpression orphansUpperBound - val List> unfinishedMultiplicitiesMatchers - val List> remainingContentsQueries + val List> unfinishedMultiplicities + val List> remainingContents override update(PartialInterpretation p) { tightenLowerBound(p) @@ -483,12 +473,9 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { private def tightenLowerBound(PartialInterpretation p) { var int sum = 0 - for (matcher : remainingContentsQueries) { - val value = matcher.getCalculatedMultiplicity(p) - if (value === null) { - throw new IllegalArgumentException("Remaining contents count is missing for " + name) - } - if (value == -1) { + for (calculator : remainingContents) { + val value = calculator.getMultiplicity(p) + if (value < 0) { // Infinite upper bound, no need to tighten. return } @@ -499,11 +486,8 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { private def tightenUpperBound(PartialInterpretation p) { var int sum = 0 - for (matcher : unfinishedMultiplicitiesMatchers) { - val value = matcher.getCalculatedMultiplicity(p) - if (value === null) { - throw new IllegalArgumentException("Unfinished multiplicity is missing for " + name) - } + for (calculator : unfinishedMultiplicities) { + val value = calculator.getMultiplicity(p) sum += value } orphansUpperBound.tightenLowerBound(sum) @@ -531,20 +515,13 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { @FinalFieldsConstructor private static class UnfinishedMultiplicityConstraintUpdater implements RelationConstraintUpdater { - val String name val LinearBoundedExpression availableMultiplicityExpression - val ViatraQueryMatcher unfinishedMultiplicityMatcher - val ViatraQueryMatcher remainingInverseMultiplicityMatcher + val MultiplicityCalculator unfinishedMultiplicityCalculator + val MultiplicityCalculator remainingInverseMultiplcityCalculator override update(PartialInterpretation p) { - val unfinishedMultiplicity = unfinishedMultiplicityMatcher.getCalculatedMultiplicity(p) - if (unfinishedMultiplicity === null) { - throw new IllegalArgumentException("Unfinished multiplicity is missing for " + name) - } - val remainingInverseMultiplicity = remainingInverseMultiplicityMatcher.getCalculatedMultiplicity(p) - if (remainingInverseMultiplicity === null) { - throw new IllegalArgumentException("Remaining inverse multiplicity is missing for " + name) - } + val unfinishedMultiplicity = unfinishedMultiplicityCalculator.getMultiplicity(p) + val remainingInverseMultiplicity = remainingInverseMultiplcityCalculator.getMultiplicity(p) val int requiredMultiplicity = unfinishedMultiplicity - remainingInverseMultiplicity availableMultiplicityExpression.tightenLowerBound(requiredMultiplicity) } @@ -552,15 +529,11 @@ class PolyhedronScopePropagator extends TypeHierarchyScopePropagator { @FinalFieldsConstructor private static class UnrepairableMultiplicityConstraintUpdater implements RelationConstraintUpdater { - val String name val LinearBoundedExpression targetCardinalityExpression - val ViatraQueryMatcher unrepairableMultiplicityMatcher + val MultiplicityCalculator calculator override update(PartialInterpretation p) { - val value = unrepairableMultiplicityMatcher.getCalculatedMultiplicity(p) - if (value === null) { - throw new IllegalArgumentException("Unrepairable multiplicity is missing for " + name) - } + val value = calculator.getMultiplicity(p) targetCardinalityExpression.tightenLowerBound(value) } } diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RelationConstraintCalculator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RelationConstraintCalculator.xtend index 3e4fea8a..7fec452f 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RelationConstraintCalculator.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RelationConstraintCalculator.xtend @@ -46,11 +46,11 @@ class RelationMultiplicityConstraint { def constrainsUnrepairable() { // TODO Optimize the unrepairable matches computation, // or come up with a heuristic when does computing unrepairables worth the overhead. - constrainsUnfinished && canHaveMultipleSourcesPerTarget && false + constrainsUnfinished && canHaveMultipleSourcesPerTarget && reference } def constrainsRemainingInverse() { - lowerBound >= 1 && !containment && inverseUpperBoundFinite + lowerBound >= 1 && !containment && !container && inverseUpperBoundFinite && reference } def constrainsRemainingContents() { @@ -61,6 +61,18 @@ class RelationMultiplicityConstraint { constrainsUnfinished || constrainsUnrepairable || constrainsRemainingInverse || constrainsRemainingContents } + def isSourceTypeComplex() { + getParamTypeReference(0) instanceof ComplexTypeReference + } + + def isTargetTypeComplex() { + getParamTypeReference(1) instanceof ComplexTypeReference + } + + def isReference() { + sourceTypeComplex && targetTypeComplex + } + def getSourceType() { getParamType(0) } @@ -69,15 +81,20 @@ class RelationMultiplicityConstraint { getParamType(1) } - private def getParamType(int i) { + private def getParamTypeReference(int i) { val parameters = relation.parameters if (i < parameters.size) { - val firstParam = parameters.get(i) - if (firstParam instanceof ComplexTypeReference) { - return firstParam.referred - } + return parameters.get(i) + } + throw new IllegalArgumentException("Argument index out of range") + } + + private def getParamType(int i) { + val reference = getParamTypeReference(i) + if (reference instanceof ComplexTypeReference) { + return reference.referred } - throw new IllegalArgumentException("Constraint with unknown source type") + throw new IllegalArgumentException("Constraint with primitive type") } } diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RemainingMultiplicityCalculator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RemainingMultiplicityCalculator.xtend new file mode 100644 index 00000000..48b52d28 --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RemainingMultiplicityCalculator.xtend @@ -0,0 +1,111 @@ +package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality + +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation +import java.util.Iterator +import org.eclipse.viatra.query.runtime.api.IPatternMatch +import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher +import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor + +@FinalFieldsConstructor +abstract class MultiplicityCalculator { + val ViatraQueryMatcher matcher + + def getMultiplicity() { + val iterator = matcher.streamAllMatches.iterator + getMultiplicity(iterator) + } + + def getMultiplicity(PartialInterpretation interpretation) { + val partialMatch = matcher.newEmptyMatch + partialMatch.set(0, interpretation.problem) + partialMatch.set(1, interpretation) + val iterator = matcher.streamAllMatches(partialMatch).iterator + getMultiplicity(iterator) + } + + protected def int getMultiplicity(Iterator iterator) +} + +class RemainingMultiplicityCalculator extends MultiplicityCalculator { + val int bound + + @FinalFieldsConstructor + private new() { + } + + protected override getMultiplicity(Iterator iterator) { + var res = 0 + while (iterator.hasNext) { + val match = iterator.next + val existingMultiplicity = match.get(3) as Integer + if (existingMultiplicity < bound) { + res += bound - existingMultiplicity + } + } + res + } + + static def of(ViatraQueryMatcher matcher, int bound) { + if (bound < 0) { + new RemainingInfiniteMultiplicityCalculator(matcher) + } else { + new RemainingMultiplicityCalculator(matcher, bound) + } + } +} + +package class RemainingInfiniteMultiplicityCalculator extends MultiplicityCalculator { + + @FinalFieldsConstructor + package new() { + } + + protected override getMultiplicity(Iterator iterator) { + if (iterator.hasNext) { + -1 + } else { + 0 + } + } +} + +@FinalFieldsConstructor +class UnrepairableMultiplicityCalculator extends MultiplicityCalculator { + val int lowerBound + + override protected getMultiplicity(Iterator iterator) { + var res = 0 + while (iterator.hasNext) { + val match = iterator.next + val existingMultiplicity = match.get(3) as Integer + if (existingMultiplicity < lowerBound) { + val missingMultiplcity = lowerBound - existingMultiplicity + val numerOfRepairMatches = match.get(4) as Integer + val unrepairableMultiplicty = missingMultiplcity - numerOfRepairMatches + if (unrepairableMultiplicty > res) { + res = unrepairableMultiplicty + } + } + } + res + } +} + +@FinalFieldsConstructor +class RemainingInverseMultiplicityCalculator extends MultiplicityCalculator { + val int upperBound + + override protected getMultiplicity(Iterator iterator) { + var res = 0 + while (iterator.hasNext) { + val match = iterator.next + val existingMultiplicity = match.get(3) as Integer + if (existingMultiplicity < upperBound) { + val availableMultiplicity = upperBound - existingMultiplicity + val numberOfRepairMatches = match.get(4) as Integer + res += Math.min(availableMultiplicity, numberOfRepairMatches) + } + } + res + } +} diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ScopePropagator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ScopePropagator.xtend index 8350c7f4..132ca8e8 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ScopePropagator.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ScopePropagator.xtend @@ -4,6 +4,7 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope import java.util.HashMap @@ -80,6 +81,10 @@ class ScopePropagator { } def decrementTypeScope(PartialTypeInterpratation t) { + val isPrimitive = t instanceof PartialPrimitiveInterpretation || t === null + if (isPrimitive) { + return + } // println('''Adding to «(t as PartialComplexTypeInterpretation).interpretationOf.name»''') val targetScope = type2Scope.get(t) if (targetScope !== null) { diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PatternProvider.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PatternProvider.xtend index ac4a0855..2f7c9e2d 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PatternProvider.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PatternProvider.xtend @@ -53,10 +53,8 @@ class ModalPatternQueries { @Data class UnifinishedMultiplicityQueries { - val IQuerySpecification> unfinishedMultiplicityQuery - val IQuerySpecification> unrepairableMultiplicityQuery - val IQuerySpecification> remainingInverseMultiplicityQuery - val IQuerySpecification> remainingContentsQuery + val IQuerySpecification> existingMultiplicityQuery + val IQuerySpecification> existingInverseMultiplicityQuery } class PatternProvider { @@ -108,9 +106,8 @@ class PatternProvider { val unfinishedMultiplicities = patternGenerator.unfinishedIndexer.getUnfinishedMultiplicityQueries(relationConstraints.multiplicityConstraints) val multiplicityConstraintQueries = unfinishedMultiplicities.mapValues [ - new UnifinishedMultiplicityQueries(unfinishedMultiplicityQueryName?.lookup(queries), - unrepairableMultiplicityQueryName?.lookup(queries), - remainingInverseMultiplicityQueryName?.lookup(queries), remainingContentsQueryName?.lookup(queries)) + new UnifinishedMultiplicityQueries(existingMultiplicityQueryName?.lookup(queries), + existingInverseMultiplicityQueryName?.lookup(queries)) ] val hasElementInContainmentQuery = patternGenerator.typeRefinementGenerator.hasElementInContainmentName.lookup( queries) diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/UnfinishedIndexer.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/UnfinishedIndexer.xtend index a8a07756..65ad3d48 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/UnfinishedIndexer.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/UnfinishedIndexer.xtend @@ -14,10 +14,8 @@ import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* @Data class UnifinishedMultiplicityQueryNames { - val String unfinishedMultiplicityQueryName - val String unrepairableMultiplicityQueryName - val String remainingInverseMultiplicityQueryName - val String remainingContentsQueryName + val String existingMultiplicityQueryName + val String existingInverseMultiplicityQueryName } class UnfinishedIndexer { @@ -58,147 +56,94 @@ class UnfinishedIndexer { def generateUnfinishedMultiplicityQueries(List constraints, Map fqn2PQuery) ''' «FOR constraint : constraints» - «IF constraint.constrainsUnfinished» - private pattern «unfinishedMultiplicityName(constraint)»_helper(problem:LogicProblem, interpretation:PartialInterpretation, object:DefinedElement, missingMultiplicity:java Integer) { + «IF constraint.shouldIndexExistingMultiplicites(indexUpperMultiplicities)» + private pattern «existingMultiplicityName(constraint)»(problem:LogicProblem, interpretation:PartialInterpretation, object:DefinedElement, numberOfExistingReferences:java Integer«IF constraint.shouldIndexRepairMultiplcities(indexUpperMultiplicities)», numberOfRepairMatches: java Integer«ENDIF») { find interpretation(problem,interpretation); find mustExist(problem,interpretation,object); «base.typeIndexer.referInstanceOf(constraint.sourceType,Modality::MUST,"object")» numberOfExistingReferences == count «base.referRelation(constraint.relation,"object","_",Modality.MUST,fqn2PQuery)» - check(numberOfExistingReferences < «constraint.lowerBound»); - missingMultiplicity == eval(«constraint.lowerBound»-numberOfExistingReferences); - } - - pattern «unfinishedMultiplicityName(constraint)»(problem:LogicProblem, interpretation:PartialInterpretation, missingMultiplicity:java Integer) { - find interpretation(problem,interpretation); - missingMultiplicity == sum find «unfinishedMultiplicityName(constraint)»_helper(problem, interpretation, _, #_); + «IF constraint.shouldIndexRepairMultiplcities(indexUpperMultiplicities)» + numberOfRepairMatches == count find «repairMatchName(constraint)»(problem, interpretation, object, _); + «ENDIF» } «ENDIF» - «IF indexUpperMultiplicities» - «IF constraint.constrainsUnrepairable || constraint.constrainsRemainingInverse» - private pattern «repairMatchName(constraint)»(problem:LogicProblem, interpretation:PartialInterpretation, source:DefinedElement, target:DefinedElement) { - «IF base.isRepresentative(constraint.relation, constraint.inverseRelation) && constraint.relation instanceof RelationDeclaration» - «base.relationRefinementGenerator.referRefinementQuery(constraint.relation as RelationDeclaration, constraint.inverseRelation, "_", "_", "source", "target")» - «ELSE» - «IF base.isRepresentative(constraint.inverseRelation, constraint.relation) && constraint.inverseRelation instanceof RelationDeclaration» - «base.relationRefinementGenerator.referRefinementQuery(constraint.inverseRelation as RelationDeclaration, constraint.relation, "_", "_", "target", "source")» - «ELSE» - find interpretation(problem,interpretation); - find mustExist(problem,interpretation,source); - «base.typeIndexer.referInstanceOf(constraint.sourceType,Modality::MUST,"source")» - find mustExist(problem,interpretation,target); - «base.typeIndexer.referInstanceOf(constraint.targetType,Modality::MUST,"target")» - neg «base.referRelation(constraint.relation,"source","target",Modality.MUST,fqn2PQuery)» - «base.referRelation(constraint.relation,"source","target",Modality.MAY,fqn2PQuery)» - «ENDIF» - «ENDIF» - } - «ENDIF» - - «IF constraint.constrainsUnrepairable» - private pattern «unrepairableMultiplicityName(constraint)»_helper(problem:LogicProblem, interpretation:PartialInterpretation, object:DefinedElement, unrepairableMultiplicity:java Integer) { - find «unfinishedMultiplicityName(constraint)»_helper(problem, interpretation, object, missingMultiplicity); - numberOfRepairMatches == count find «repairMatchName(constraint)»(problem, interpretation, object, _); - check(numberOfRepairMatches < missingMultiplicity); - unrepairableMultiplicity == eval(missingMultiplicity-numberOfRepairMatches); - } - - private pattern «unrepairableMultiplicityName(constraint)»(problem:LogicProblem, interpretation:PartialInterpretation, unrepairableMultiplicity:java Integer) { - find interpretation(problem,interpretation); - unrepairableMultiplicity == max find «unrepairableMultiplicityName(constraint)»_helper(problem, interpretation, _, #_); - } or { - find interpretation(problem,interpretation); - neg find «unrepairableMultiplicityName(constraint)»_helper(problem, interpretation, _, _); - unrepairableMultiplicity == 0; - } - «ENDIF» - - «IF constraint.constrainsRemainingInverse» - private pattern «remainingMultiplicityName(constraint)»_helper(problem:LogicProblem, interpretation:PartialInterpretation, object:DefinedElement, remainingMultiplicity:java Integer) { - find interpretation(problem,interpretation); - find mustExist(problem,interpretation,object); - «base.typeIndexer.referInstanceOf(constraint.targetType,Modality::MUST,"object")» - numberOfExistingReferences == count «base.referRelation(constraint.relation,"_","object",Modality.MUST,fqn2PQuery)» - check(numberOfExistingReferences < «constraint.inverseUpperBound»); - numberOfRepairMatches == count find «repairMatchName(constraint)»(problem, interpretation, _, object); - remainingMultiplicity == eval(Math.min(«constraint.inverseUpperBound»-numberOfExistingReferences, numberOfRepairMatches)); - } - - pattern «remainingMultiplicityName(constraint)»(problem:LogicProblem, interpretation:PartialInterpretation, remainingMultiplicity:java Integer) { - find interpretation(problem,interpretation); - remainingMultiplicity == sum find «remainingMultiplicityName(constraint)»_helper(problem, interpretation, _, #_); - } - «ENDIF» - - «IF constraint.constrainsRemainingContents» - «IF constraint.upperBoundFinite» - private pattern «remainingContentsName(constraint)»_helper(problem:LogicProblem, interpretation:PartialInterpretation, object:DefinedElement, remainingMultiplicity:java Integer) { - find interpretation(problem,interpretation); - find mustExist(problem,interpretation,object); - «base.typeIndexer.referInstanceOf(constraint.sourceType,Modality::MUST,"object")» - numberOfExistingReferences == count «base.referRelation(constraint.relation,"object","_",Modality.MUST,fqn2PQuery)» - check(numberOfExistingReferences < «constraint.upperBound»); - remainingMultiplicity == eval(«constraint.upperBound»-numberOfExistingReferences); - } - - pattern «remainingContentsName(constraint)»(problem:LogicProblem, interpretation:PartialInterpretation, remainingMultiplicity:java Integer) { - find interpretation(problem,interpretation); - remainingMultiplicity == sum find «remainingContentsName(constraint)»_helper(problem, interpretation, _, #_); - } + «IF constraint.shouldIndexRepairMatches(indexUpperMultiplicities)» + private pattern «repairMatchName(constraint)»(problem:LogicProblem, interpretation:PartialInterpretation, source:DefinedElement, target:DefinedElement) { + «IF constraint.containment || constraint.container» + «repairMatchFallback(constraint, fqn2PQuery)» + «ELSEIF base.isRepresentative(constraint.relation, constraint.inverseRelation) && constraint.relation instanceof RelationDeclaration» + «base.relationRefinementGenerator.referRefinementQuery(constraint.relation as RelationDeclaration, constraint.inverseRelation, "_", "_", "source", "target")» + «ELSEIF base.isRepresentative(constraint.inverseRelation, constraint.relation) && constraint.inverseRelation instanceof RelationDeclaration» + «base.relationRefinementGenerator.referRefinementQuery(constraint.inverseRelation as RelationDeclaration, constraint.relation, "_", "_", "target", "source")» «ELSE» - pattern «remainingContentsName(constraint)»_helper(problem:LogicProblem, interpretation:PartialInterpretation) { - find interpretation(problem,interpretation); - find mustExist(problem,interpretation,object); - «base.typeIndexer.referInstanceOf(constraint.sourceType,Modality::MUST,"object")» - } - - pattern «remainingContentsName(constraint)»(problem:LogicProblem, interpretation:PartialInterpretation, remainingMultiplicity:java Integer) { - find interpretation(problem,interpretation); - find «remainingContentsName(constraint)»_helper(problem, interpretation); - remainingMultiplicity == -1; - } or { - find interpretation(problem,interpretation); - neg find «remainingContentsName(constraint)»_helper(problem, interpretation); - remainingMultiplicity == 0; - } + «repairMatchFallback(constraint, fqn2PQuery)» «ENDIF» - «ENDIF» + } + «ENDIF» + + «IF constraint.shouldIndexInverseMultiplicites(indexUpperMultiplicities)» + private pattern «existingInverseMultiplicityName(constraint)»(problem:LogicProblem, interpretation:PartialInterpretation, object:DefinedElement, numberOfExistingReferences:java Integer, numberOfRepairMatches: java Integer) { + find interpretation(problem,interpretation); + find mustExist(problem,interpretation,object); + «base.typeIndexer.referInstanceOf(constraint.targetType,Modality::MUST,"object")» + numberOfExistingReferences == count «base.referRelation(constraint.relation,"_","object",Modality.MUST,fqn2PQuery)» + numberOfRepairMatches == count find «repairMatchName(constraint)»(problem, interpretation, _, object); + } «ENDIF» «ENDFOR» ''' - def String unfinishedMultiplicityName( - RelationMultiplicityConstraint constraint) '''unfinishedLowerMultiplicity_«base.canonizeName(constraint.relation.name)»''' + private def repairMatchFallback(RelationMultiplicityConstraint constraint, Map fqn2PQuery) ''' + find interpretation(problem,interpretation); + find mustExist(problem,interpretation,source); + «base.typeIndexer.referInstanceOf(constraint.sourceType,Modality::MUST,"source")» + find mustExist(problem,interpretation,target); + «base.typeIndexer.referInstanceOf(constraint.targetType,Modality::MUST,"target")» + neg «base.referRelation(constraint.relation,"source","target",Modality.MUST,fqn2PQuery)» + «base.referRelation(constraint.relation,"source","target",Modality.MAY,fqn2PQuery)» + ''' + + def String existingMultiplicityName( + RelationMultiplicityConstraint constraint) '''existingMultiplicity_«base.canonizeName(constraint.relation.name)»''' - def String unrepairableMultiplicityName( - RelationMultiplicityConstraint constraint) '''unrepairableLowerMultiplicity_«base.canonizeName(constraint.relation.name)»''' + def String existingInverseMultiplicityName( + RelationMultiplicityConstraint constraint) '''existingInverseMultiplicity_«base.canonizeName(constraint.relation.name)»''' private def String repairMatchName( RelationMultiplicityConstraint constraint) '''repair_«base.canonizeName(constraint.relation.name)»''' - def String remainingMultiplicityName( - RelationMultiplicityConstraint constraint) '''remainingInverseUpperMultiplicity_«base.canonizeName(constraint.relation.name)»''' - - def String remainingContentsName( - RelationMultiplicityConstraint constraint) '''remainingContents_«base.canonizeName(constraint.relation.name)»''' - def getUnfinishedMultiplicityQueries(List constraints) { constraints.toInvertedMap [ constraint | new UnifinishedMultiplicityQueryNames( - if(constraint.constrainsUnfinished) unfinishedMultiplicityName(constraint) else null, - if (indexUpperMultiplicities && constraint.constrainsUnrepairable) - unrepairableMultiplicityName(constraint) - else - null, - if (indexUpperMultiplicities && constraint.constrainsRemainingInverse) - remainingMultiplicityName(constraint) - else - null, - if (indexUpperMultiplicities && constraint.constrainsRemainingContents) - remainingContentsName(constraint) - else + if (constraint.shouldIndexExistingMultiplicites(indexUpperMultiplicities)) { + existingMultiplicityName(constraint) + } else { + null + }, + if (constraint.shouldIndexInverseMultiplicites(indexUpperMultiplicities)) { + existingInverseMultiplicityName(constraint) + } else { null + } ) ] } + + static def shouldIndexExistingMultiplicites(RelationMultiplicityConstraint it, boolean indexUpperMultiplicities) { + constrainsUnfinished || (indexUpperMultiplicities && constrainsRemainingContents) + } + + static def shouldIndexRepairMultiplcities(RelationMultiplicityConstraint it, boolean indexUpperMultiplicities) { + shouldIndexExistingMultiplicites(indexUpperMultiplicities) && constrainsUnrepairable + } + + static def shouldIndexInverseMultiplicites(RelationMultiplicityConstraint it, boolean indexUpperMultiplicities) { + indexUpperMultiplicities && constrainsRemainingInverse + } + + static def shouldIndexRepairMatches(RelationMultiplicityConstraint it, boolean indexUpperMultiplicities) { + shouldIndexRepairMultiplcities(indexUpperMultiplicities) || + shouldIndexInverseMultiplicites(indexUpperMultiplicities) + } } diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/GoalConstraintProvider.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/GoalConstraintProvider.xtend index d2ee80dc..7dc21410 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/GoalConstraintProvider.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/GoalConstraintProvider.xtend @@ -14,9 +14,10 @@ class GoalConstraintProvider { if (constraint.constrainsUnfinished) { val queries = entry.value val targetRelationName = constraint.relation.name - val query = queries.unfinishedMultiplicityQuery + val query = queries.existingMultiplicityQuery val containment = constraint.containment - res += new MultiplicityGoalConstraintCalculator(targetRelationName, query, containment, 1) + val lowerBound = constraint.lowerBound + res += new MultiplicityGoalConstraintCalculator(targetRelationName, query, containment, 1, lowerBound) } } return res 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 3033eca7..b9056685 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 @@ -26,6 +26,7 @@ import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityChecker import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.InconsistentScopeGlobalConstraint import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.LoggerSolutionFoundHandler import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ModelGenerationCompositeObjective +import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.NumericSolver import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PartialModelAsLogicInterpretation import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ScopeObjective import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.SurelyViolatedObjectiveGlobalConstraint @@ -42,7 +43,6 @@ import org.eclipse.viatra.dse.api.DesignSpaceExplorer import org.eclipse.viatra.dse.api.DesignSpaceExplorer.DseLoggingLevel import org.eclipse.viatra.dse.solutionstore.SolutionStore import org.eclipse.viatra.dse.statecode.IStateCoderFactory -import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.NumericSolver class ViatraReasoner extends LogicReasoner { val PartialInterpretationInitialiser initialiser = new PartialInterpretationInitialiser() diff --git a/Tests/MODELS2020-CaseStudies/case.study.pledge.model/model/TaxationWithRoot.aird b/Tests/MODELS2020-CaseStudies/case.study.pledge.model/model/TaxationWithRoot.aird index e5bce79e..a4252796 100644 --- a/Tests/MODELS2020-CaseStudies/case.study.pledge.model/model/TaxationWithRoot.aird +++ b/Tests/MODELS2020-CaseStudies/case.study.pledge.model/model/TaxationWithRoot.aird @@ -1,5151 +1,5151 @@ - - - - TaxationWithRoot.ecore - TaxationWithRoot.genmodel - platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore - - - - - - - - - - - - - - - - - - - - - - - bold - - - - - - - bold - - - - - - - - - - bold - - - - - - - - - - bold - - - - bold - - - - - - - bold - - - - bold - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - italic - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - - italic - - - - - - - - - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - - - - - - - - - bold - - - - - - - - bold - - - - - - - - - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - bold - - - - - - - - - italic - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - bold - - - - - - - - bold - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - italic - - - - - - - - - - - - - - - - bold - - - - - - - - bold - - - - - - - - - italic - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - - italic - - - - - - - - bold - - - - - - - - - - - - - - - - - - - - - - - - bold - - - - - - - - bold - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - bold - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - bold - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - bold - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bold - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - bold - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - bold - - - - - - - - bold - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - bold - - - - - - - - bold - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - bold - - - - - - - - bold - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - bold - - - - - - - - bold - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - KEEP_LOCATION - KEEP_SIZE - KEEP_RATIO - - - - - - - - - - - labelSize - bold - - - labelSize - - - - - - - - - - labelSize - bold - - - labelSize - - - - - - - - - - labelSize - bold - - - labelSize - - - - - - - - - - labelSize - bold - - - labelSize - - - - - - - - - - - labelSize - - - labelSize - - - - - - - - - - - labelSize - - - labelSize - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - italic - - - - - - - - - - - - bold - - - bold - - - - - - - - - - - bold - - - bold - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bold - - - bold - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bold - - - bold - - - - - - - - - - - bold - - - bold - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bold - - - bold - - - - - - - - - - - bold - - - bold - - - - - - - - - - - - - - - - - - - - - - bold - - - bold - - - - - - - - - - labelSize - - - labelSize - - - - - - - - - - - - - + + + + TaxationWithRoot.ecore + TaxationWithRoot.genmodel + platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore + + + + + + + + + + + + + + + + + + + + + + + bold + + + + + + + bold + + + + + + + + + + bold + + + + + + + + + + bold + + + + bold + + + + + + + bold + + + + bold + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + italic + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + + italic + + + + + + + + + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + + + + + + + + + bold + + + + + + + + bold + + + + + + + + + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + + italic + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + italic + + + + + + + + + + + + + + + + bold + + + + + + + + bold + + + + + + + + + italic + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + + italic + + + + + + + + bold + + + + + + + + + + + + + + + + + + + + + + + + bold + + + + + + + + bold + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bold + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + labelSize + bold + + + labelSize + + + + + + + + + + labelSize + bold + + + labelSize + + + + + + + + + + labelSize + bold + + + labelSize + + + + + + + + + + labelSize + bold + + + labelSize + + + + + + + + + + + labelSize + + + labelSize + + + + + + + + + + + labelSize + + + labelSize + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + bold + + + bold + + + + + + + + + + + bold + + + bold + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bold + + + bold + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bold + + + bold + + + + + + + + + + + bold + + + bold + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bold + + + bold + + + + + + + + + + + bold + + + bold + + + + + + + + + + + + + + + + + + + + + + bold + + + bold + + + + + + + + + + labelSize + + + labelSize + + + + + + + + + + + + + -- cgit v1.2.3-54-g00ecf