aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver
diff options
context:
space:
mode:
authorLibravatar 20001LastOrder <boqi.chen@mail.mcgill.ca>2020-11-04 01:33:58 -0500
committerLibravatar 20001LastOrder <boqi.chen@mail.mcgill.ca>2020-11-04 01:33:58 -0500
commita20af4d0dbf5eab84ee271d426528aabb5a8ac3b (patch)
treea9ab772ee313125aaf3a941d66e131b408d949ba /Solvers/VIATRA-Solver
parentchanges in settings of measurements (diff)
parentmerge with current master, comment numerical solver related logging (diff)
downloadVIATRA-Generator-a20af4d0dbf5eab84ee271d426528aabb5a8ac3b.tar.gz
VIATRA-Generator-a20af4d0dbf5eab84ee271d426528aabb5a8ac3b.tar.zst
VIATRA-Generator-a20af4d0dbf5eab84ee271d426528aabb5a8ac3b.zip
fix merging issue
Diffstat (limited to 'Solvers/VIATRA-Solver')
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/META-INF/MANIFEST.MF19
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/build.properties3
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/plugin.xml28
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/Modality.java31
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/ModelGenerationMethodProvider.xtend97
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/ModelGenerationStatistics.xtend52
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/MultiplicityGoalConstraintCalculator.xtend46
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/PropagationModality.java8
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/TypeInferenceMethod.xtend44
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/AbstractPolyhedronSaturationOperator.xtend53
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/CbcPolyhedronSolver.xtend241
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ExtendedLinearExpressionBuilderFactory.xtend140
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ExtendedPolyhedronScopePropagatorStrategy.xtend63
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/LinearTypeConstraintHint.xtend32
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/MultiplicityGoalConstraintCalculator.xtend57
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronScopePropagator.xtend522
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronScopePropagatorStrategy.xtend92
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronSolver.xtend186
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RelationConstraintCalculator.xtend156
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RemainingMultiplicityCalculator.xtend111
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ScopePropagator.xtend161
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ScopePropagatorStrategy.xtend71
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/TypeHierarchyScopePropagator.xtend85
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/Z3PolyhedronSolver.xtend272
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/formulacanonization/CanonisedFormulae.xtend2
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/formulacanonization/FormulaCanoniser.xtend36
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/Interval.xtend584
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalAggregationMode.java99
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalAggregationOperator.xtend48
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalHullAggregatorOperator.xtend87
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalRedBlackNode.xtend177
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/RedBlackNode.java1392
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/Reference.java51
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/aggregators/IntervalAggregatorFactory.xtend50
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/aggregators/intervalHull.xtend74
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/GenericTypeIndexer.xtend321
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/GenericTypeRefinementGenerator.xtend186
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PConstraintTransformer.xtend275
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PExpressionGenerator.xtend116
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PatternGenerator.xtend303
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PatternProvider.xtend172
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDeclarationIndexer.xtend158
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDefinitionIndexer.xtend184
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationRefinementGenerator.xtend174
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeIndexer.xtend126
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeIndexerWithPreliminaryTypeAnalysis.xtend144
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeRefinementGenerator.xtend83
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeRefinementWithPreliminaryTypeAnalysis.xtend6
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/UnfinishedIndexer.xtend172
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/UnitPropagationPreconditionGenerator.xtend302
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/GoalConstraintProvider.xtend89
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend825
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/util/ParseUtil.xtend29
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/META-INF/MANIFEST.MF3
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/PartialInterpretation.java24
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/PartialinterpretationPackage.java60
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/Scope.java24
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/BinaryElementRelationLinkImpl.java4
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/BooleanElementImpl.java4
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/IntegerElementImpl.java4
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/NaryRelationLinkElementImpl.java6
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/NaryRelationLinkImpl.java1
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialComplexTypeInterpretationImpl.java3
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialConstantInterpretationImpl.java2
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialFunctionInterpretationImpl.java2
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialInterpretationImpl.java73
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialRelationInterpretationImpl.java7
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialTypeInterpratationImpl.java2
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialinterpretationFactoryImpl.java19
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialinterpretationPackageImpl.java88
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PrimitiveElementImpl.java4
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/RealElementImpl.java4
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/ScopeImpl.java64
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/StringElementImpl.java4
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/UnaryElementRelationLinkImpl.java2
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/model/PartialInterpretation.ecore6
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/model/PartialInterpretation.genmodel14
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretation2logic/InstanceModel2PartialInterpretation.xtend23
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/PartialInterpretationInitialiser.xtend34
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/Descriptor.xtend242
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/NeighbourhoodOptions.xtend22
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2Hash.xtend16
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend491
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2PairwiseNeighbourhoodRepresentation.xtend68
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/AbstractNeighborhoodBasedStateCoderFactory.xtend137
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/IdentifierBasedStateCoderFactory.xtend4
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/NeighbourhoodBasedStateCoderFactory.xtend294
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/PairwiseNeighbourhoodBasedStateCoderFactory.xtend75
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/visualisation/PartialInterpretation2Gml.xtend36
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/META-INF/MANIFEST.MF4
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodBasedGlobalConstraint.xtend21
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodProvider.xtend201
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend331
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend96
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ActivationSelector.xtend24
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BalancedActivationSelector.xtend51
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BasicScopeGlobalConstraint.xtend103
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java207
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend184
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DseUtils.xtend66
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/EvenActivationSelector.xtend20
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java1000
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/InconsistentScopeGlobalConstraint.xtend25
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/LoggerSolutionFoundHandler.xtend24
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend130
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend192
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend67
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PunishSizeObjective.xtend52
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend6
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionCopier.xtend82
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend9
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend120
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend27
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend18
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend54
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend250
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend43
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend35
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend62
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostElementMatchers.xtend137
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostObjectiveHint.xtend68
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend164
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IObjectiveBoundsProvider.xtend8
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IThreeValuedObjective.xtend10
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend52
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java60
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend48
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend80
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjectiveProvider.xtend205
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/META-INF/MANIFEST.MF3
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/GraphvizV8WithMemory.xtend16
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/PartialInterpretation2Graphviz.xtend51
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/VisualisationQueque.xtend8
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.classpath7
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.project28
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.settings/org.eclipse.jdt.core.prefs8
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/MANIFEST.MF387
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.properties3
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.xml14
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/about.html21
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/build.properties4
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSEException.java47
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSETransformationRule.java51
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DesignSpaceExplorer.java622
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Objectives.java153
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Solution.java60
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/SolutionTrajectory.java345
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Strategies.java123
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BestFirstStrategy.java228
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BreadthFirstStrategy.java220
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/DepthFirstStrategy.java188
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/FixedPriorityStrategy.java208
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/HillClimbingStrategy.java142
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/RandomSearchStrategy.java163
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategy.java44
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategyFactory.java13
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ActivationCodesConflictSet.java213
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DesignSpaceManager.java577
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictResolver.java35
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictSet.java83
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseEvmRuleBase.java21
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseIdPoolHelper.java68
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ExplorerThread.java88
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/GlobalContext.java374
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/IDseStrategyContext.java117
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/SingletonSetConflictResolver.java53
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ThreadContext.java542
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/DesignSpace.java106
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IBacktrackListener.java7
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IDesignSpace.java27
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/TrajectoryInfo.java154
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/multithreading/DSEThreadPool.java58
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ActivationFitnessProcessor.java15
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Comparators.java31
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Fitness.java29
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IGlobalConstraint.java58
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IObjective.java110
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/LeveledObjectivesHelper.java114
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ObjectiveComparatorHelper.java217
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/TrajectoryFitness.java84
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/AlwaysSatisfiedDummyHardObjective.java52
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/BaseObjective.java150
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/CompositeObjective.java137
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ConstraintsObjective.java316
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/DepthHardObjective.java89
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueriesGlobalConstraint.java116
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueryType.java14
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NeverSatisfiedDummyHardObjective.java52
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NoRuleActivationsHardObjective.java59
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/TrajectoryCostSoftObjective.java148
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionFoundHandler.java40
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionNameProvider.java18
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/IdBasedSolutionNameProvider.java37
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/LogSolutionHandler.java28
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ModelSaverSolutionFoundHandler.java55
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/SolutionStore.java311
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoder.java82
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoderFactory.java29
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProvider.java45
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProviderFactory.java25
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProvider.java60
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProviderFactory.java18
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependency.java33
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyGraph.java44
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyType.java15
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNode.java100
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNodeType.java17
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoder.java215
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoderFactory.java40
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder.java250
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoderFactory.java38
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/EMFHelper.java424
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/Hasher.java86
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/ValueComparableEObjectStringMap.java63
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/DesignSpaceVisualizerOptions.java56
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IDesignSpaceVisualizer.java39
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IExploreEventHandler.java40
217 files changed, 21862 insertions, 2854 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/META-INF/MANIFEST.MF b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/META-INF/MANIFEST.MF
index 23e3ad13..ec1557e8 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/META-INF/MANIFEST.MF
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/META-INF/MANIFEST.MF
@@ -4,8 +4,12 @@ Bundle-Name: Logic2viatra
4Bundle-SymbolicName: hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatraquery;singleton:=true 4Bundle-SymbolicName: hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatraquery;singleton:=true
5Bundle-Version: 1.0.0.qualifier 5Bundle-Version: 1.0.0.qualifier
6Export-Package: hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra, 6Export-Package: hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra,
7 hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality,
8 hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval,
9 hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval.aggregators,
7 hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns, 10 hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns,
8 hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries 11 hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries,
12 hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules
9Require-Bundle: hu.bme.mit.inf.dslreasoner.logic.model;bundle-version="1.0.0", 13Require-Bundle: hu.bme.mit.inf.dslreasoner.logic.model;bundle-version="1.0.0",
10 hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage;bundle-version="1.0.0", 14 hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage;bundle-version="1.0.0",
11 hu.bme.mit.inf.dslreasoner.ecore2logic;bundle-version="1.0.0", 15 hu.bme.mit.inf.dslreasoner.ecore2logic;bundle-version="1.0.0",
@@ -14,13 +18,16 @@ Require-Bundle: hu.bme.mit.inf.dslreasoner.logic.model;bundle-version="1.0.0",
14 org.eclipse.xtext.xbase.lib, 18 org.eclipse.xtext.xbase.lib,
15 org.eclipse.xtend.lib, 19 org.eclipse.xtend.lib,
16 org.eclipse.xtend.lib.macro, 20 org.eclipse.xtend.lib.macro,
17 org.eclipse.viatra.query.runtime;bundle-version="1.5.0", 21 org.eclipse.viatra.query.runtime;bundle-version="2.0.0",
18 org.eclipse.viatra.query.runtime.base.itc;bundle-version="1.5.0", 22 org.eclipse.viatra.query.runtime.base.itc;bundle-version="2.0.0",
19 org.eclipse.viatra.query.patternlanguage.emf;bundle-version="1.5.0", 23 org.eclipse.viatra.query.patternlanguage.emf;bundle-version="2.0.0",
20 com.google.inject;bundle-version="3.0.0", 24 com.google.inject;bundle-version="3.0.0",
21 org.eclipse.xtext;bundle-version="2.10.0", 25 org.eclipse.xtext;bundle-version="2.10.0",
22 org.eclipse.viatra.transformation.runtime.emf;bundle-version="1.5.0", 26 org.eclipse.viatra.transformation.runtime.emf;bundle-version="2.0.0",
23 org.eclipse.xtext.xbase;bundle-version="2.10.0" 27 org.eclipse.xtext.xbase;bundle-version="2.10.0",
28 com.microsoft.z3;bundle-version="4.8.5",
29 hu.bme.mit.inf.dslreasoner.ilp.cbc;bundle-version="1.0.0",
30 org.eclipse.viatra.query.runtime.rete;bundle-version="2.0.0"
24Bundle-RequiredExecutionEnvironment: JavaSE-1.8 31Bundle-RequiredExecutionEnvironment: JavaSE-1.8
25Import-Package: org.apache.log4j 32Import-Package: org.apache.log4j
26Automatic-Module-Name: hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatraquery 33Automatic-Module-Name: hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatraquery
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/build.properties b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/build.properties
index 585df5ce..9ffc994a 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/build.properties
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/build.properties
@@ -4,6 +4,5 @@ bin.includes = META-INF/,\
4source.. = src/,\ 4source.. = src/,\
5 patterns/,\ 5 patterns/,\
6 vql-gen/,\ 6 vql-gen/,\
7 xtend-gen/,\ 7 xtend-gen/
8 src-gen/
9output.. = bin/ 8output.. = bin/
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/plugin.xml b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/plugin.xml
index 05e00983..6e4d96ca 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/plugin.xml
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/plugin.xml
@@ -1,14 +1,14 @@
1<?xml version="1.0" encoding="UTF-8"?><plugin> 1<?xml version="1.0" encoding="UTF-8"?><plugin>
2 <extension id="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.TypeAnalysis" point="org.eclipse.viatra.query.runtime.queryspecification"> 2 <extension id="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.TypeAnalysis" point="org.eclipse.viatra.query.runtime.queryspecification">
3 <group group="org.eclipse.viatra.query.runtime.extensibility.SingletonExtensionFactory:hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.TypeAnalysis" id="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.TypeAnalysis"> 3 <group group="org.eclipse.viatra.query.runtime.extensibility.SingletonExtensionFactory:hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.TypeAnalysis" id="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.TypeAnalysis">
4 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.hasDefinedSupertype"/> 4 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.hasDefinedSupertype"/>
5 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.dontHaveDefinedSupertype"/> 5 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.dontHaveDefinedSupertype"/>
6 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.newElementTypeConstructor"/> 6 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.newElementTypeConstructor"/>
7 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.newElementTypeRefinementTarget"/> 7 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.newElementTypeRefinementTarget"/>
8 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.incompatibleSuperType"/> 8 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.incompatibleSuperType"/>
9 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.incompatibleTopType"/> 9 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.incompatibleTopType"/>
10 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.newElementTypeRefinementNegativeConstraint"/> 10 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.newElementTypeRefinementNegativeConstraint"/>
11 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.newElementMayTypeNegativeConstraint"/> 11 <query-specification fqn="hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.queries.newElementMayTypeNegativeConstraint"/>
12 </group> 12 </group>
13 </extension> 13 </extension>
14</plugin> 14</plugin>
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/Modality.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/Modality.java
index d2132cea..f3a6ec32 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/Modality.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/Modality.java
@@ -2,21 +2,46 @@ package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra;
2 2
3public enum Modality { 3public enum Modality {
4 MUST, MAY, CURRENT; 4 MUST, MAY, CURRENT;
5
5 public boolean isMust() { 6 public boolean isMust() {
6 return this == MUST; 7 return this == MUST;
7 } 8 }
9
8 public boolean isMay() { 10 public boolean isMay() {
9 return this == MAY; 11 return this == MAY;
10 } 12 }
13
11 public boolean isCurrent() { 14 public boolean isCurrent() {
12 return this == CURRENT; 15 return this == CURRENT;
13 } 16 }
17
14 public boolean isMustOrCurrent() { 18 public boolean isMustOrCurrent() {
15 return isMust() || isCurrent(); 19 return isMust() || isCurrent();
16 } 20 }
21
17 public Modality getDual() { 22 public Modality getDual() {
18 if(this.isCurrent()) return CURRENT; 23 switch (this) {
19 else if(this.isMust())return MAY; 24 case CURRENT:
20 else return MUST; 25 return CURRENT;
26 case MUST:
27 return MAY;
28 case MAY:
29 return MUST;
30 default:
31 throw new UnsupportedOperationException("Unknown Modality: " + this);
32 }
33 }
34
35 public Modality toBase() {
36 if (this.isCurrent()) {
37 return MUST;
38 } else {
39 return this;
40 }
41 }
42
43 @Override
44 public String toString() {
45 return super.toString().toLowerCase();
21 } 46 }
22} 47}
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
deleted file mode 100644
index 8a26470a..00000000
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/ModelGenerationMethodProvider.xtend
+++ /dev/null
@@ -1,97 +0,0 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra
2
3import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel
4import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
5import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.TransfomedViatraQuery
6import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.PatternProvider
7import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules.GoalConstraintProvider
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules.RefinementRuleProvider
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
10import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace
11import java.util.Collection
12import java.util.List
13import java.util.Set
14import org.eclipse.viatra.query.runtime.api.IPatternMatch
15import org.eclipse.viatra.query.runtime.api.IQuerySpecification
16import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
17import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
18import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule
19import org.eclipse.xtend.lib.annotations.Data
20
21class ModelGenerationStatistics {
22 public var long transformationExecutionTime = 0
23 public var long metricCalculationTime = 0
24
25 synchronized def addExecutionTime(long amount) {
26 transformationExecutionTime+=amount
27 }
28
29 synchronized def addMetricCalculationTime(long amount) {
30 metricCalculationTime+=amount
31 }
32
33 public var long PreliminaryTypeAnalisisTime = 0
34}
35@Data class ModelGenerationMethod {
36 ModelGenerationStatistics statistics
37
38 Collection<? extends BatchTransformationRule<?,?>> objectRefinementRules
39 Collection<? extends BatchTransformationRule<?,?>> relationRefinementRules
40
41 List<MultiplicityGoalConstraintCalculator> unfinishedMultiplicities
42 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWF
43
44 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidWF
45
46 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> allPatterns
47}
48enum TypeInferenceMethod {
49 Generic, PreliminaryAnalysis
50}
51
52class ModelGenerationMethodProvider {
53 private val PatternProvider patternProvider = new PatternProvider
54 private val RefinementRuleProvider refinementRuleProvider = new RefinementRuleProvider
55 private val GoalConstraintProvider goalConstraintProvider = new GoalConstraintProvider
56
57 public def ModelGenerationMethod createModelGenerationMethod(
58 LogicProblem logicProblem,
59 PartialInterpretation emptySolution,
60 ReasonerWorkspace workspace,
61 boolean nameNewElements,
62 TypeInferenceMethod typeInferenceMethod,
63 ScopePropagator scopePropagator,
64 DocumentationLevel debugLevel
65 ) {
66 val statistics = new ModelGenerationStatistics
67 val writeFiles = (debugLevel === DocumentationLevel.NORMAL || debugLevel === DocumentationLevel.FULL)
68
69 val Set<PQuery> existingQueries = logicProblem
70 .relations
71 .map[annotations]
72 .flatten
73 .filter(TransfomedViatraQuery)
74 .map[it.patternPQuery as PQuery]
75 .toSet
76
77 val queries = patternProvider.generateQueries(logicProblem,emptySolution,statistics,existingQueries,workspace,typeInferenceMethod,writeFiles)
78 val //LinkedHashMap<Pair<Relation, ? extends Type>, BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>>>
79 objectRefinementRules = refinementRuleProvider.createObjectRefinementRules(queries,scopePropagator,nameNewElements,statistics)
80 val relationRefinementRules = refinementRuleProvider.createRelationRefinementRules(queries,statistics)
81
82 val unfinishedMultiplicities = goalConstraintProvider.getUnfinishedMultiplicityQueries(queries)
83 val unfinishedWF = queries.getUnfinishedWFQueries.values
84
85 val invalidWF = queries.getInvalidWFQueries.values
86
87 return new ModelGenerationMethod(
88 statistics,
89 objectRefinementRules.values,
90 relationRefinementRules.values,
91 unfinishedMultiplicities,
92 unfinishedWF,
93 invalidWF,
94 queries.allQueries
95 )
96 }
97}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/ModelGenerationStatistics.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/ModelGenerationStatistics.xtend
new file mode 100644
index 00000000..ab4fa039
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/ModelGenerationStatistics.xtend
@@ -0,0 +1,52 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra
2
3class ModelGenerationStatistics {
4 public var long transformationExecutionTime = 0
5 public var long metricCalculationTime = 0
6
7
8 synchronized def addMetricCalculationTime(long amount) {
9 metricCalculationTime+=amount
10 }
11 synchronized def addExecutionTime(long amount) {
12 transformationExecutionTime += amount
13 }
14
15 public var long scopePropagationTime = 0
16
17 synchronized def addScopePropagationTime(long amount) {
18 scopePropagationTime += amount
19 }
20
21 public var long mustRelationPropagationTime = 0
22
23 synchronized def addMustRelationPropagationTime(long amount) {
24 mustRelationPropagationTime += amount
25 }
26
27 public var long preliminaryTypeAnalisisTime = 0
28
29 public var int decisionsTried = 0
30
31 synchronized def incrementDecisionCount() {
32 decisionsTried++
33 }
34
35 public var int transformationInvocations
36
37 synchronized def incrementTransformationCount() {
38 transformationInvocations++
39 }
40
41 public var int scopePropagatorInvocations
42
43 synchronized def incrementScopePropagationCount() {
44 scopePropagatorInvocations++
45 }
46
47 public var int scopePropagatorSolverInvocations
48
49 synchronized def incrementScopePropagationSolverCount() {
50 scopePropagatorSolverInvocations++
51 }
52}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/MultiplicityGoalConstraintCalculator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/MultiplicityGoalConstraintCalculator.xtend
deleted file mode 100644
index e05160d0..00000000
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/MultiplicityGoalConstraintCalculator.xtend
+++ /dev/null
@@ -1,46 +0,0 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra
2
3import org.eclipse.emf.common.notify.Notifier
4import org.eclipse.viatra.query.runtime.api.IQuerySpecification
5import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
6import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
7import org.eclipse.viatra.query.runtime.emf.EMFScope
8
9class MultiplicityGoalConstraintCalculator {
10 val String targetRelationName;
11 val IQuerySpecification<?> querySpecification;
12 var ViatraQueryMatcher<?> matcher;
13
14 public new(String targetRelationName, IQuerySpecification<?> querySpecification) {
15 this.targetRelationName = targetRelationName
16 this.querySpecification = querySpecification
17 this.matcher = null
18 }
19
20 public new(MultiplicityGoalConstraintCalculator other) {
21 this.targetRelationName = other.targetRelationName
22 this.querySpecification = other.querySpecification
23 this.matcher = null
24 }
25
26 def public getName() {
27 targetRelationName
28 }
29
30 def public init(Notifier notifier) {
31 val engine = ViatraQueryEngine.on(new EMFScope(notifier))
32 matcher = querySpecification.getMatcher(engine)
33 }
34
35 def public calculateValue() {
36 var res = 0
37 val allMatches = this.matcher.allMatches
38 for(match : allMatches) {
39 //println(targetRelationName+ " missing multiplicity: "+match.get(3))
40 val missingMultiplicity = match.get(4) as Integer
41 res += missingMultiplicity
42 }
43 //println(targetRelationName+ " all missing multiplicities: "+res)
44 return res
45 }
46} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/PropagationModality.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/PropagationModality.java
new file mode 100644
index 00000000..2288ad7e
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/PropagationModality.java
@@ -0,0 +1,8 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra;
2
3public enum PropagationModality {
4 /**The value was originally ? and set to 1 */
5 UP,
6 /**The value was originally ? and set to 0 */
7 DOWN
8}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/TypeInferenceMethod.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/TypeInferenceMethod.xtend
new file mode 100644
index 00000000..9296a0be
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/TypeInferenceMethod.xtend
@@ -0,0 +1,44 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra
2
3import com.google.common.collect.ImmutableMap
4import com.google.common.collect.ImmutableSet
5import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel
6import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
7import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.TransfomedViatraQuery
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.CachingSimplePolyhedronScopePropagatorStrategy
9import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.CbcPolyhedronSolver
10import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeConstraintHint
11import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.MultiplicityGoalConstraintCalculator
12import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedronScopePropagator
13import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.RelationConstraintCalculator
14import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagator
15import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy
16import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.TypeHierarchyScopePropagator
17import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.Z3PolyhedronSolver
18import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns
19import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.ModalPatternQueries
20import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.PatternProvider
21import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.UnitPropagationPatternGenerator
22import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules.GoalConstraintProvider
23import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules.RefinementRuleProvider
24import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
25import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace
26import java.util.Collection
27import java.util.List
28import java.util.Map
29import java.util.Set
30import org.eclipse.viatra.query.runtime.api.GenericQueryGroup
31import org.eclipse.viatra.query.runtime.api.IPatternMatch
32import org.eclipse.viatra.query.runtime.api.IQuerySpecification
33import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
34import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
35import org.eclipse.viatra.query.runtime.emf.EMFScope
36import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint
37import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
38import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule
39import org.eclipse.xtend.lib.annotations.Data
40
41enum TypeInferenceMethod {
42 Generic,
43 PreliminaryAnalysis
44} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/AbstractPolyhedronSaturationOperator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/AbstractPolyhedronSaturationOperator.xtend
new file mode 100644
index 00000000..94f97e94
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/AbstractPolyhedronSaturationOperator.xtend
@@ -0,0 +1,53 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import com.google.common.collect.ImmutableList
4import org.eclipse.xtend.lib.annotations.Accessors
5
6abstract class AbstractPolyhedronSaturationOperator implements PolyhedronSaturationOperator {
7 @Accessors val Polyhedron polyhedron
8
9 new(Polyhedron polyhedron) {
10 if (polyhedron.dimensions.empty) {
11 throw new IllegalArgumentException("Polyhedron must have at least one dimension.")
12 }
13 this.polyhedron = polyhedron
14 }
15
16 override saturate() {
17 if (polyhedron.expressionsToSaturate.empty) {
18 return PolyhedronSaturationResult.SATURATED
19 }
20 for (constraint : polyhedron.constraints) {
21 if (constraint.zero) {
22 if (constraint.lowerBound !== null && constraint.lowerBound > 0) {
23 return PolyhedronSaturationResult.EMPTY
24 }
25 if (constraint.upperBound !== null && constraint.upperBound < 0) {
26 return PolyhedronSaturationResult.EMPTY
27 }
28 } else {
29 if (constraint.lowerBound !== null && constraint.upperBound !== null &&
30 constraint.upperBound < constraint.lowerBound) {
31 return PolyhedronSaturationResult.EMPTY
32 }
33 }
34 }
35 doSaturate()
36 }
37
38 protected def PolyhedronSaturationResult doSaturate()
39
40 protected def getNonTrivialConstraints() {
41 ImmutableList.copyOf(polyhedron.constraints.filter [ constraint |
42 (constraint.lowerBound !== null || constraint.upperBound !== null) && !constraint.zero
43 ])
44 }
45
46 private static def isZero(LinearConstraint constraint) {
47 constraint.coefficients.values.forall[it == 0]
48 }
49
50 override close() throws Exception {
51 // Nothing to close by default.
52 }
53}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/CbcPolyhedronSolver.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/CbcPolyhedronSolver.xtend
new file mode 100644
index 00000000..708f93dc
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/CbcPolyhedronSolver.xtend
@@ -0,0 +1,241 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import com.google.common.collect.ImmutableList
4import com.google.common.collect.ImmutableMap
5import hu.bme.mit.inf.dslreasoner.ilp.cbc.CbcResult
6import hu.bme.mit.inf.dslreasoner.ilp.cbc.CbcSolver
7import java.util.HashSet
8import java.util.List
9import java.util.Map
10import java.util.Set
11import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
12
13@FinalFieldsConstructor
14class CbcPolyhedronSolver implements PolyhedronSolver {
15 val boolean lpRelaxation
16 val double timeoutSeconds
17 val boolean silent
18
19 new() {
20 this(false, -1, true)
21 }
22
23 override createSaturationOperator(Polyhedron polyhedron) {
24 new CbcSaturationOperator(polyhedron, lpRelaxation, timeoutSeconds, silent)
25 }
26}
27
28class CbcSaturationOperator extends AbstractPolyhedronSaturationOperator {
29 static val EPSILON = 1e-6
30
31 val boolean lpRelaxation
32 val double timeoutSeconds
33 val boolean silent
34 val double[] columnLowerBounds
35 val double[] columnUpperBounds
36 val double[] objective
37 val Map<Dimension, Integer> dimensionsToIndicesMap
38
39 new(Polyhedron polyhedron, boolean lpRelaxation, double timeoutSeconds, boolean silent) {
40 super(polyhedron)
41 this.lpRelaxation = lpRelaxation
42 this.timeoutSeconds = timeoutSeconds
43 this.silent = silent
44 val numDimensions = polyhedron.dimensions.size
45 columnLowerBounds = newDoubleArrayOfSize(numDimensions)
46 columnUpperBounds = newDoubleArrayOfSize(numDimensions)
47 objective = newDoubleArrayOfSize(numDimensions)
48 dimensionsToIndicesMap = ImmutableMap.copyOf(polyhedron.dimensions.indexed.toMap([value], [key]))
49 }
50
51 override doSaturate() {
52 val numDimensions = polyhedron.dimensions.size
53 for (var int j = 0; j < numDimensions; j++) {
54 val dimension = polyhedron.dimensions.get(j)
55 columnLowerBounds.set(j, dimension.lowerBound.toDouble(Double.NEGATIVE_INFINITY))
56 columnUpperBounds.set(j, dimension.upperBound.toDouble(Double.POSITIVE_INFINITY))
57 }
58 val constraints = nonTrivialConstraints
59 val numConstraints = constraints.size
60 val rowStarts = newIntArrayOfSize(numConstraints + 1)
61 val rowLowerBounds = newDoubleArrayOfSize(numConstraints)
62 val rowUpperBounds = newDoubleArrayOfSize(numConstraints)
63 val numEntries = constraints.map[coefficients.size].reduce[a, b|a + b] ?: 0
64 rowStarts.set(numConstraints, numEntries)
65 val columnIndices = newIntArrayOfSize(numEntries)
66 val entries = newDoubleArrayOfSize(numEntries)
67 val unconstrainedDimensions = new HashSet
68 for (dimension : polyhedron.dimensions) {
69 if (dimension.lowerBound === null && dimension.upperBound === null) {
70 unconstrainedDimensions += dimension
71 }
72 }
73 var int index = 0
74 for (var int i = 0; i < numConstraints; i++) {
75 rowStarts.set(i, index)
76 val constraint = constraints.get(i)
77 rowLowerBounds.set(i, constraint.lowerBound.toDouble(Double.NEGATIVE_INFINITY))
78 rowUpperBounds.set(i, constraint.upperBound.toDouble(Double.POSITIVE_INFINITY))
79 if (!dimensionsToIndicesMap.keySet.containsAll(constraint.coefficients.keySet)) {
80 throw new IllegalArgumentException("Constrains has unknown dimensions")
81 }
82 for (var int j = 0; j < numDimensions; j++) {
83 val dimension = polyhedron.dimensions.get(j)
84 val coefficient = constraint.coefficients.get(dimension)
85 if (coefficient !== null && coefficient != 0) {
86 unconstrainedDimensions -= dimension
87 columnIndices.set(index, j)
88 entries.set(index, coefficient)
89 index++
90 }
91 }
92 }
93 if (index != numEntries) {
94 throw new AssertionError("Last entry does not equal the number of entries in the constraint matrix")
95 }
96 for (expressionToSaturate : polyhedron.expressionsToSaturate) {
97 val result = saturate(expressionToSaturate, rowStarts, columnIndices, entries, rowLowerBounds,
98 rowUpperBounds, unconstrainedDimensions, constraints)
99 if (result != PolyhedronSaturationResult.SATURATED) {
100 return result
101 }
102 }
103 PolyhedronSaturationResult.SATURATED
104 }
105
106 protected def saturate(LinearBoundedExpression expressionToSaturate, int[] rowStarts, int[] columnIndices,
107 double[] entries, double[] rowLowerBounds, double[] rowUpperBounds, Set<Dimension> unconstrainedDimensions,
108 ImmutableList<LinearConstraint> constraints) {
109 val numDimensions = objective.size
110 for (var int j = 0; j < numDimensions; j++) {
111 objective.set(j, 0)
112 }
113 switch (expressionToSaturate) {
114 Dimension: {
115 // CBC will return nonsensical results or call free() with invalid arguments if
116 // it is passed a fully unconstrained (-Inf lower and +Int upper bound, no inequalities) variable
117 // in the objective function.
118 if (unconstrainedDimensions.contains(expressionToSaturate)) {
119 return PolyhedronSaturationResult.SATURATED
120 }
121 val j = getIndex(expressionToSaturate)
122 objective.set(j, 1)
123 }
124 LinearConstraint: {
125 for (pair : expressionToSaturate.coefficients.entrySet) {
126 val dimension = pair.key
127 // We also have to check for unconstrained dimensions here to avoid crashing.
128 if (unconstrainedDimensions.contains(dimension)) {
129 expressionToSaturate.lowerBound = null
130 expressionToSaturate.upperBound = null
131 return PolyhedronSaturationResult.SATURATED
132 }
133 val j = getIndex(dimension)
134 objective.set(j, pair.value)
135 }
136 }
137 default:
138 throw new IllegalArgumentException("Unknown expression: " + expressionToSaturate)
139 }
140 val minimizationResult = CbcSolver.solve(columnLowerBounds, columnUpperBounds, rowStarts, columnIndices,
141 entries, rowLowerBounds, rowUpperBounds, objective, lpRelaxation, timeoutSeconds, silent)
142 switch (minimizationResult) {
143 CbcResult.SolutionBounded: {
144 val doubleValue = minimizationResult.value
145 val roundedValue = Math.ceil(doubleValue - EPSILON)
146 val intValue = roundedValue as int
147 val oldBound = expressionToSaturate.lowerBound
148 if (oldBound === null || intValue >= oldBound) {
149 expressionToSaturate.lowerBound = intValue
150 setBound(expressionToSaturate, constraints, roundedValue, columnLowerBounds, rowLowerBounds)
151 } else {
152 throw new IllegalStateException("Unexpected decrease of lower bound by " + (oldBound - doubleValue))
153 }
154 }
155 case CbcResult.SOLUTION_UNBOUNDED: {
156 if (expressionToSaturate.lowerBound !== null) {
157 throw new IllegalStateException("Finite lower bound became infinite")
158 }
159 setBound(expressionToSaturate, constraints, Double.NEGATIVE_INFINITY, columnLowerBounds, rowLowerBounds)
160 }
161 case CbcResult.UNSAT:
162 return PolyhedronSaturationResult.EMPTY
163 case CbcResult.ABANDONED,
164 case CbcResult.TIMEOUT:
165 return PolyhedronSaturationResult.UNKNOWN
166 default:
167 throw new RuntimeException("Unknown CbcResult: " + minimizationResult)
168 }
169 for (var int j = 0; j < numDimensions; j++) {
170 val objectiveCoefficient = objective.get(j)
171 objective.set(j, -objectiveCoefficient)
172 }
173 val maximizationResult = CbcSolver.solve(columnLowerBounds, columnUpperBounds, rowStarts, columnIndices,
174 entries, rowLowerBounds, rowUpperBounds, objective, lpRelaxation, timeoutSeconds, silent)
175 switch (maximizationResult) {
176 CbcResult.SolutionBounded: {
177 val doubleValue = -maximizationResult.value
178 val roundedValue = Math.floor(doubleValue + EPSILON)
179 val intValue = roundedValue as int
180 val oldBound = expressionToSaturate.upperBound
181 if (oldBound === null || intValue <= oldBound) {
182 expressionToSaturate.upperBound = intValue
183 setBound(expressionToSaturate, constraints, roundedValue, columnUpperBounds, rowUpperBounds)
184 } else {
185 throw new IllegalStateException("Unexpected increase of upper bound by " + (doubleValue - oldBound))
186 }
187 }
188 case CbcResult.SOLUTION_UNBOUNDED: {
189 if (expressionToSaturate.lowerBound !== null) {
190 throw new IllegalStateException("Finite upper bound became infinite")
191 }
192 expressionToSaturate.upperBound = null
193 setBound(expressionToSaturate, constraints, Double.POSITIVE_INFINITY, columnUpperBounds, rowUpperBounds)
194 }
195 case CbcResult.UNSAT:
196 if (lpRelaxation) {
197 return PolyhedronSaturationResult.EMPTY
198 } else {
199 throw new RuntimeException("Minimization was SAT, but maximization is UNSAT")
200 }
201 case CbcResult.ABANDONED,
202 case CbcResult.TIMEOUT:
203 return PolyhedronSaturationResult.UNKNOWN
204 default:
205 throw new RuntimeException("Unknown CbcResult: " + maximizationResult)
206 }
207 return PolyhedronSaturationResult.SATURATED
208 }
209
210 private def toDouble(Integer nullableInt, double defaultValue) {
211 if (nullableInt === null) {
212 defaultValue
213 } else {
214 nullableInt.doubleValue
215 }
216 }
217
218 private def int getIndex(Dimension dimension) {
219 val index = dimensionsToIndicesMap.get(dimension)
220 if (index === null) {
221 throw new IllegalArgumentException("Unknown dimension: " + dimension)
222 }
223 index
224 }
225
226 private def void setBound(LinearBoundedExpression expression, List<LinearConstraint> constraints, double bound,
227 double[] columnBounds, double[] rowBounds) {
228 switch (expression) {
229 Dimension: {
230 val j = getIndex(expression)
231 columnBounds.set(j, bound)
232 }
233 LinearConstraint: {
234 val i = constraints.indexOf(expression)
235 if (i >= 0) {
236 rowBounds.set(i, bound)
237 }
238 }
239 }
240 }
241}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ExtendedLinearExpressionBuilderFactory.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ExtendedLinearExpressionBuilderFactory.xtend
new file mode 100644
index 00000000..e97fa5d7
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ExtendedLinearExpressionBuilderFactory.xtend
@@ -0,0 +1,140 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import com.google.common.collect.ImmutableList
4import com.google.common.collect.ImmutableMap
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
6import java.util.ArrayList
7import java.util.HashMap
8import java.util.HashSet
9import java.util.List
10import java.util.Map
11import java.util.Set
12import org.eclipse.viatra.query.runtime.api.IPatternMatch
13import org.eclipse.xtend.lib.annotations.Accessors
14import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
15
16interface BoundSaturationListener {
17 def void boundsSaturated(Integer lower, Integer upper)
18}
19
20interface ExtendedLinearExpressionBuilderFactory {
21 def ExtendedLinearExpressionBuilder createBuilder()
22
23 def Dimension getDimension(IPatternMatch patternMatch)
24}
25
26interface ExtendedLinearExpressionBuilder extends LinearTypeExpressionBuilder {
27 override ExtendedLinearExpressionBuilder add(int scale, Type type)
28
29 def ExtendedLinearExpressionBuilder add(int scale, IPatternMatch patternMatch)
30
31 def ExtendedLinearExpressionBuilder add(int scale, Dimension dimension)
32
33 def LinearBoundedExpression build(BoundSaturationListener listener)
34}
35
36class ExtendedPolyhedronBuilder implements ExtendedLinearExpressionBuilderFactory {
37 val Map<Type, LinearBoundedExpression> typeBounds
38 val Map<Map<Dimension, Integer>, LinearBoundedExpression> expressionsCache
39
40 val ImmutableList.Builder<Dimension> dimensions = ImmutableList.builder
41 val Set<LinearConstraint> constraints = new HashSet
42 val Set<LinearBoundedExpression> expressionsToSaturate = new HashSet
43 val Map<IPatternMatch, Dimension> patternMatchCounts = new HashMap
44 @Accessors(PUBLIC_GETTER) val List<Pair<LinearBoundedExpression, BoundSaturationListener>> saturationListeners = new ArrayList
45
46 new(Polyhedron polyhedron, Map<Type, LinearBoundedExpression> typeBounds,
47 Map<Map<Dimension, Integer>, LinearBoundedExpression> initialExpressionsCache) {
48 this.typeBounds = typeBounds
49 this.expressionsCache = new HashMap(initialExpressionsCache)
50 dimensions.addAll(polyhedron.dimensions)
51 constraints.addAll(polyhedron.constraints)
52 expressionsToSaturate.addAll(polyhedron.expressionsToSaturate)
53 }
54
55 override createBuilder() {
56 new ExtendedLinearExpressionBuilderImpl(this)
57 }
58
59 override getDimension(IPatternMatch patternMatch) {
60 patternMatchCounts.computeIfAbsent(patternMatch) [ key |
61 val dimension = new Dimension(key.toString, 0, null)
62 dimensions.add(dimension)
63 dimension
64 ]
65 }
66
67 def buildPolyhedron() {
68 new Polyhedron(
69 dimensions.build,
70 ImmutableList.copyOf(constraints),
71 ImmutableList.copyOf(expressionsToSaturate)
72 )
73 }
74
75 @FinalFieldsConstructor
76 private static class ExtendedLinearExpressionBuilderImpl implements ExtendedLinearExpressionBuilder {
77 val ExtendedPolyhedronBuilder polyhedronBuilder
78
79 val Map<Dimension, Integer> coefficients = new HashMap
80
81 override add(int scale, Type type) {
82 val expression = polyhedronBuilder.typeBounds.get(type)
83 if (expression === null) {
84 throw new IllegalArgumentException("Unknown Type: " + type)
85 }
86 add(scale, expression)
87 }
88
89 override add(int scale, IPatternMatch patternMatch) {
90 val dimension = polyhedronBuilder.getDimension(patternMatch)
91 add(scale, dimension)
92 }
93
94 private def add(int scale, LinearBoundedExpression expression) {
95 switch (expression) {
96 Dimension: add(scale, expression)
97 LinearConstraint: add(scale, expression.coefficients)
98 default: throw new IllegalArgumentException("Unknown LinearBoundedExpression: " + expression)
99 }
100 }
101
102 private def add(int scale, Map<Dimension, Integer> coefficients) {
103 for (pair : coefficients.entrySet) {
104 add(scale * pair.value, pair.key)
105 }
106 this
107 }
108
109 override add(int scale, Dimension dimension) {
110 coefficients.merge(dimension, scale)[a, b|a + b]
111 this
112 }
113
114 override build() {
115 val filteredCoefficients = ImmutableMap.copyOf(coefficients.filter [ x, coefficient |
116 coefficient != 0
117 ])
118 polyhedronBuilder.expressionsCache.computeIfAbsent(filteredCoefficients) [ map |
119 if (map.size == 1) {
120 val pair = map.entrySet.head
121 if (pair.value == 1) {
122 return pair.key
123 }
124 }
125 val constraint = new LinearConstraint(map)
126 polyhedronBuilder.constraints.add(constraint)
127 constraint
128 ]
129 }
130
131 override build(BoundSaturationListener listener) {
132 val expression = build()
133 if (listener !== null) {
134 polyhedronBuilder.expressionsToSaturate.add(expression)
135 polyhedronBuilder.saturationListeners.add(expression -> listener)
136 }
137 expression
138 }
139 }
140}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ExtendedPolyhedronScopePropagatorStrategy.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ExtendedPolyhedronScopePropagatorStrategy.xtend
new file mode 100644
index 00000000..32923396
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ExtendedPolyhedronScopePropagatorStrategy.xtend
@@ -0,0 +1,63 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
4import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics
5import java.util.Collection
6import java.util.Map
7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
8
9interface PolyhedronExtensionOperator {
10 def void extendPolyhedron(ExtendedLinearExpressionBuilderFactory factory)
11}
12
13class ExtendedPolyhedronScopePropagatorStrategy extends PolyhedronScopePropagatorStrategy {
14 val PolyhedronSolver solver
15 val Collection<PolyhedronExtensionOperator> extensionOperators
16
17 var Map<Type, LinearBoundedExpression> typeBounds
18 var Map<Map<Dimension, Integer>, LinearBoundedExpression> initialExpressionsCache
19
20 new(PolyhedronSolver solver, Collection<PolyhedronExtensionOperator> extensionOperators,
21 ModelGenerationStatistics statistics) {
22 super(statistics)
23 this.solver = solver
24 this.extensionOperators = extensionOperators
25 }
26
27 override setPolyhedron(Polyhedron polyhedron, Map<Type, LinearBoundedExpression> typeBounds,
28 Map<Map<Dimension, Integer>, LinearBoundedExpression> initialExpressionsCache) {
29 super.setPolyhedron(polyhedron, typeBounds, initialExpressionsCache)
30 this.typeBounds = typeBounds
31 this.initialExpressionsCache = initialExpressionsCache
32 }
33
34 override isRelevantRelation(Relation relation) {
35 true
36 }
37
38 override protected doSaturate() {
39 val builder = new ExtendedPolyhedronBuilder(polyhedron, typeBounds, initialExpressionsCache)
40 for (extensionOperator : extensionOperators) {
41 extensionOperator.extendPolyhedron(builder)
42 }
43 val extendedPolyhedron = builder.buildPolyhedron()
44 val saturationOperator = solver.createSaturationOperator(extendedPolyhedron)
45 val result = try {
46 saturationOperator.saturate()
47 } finally {
48 saturationOperator.close()
49 }
50 if (result == PolyhedronSaturationResult.EMPTY) {
51 // The partial model cannot be refined any more, we can't provide objective bounds.
52 for (pair : builder.saturationListeners) {
53 pair.value.boundsSaturated(null, null)
54 }
55 return false
56 }
57 for (pair : builder.saturationListeners) {
58 val expression = pair.key
59 pair.value.boundsSaturated(expression.lowerBound, expression.upperBound)
60 }
61 true
62 }
63}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/LinearTypeConstraintHint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/LinearTypeConstraintHint.xtend
new file mode 100644
index 00000000..31f98e36
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/LinearTypeConstraintHint.xtend
@@ -0,0 +1,32 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
4import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.PatternGenerator
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
6import java.util.Map
7import org.eclipse.viatra.query.runtime.api.IPatternMatch
8import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
9import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
10
11interface LinearTypeExpressionBuilderFactory {
12 def ViatraQueryMatcher<? extends IPatternMatch> createMatcher(String queryName)
13
14 def LinearTypeExpressionBuilder createBuilder()
15}
16
17interface LinearTypeExpressionBuilder {
18 def LinearTypeExpressionBuilder add(int scale, Type type)
19
20 def LinearBoundedExpression build()
21}
22
23@FunctionalInterface
24interface RelationConstraintUpdater {
25 def void update(PartialInterpretation p)
26}
27
28interface LinearTypeConstraintHint {
29 def CharSequence getAdditionalPatterns(PatternGenerator patternGenerator, Map<String, PQuery> fqnToPQuery)
30
31 def RelationConstraintUpdater createConstraintUpdater(LinearTypeExpressionBuilderFactory builderFactory)
32}
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
new file mode 100644
index 00000000..273e0ac3
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/MultiplicityGoalConstraintCalculator.xtend
@@ -0,0 +1,57 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import org.eclipse.emf.common.notify.Notifier
4import org.eclipse.viatra.query.runtime.api.IQuerySpecification
5import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
6import org.eclipse.viatra.query.runtime.emf.EMFScope
7
8class MultiplicityGoalConstraintCalculator {
9 val String targetRelationName
10 val IQuerySpecification<?> querySpecification
11 var MultiplicityCalculator<?> calculator
12 val boolean containment
13 val int lowerBound
14 val int cost
15
16 new(String targetRelationName, IQuerySpecification<?> querySpecification, boolean containment, int lowerBound, int cost) {
17 if (lowerBound <= 0) {
18 throw new IllegalArgumentException("Invalid lower bound: " + lowerBound)
19 }
20 this.targetRelationName = targetRelationName
21 this.querySpecification = querySpecification
22 this.calculator = null
23 this.containment = containment
24 this.lowerBound = lowerBound
25 this.cost = cost
26 }
27
28 new(MultiplicityGoalConstraintCalculator other) {
29 this.targetRelationName = other.targetRelationName
30 this.querySpecification = other.querySpecification
31 this.calculator = null
32 this.containment = other.containment
33 this.lowerBound = other.lowerBound
34 this.cost = other.cost
35 }
36
37 def getName() {
38 targetRelationName
39 }
40
41 def isContainment() {
42 return containment
43 }
44
45 def init(Notifier notifier) {
46 val engine = ViatraQueryEngine.on(new EMFScope(notifier))
47 val matcher = querySpecification.getMatcher(engine)
48 calculator = RemainingMultiplicityCalculator.of(matcher, lowerBound)
49 }
50
51 def calculateValue() {
52 val res = calculator.multiplicity
53// if(res>0)
54// println(targetRelationName+ " all missing multiplicities: "+res + "*"+cost+"="+res*cost)
55 return res*cost
56 }
57}
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
new file mode 100644
index 00000000..ad8f94ab
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronScopePropagator.xtend
@@ -0,0 +1,522 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import com.google.common.collect.ImmutableList
4import com.google.common.collect.ImmutableMap
5import com.google.common.collect.ImmutableSet
6import com.google.common.collect.Maps
7import com.google.common.collect.Sets
8import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
9import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
10import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics
11import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.UnifinishedMultiplicityQueries
12import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
13import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
14import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation
15import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope
16import java.util.ArrayDeque
17import java.util.ArrayList
18import java.util.Collection
19import java.util.HashMap
20import java.util.HashSet
21import java.util.List
22import java.util.Map
23import java.util.Set
24import org.eclipse.viatra.query.runtime.api.IPatternMatch
25import org.eclipse.viatra.query.runtime.api.IQuerySpecification
26import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
27import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
28import org.eclipse.viatra.query.runtime.emf.EMFScope
29import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
30
31class PolyhedronScopePropagator extends TypeHierarchyScopePropagator {
32 val boolean updateHeuristic
33 val Map<Scope, LinearBoundedExpression> scopeBounds
34 val LinearBoundedExpression topLevelBounds
35 val Polyhedron polyhedron
36 val PolyhedronScopePropagatorStrategy strategy
37 val Set<Relation> relevantRelations
38 List<RelationConstraintUpdater> updaters = emptyList
39
40 new(PartialInterpretation p, ModelGenerationStatistics statistics, Set<? extends Type> possibleNewDynamicTypes,
41 Map<RelationMultiplicityConstraint, UnifinishedMultiplicityQueries> unfinishedMultiplicityQueries,
42 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hasElementInContainmentQuery,
43 Map<String, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> allPatternsByName,
44 Collection<LinearTypeConstraintHint> hints, PolyhedronScopePropagatorStrategy strategy,
45 boolean propagateRelations, boolean updateHeuristic) {
46 super(p, statistics)
47 this.updateHeuristic = updateHeuristic
48 this.strategy = strategy
49 val builder = new PolyhedronBuilder(p)
50 builder.buildPolyhedron(possibleNewDynamicTypes)
51 scopeBounds = builder.scopeBounds
52 topLevelBounds = builder.topLevelBounds
53 polyhedron = builder.polyhedron
54 strategy.setPolyhedron(polyhedron, builder.typeBounds, builder.expressionsCache)
55 propagateAllScopeConstraints()
56 if (propagateRelations) {
57 val maximumNumberOfNewNodes = topLevelBounds.upperBound
58 if (maximumNumberOfNewNodes === null) {
59 throw new IllegalStateException("Could not determine maximum number of new nodes, it may be unbounded")
60 }
61 if (maximumNumberOfNewNodes <= 0) {
62 throw new IllegalStateException("Maximum number of new nodes is not positive")
63 }
64 builder.buildMultiplicityConstraints(unfinishedMultiplicityQueries, hasElementInContainmentQuery,
65 allPatternsByName, hints, maximumNumberOfNewNodes)
66 relevantRelations = builder.relevantRelations
67 updaters = builder.updaters
68 } else {
69 relevantRelations = emptySet
70 }
71 }
72
73 override void doPropagateAllScopeConstraints() {
74 super.doPropagateAllScopeConstraints()
75 resetBounds()
76 populatePolyhedronFromScope()
77// println(polyhedron)
78 if (strategy.saturate) {
79 populateScopesFromPolyhedron()
80 } else {
81 setScopesInvalid()
82 }
83// println(polyhedron)
84 if (updateHeuristic) {
85 copyScopeBoundsToHeuristic()
86 }
87 }
88
89 override isPropagationNeededAfterAdditionToRelation(Relation r) {
90 relevantRelations.contains(r) || strategy.isRelevantRelation(r) || super.isPropagationNeededAfterAdditionToRelation(r)
91 }
92
93 override isQueryEngineFlushRequiredBeforePropagation() {
94 true
95 }
96
97 def resetBounds() {
98 for (dimension : polyhedron.dimensions) {
99 dimension.lowerBound = 0
100 dimension.upperBound = null
101 }
102 for (constraint : polyhedron.constraints) {
103 constraint.lowerBound = null
104 constraint.upperBound = null
105 }
106 }
107
108 private def populatePolyhedronFromScope() {
109 topLevelBounds.tightenLowerBound(partialInterpretation.minNewElements)
110 if (partialInterpretation.maxNewElements >= 0) {
111 topLevelBounds.tightenUpperBound(partialInterpretation.maxNewElements)
112 }
113 for (pair : scopeBounds.entrySet) {
114 val scope = pair.key
115 val bounds = pair.value
116 bounds.tightenLowerBound(scope.minNewElements)
117 if (scope.maxNewElements >= 0) {
118 bounds.tightenUpperBound(scope.maxNewElements)
119 }
120 }
121 for (updater : updaters) {
122 updater.update(partialInterpretation)
123 }
124 }
125
126 private def populateScopesFromPolyhedron() {
127 checkBounds(topLevelBounds)
128 if (partialInterpretation.minNewElements > topLevelBounds.lowerBound) {
129 throw new IllegalArgumentException('''Lower bound of «topLevelBounds» smaller than top-level scope: «partialInterpretation.minNewElements»''')
130 } else if (partialInterpretation.minNewElements != topLevelBounds.lowerBound) {
131 partialInterpretation.minNewElements = topLevelBounds.lowerBound
132 }
133 val topLevelUpperBound = topLevelBounds.upperBound ?: -1
134 if (partialInterpretation.maxNewElements >= 0 && topLevelUpperBound >= 0 &&
135 partialInterpretation.maxNewElements < topLevelUpperBound) {
136 throw new IllegalArgumentException('''Upper bound of «topLevelBounds» larger than top-level scope: «partialInterpretation.maxNewElements»''')
137 } else if (partialInterpretation.maxNewElements != topLevelUpperBound) {
138 partialInterpretation.maxNewElements = topLevelUpperBound
139 }
140 for (pair : scopeBounds.entrySet) {
141 val scope = pair.key
142 val bounds = pair.value
143 checkBounds(bounds)
144 if (scope.minNewElements > bounds.lowerBound) {
145 throw new IllegalArgumentException('''Lower bound of «bounds» smaller than «scope.targetTypeInterpretation» scope: «scope.minNewElements»''')
146 } else if (scope.minNewElements != bounds.lowerBound) {
147 scope.minNewElements = bounds.lowerBound
148 }
149 val upperBound = bounds.upperBound ?: -1
150 if (scope.maxNewElements >= 0 && upperBound >= 0 && scope.maxNewElements < upperBound) {
151 throw new IllegalArgumentException('''Upper bound of «bounds» larger than «scope.targetTypeInterpretation» scope: «scope.maxNewElements»''')
152 } else if (scope.maxNewElements != upperBound) {
153 scope.maxNewElements = upperBound
154 }
155 }
156 }
157
158 private def checkBounds(LinearBoundedExpression bounds) {
159 if (bounds.lowerBound === null) {
160 throw new IllegalArgumentException("Infinite lower bound: " + bounds)
161 } else if (bounds.lowerBound < 0) {
162 throw new IllegalArgumentException("Negative lower bound: " + bounds)
163 }
164 if (bounds.upperBound !== null && bounds.upperBound < 0) {
165 throw new IllegalArgumentException("Negative upper bound: " + bounds)
166 }
167 }
168
169 @FinalFieldsConstructor
170 private static class PolyhedronBuilder implements LinearTypeExpressionBuilderFactory {
171 static val INFINITY_SCALE = 10
172
173 val PartialInterpretation p
174
175 Map<Type, Dimension> instanceCounts
176 Map<Type, Map<Dimension, Integer>> subtypeDimensions
177 Map<Map<Dimension, Integer>, LinearBoundedExpression> expressionsCache
178 Map<Type, LinearBoundedExpression> typeBounds
179 int infinity
180 ViatraQueryEngine queryEngine
181 Map<String, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> allPatternsByName
182 ImmutableList.Builder<RelationConstraintUpdater> updatersBuilder
183
184 Map<Scope, LinearBoundedExpression> scopeBounds
185 LinearBoundedExpression topLevelBounds
186 Polyhedron polyhedron
187 Set<Relation> relevantRelations
188 List<RelationConstraintUpdater> updaters
189
190 def buildPolyhedron(Set<? extends Type> possibleNewDynamicTypes) {
191 instanceCounts = possibleNewDynamicTypes.toInvertedMap[new Dimension(name, 0, null)]
192 val types = p.problem.types
193 expressionsCache = Maps.newHashMapWithExpectedSize(types.size)
194 subtypeDimensions = types.toInvertedMap[findSubtypeDimensions.toInvertedMap[1]]
195 typeBounds = ImmutableMap.copyOf(subtypeDimensions.mapValues[toExpression])
196 scopeBounds = buildScopeBounds
197 topLevelBounds = instanceCounts.values.toInvertedMap[1].toExpression
198 val dimensions = ImmutableList.copyOf(instanceCounts.values)
199 val expressionsToSaturate = ImmutableList.copyOf(scopeBounds.values)
200 polyhedron = new Polyhedron(dimensions, new ArrayList, expressionsToSaturate)
201 addCachedConstraintsToPolyhedron()
202 }
203
204 def buildMultiplicityConstraints(
205 Map<RelationMultiplicityConstraint, UnifinishedMultiplicityQueries> constraints,
206 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hasElementInContainmentQuery,
207 Map<String, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> allPatternsByName,
208 Collection<LinearTypeConstraintHint> hints, int maximumNuberOfNewNodes) {
209 infinity = if (maximumNuberOfNewNodes <= Integer.MAX_VALUE / INFINITY_SCALE) {
210 maximumNuberOfNewNodes * INFINITY_SCALE
211 } else {
212 Integer.MAX_VALUE
213 }
214
215 queryEngine = ViatraQueryEngine.on(new EMFScope(p))
216 this.allPatternsByName = allPatternsByName
217 updatersBuilder = ImmutableList.builder
218 val containmentConstraints = constraints.entrySet.filter[key.containment].groupBy[key.targetType]
219 for (pair : containmentConstraints.entrySet) {
220 buildContainmentConstraints(pair.key, pair.value)
221 }
222 buildConstainmentRootConstraints(containmentConstraints.keySet, hasElementInContainmentQuery)
223 for (pair : constraints.entrySet) {
224 val constraint = pair.key
225 if (!constraint.containment && !constraint.container) {
226 buildNonContainmentConstraints(constraint, pair.value)
227 }
228 }
229 buildRelevantRelations(constraints.keySet)
230 for (hint : hints) {
231 val updater = hint.createConstraintUpdater(this)
232 if (updater !== null) {
233 updatersBuilder.add(updater)
234 }
235 }
236 updaters = updatersBuilder.build
237 addCachedConstraintsToPolyhedron()
238 }
239
240 private def buildRelevantRelations(Set<RelationMultiplicityConstraint> constraints) {
241 val builder = ImmutableSet.builder
242 for (constraint : constraints) {
243 builder.add(constraint.relation)
244 if (constraint.inverseRelation !== null) {
245 builder.add(constraint.inverseRelation)
246 }
247 }
248 relevantRelations = builder.build
249 }
250
251 private def addCachedConstraintsToPolyhedron() {
252 val constraints = new HashSet
253 constraints.addAll(expressionsCache.values.filter(LinearConstraint))
254 constraints.removeAll(polyhedron.constraints)
255 polyhedron.constraints.addAll(constraints)
256 }
257
258 private def buildContainmentConstraints(Type containedType,
259 List<Map.Entry<RelationMultiplicityConstraint, UnifinishedMultiplicityQueries>> constraints) {
260 val typeCoefficients = subtypeDimensions.get(containedType)
261 val orphansLowerBoundCoefficients = new HashMap(typeCoefficients)
262 val orphansUpperBoundCoefficients = new HashMap(typeCoefficients)
263 val unfinishedMultiplicitiesBuilder = ImmutableList.builder
264 val remainingContentsBuilder = ImmutableList.builder
265 for (pair : constraints) {
266 val constraint = pair.key
267 val containerCoefficients = subtypeDimensions.get(constraint.sourceType)
268 if (constraint.isUpperBoundFinite) {
269 orphansLowerBoundCoefficients.addCoefficients(-constraint.upperBound, containerCoefficients)
270 } else {
271 orphansLowerBoundCoefficients.addCoefficients(-infinity, containerCoefficients)
272 }
273 orphansUpperBoundCoefficients.addCoefficients(-constraint.lowerBound, containerCoefficients)
274 val queries = pair.value
275 if (queries.existingMultiplicityQuery !== null) {
276 val matcher = queries.existingMultiplicityQuery.getMatcher(queryEngine)
277 if (constraint.constrainsUnfinished) {
278 unfinishedMultiplicitiesBuilder.add(
279 RemainingMultiplicityCalculator.of(matcher, constraint.lowerBound))
280 }
281 remainingContentsBuilder.add(RemainingMultiplicityCalculator.of(matcher, constraint.upperBound))
282 } else if (constraint.constrainsUnfinished) {
283 throw new IllegalArgumentException("Containment constraints need multiplicity queries")
284 }
285 }
286 val orphanLowerBound = orphansLowerBoundCoefficients.toExpression
287 val orphanUpperBound = orphansUpperBoundCoefficients.toExpression
288 val updater = new ContainmentConstraintUpdater(orphanLowerBound, orphanUpperBound,
289 unfinishedMultiplicitiesBuilder.build, remainingContentsBuilder.build)
290 updatersBuilder.add(updater)
291 }
292
293 private def buildConstainmentRootConstraints(Set<Type> containedTypes,
294 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hasElementInContainmentQuery) {
295 val matcher = hasElementInContainmentQuery.getMatcher(queryEngine)
296 val rootDimensions = Sets.newHashSet(instanceCounts.values)
297 for (type : containedTypes) {
298 val containedDimensions = subtypeDimensions.get(type).keySet
299 rootDimensions.removeAll(containedDimensions)
300 }
301 for (dimension : rootDimensions) {
302 updatersBuilder.add(new ContainmentRootConstraintUpdater(dimension, matcher))
303 }
304 }
305
306 private def buildNonContainmentConstraints(RelationMultiplicityConstraint constraint,
307 UnifinishedMultiplicityQueries queries) {
308 if (!constraint.reference) {
309 return
310 }
311 if (constraint.constrainsRemainingInverse) {
312 if (queries.getExistingMultiplicityQuery === null) {
313 throw new IllegalArgumentException("Reference constraints need unfinished multiplicity queries: " +
314 constraint.relation)
315 }
316 val existingMultiplicityMatcher = queries.getExistingMultiplicityQuery.getMatcher(queryEngine)
317 val unfinishedMultiplicityCalculator = RemainingMultiplicityCalculator.of(existingMultiplicityMatcher,
318 constraint.lowerBound)
319 val existingInverseMultiplicityMatcher = queries.existingInverseMultiplicityQuery.getMatcher(
320 queryEngine)
321 val remainingInverseMultiplicityCalculator = new RemainingInverseMultiplicityCalculator(
322 existingInverseMultiplicityMatcher, constraint.upperBound)
323 val availableMultiplicityCoefficients = new HashMap
324 availableMultiplicityCoefficients.addCoefficients(constraint.inverseUpperBound,
325 subtypeDimensions.get(constraint.targetType))
326 availableMultiplicityCoefficients.addCoefficients(-constraint.lowerBound,
327 subtypeDimensions.get(constraint.targetType))
328 val availableMultiplicity = availableMultiplicityCoefficients.toExpression
329 updatersBuilder.add(
330 new UnfinishedMultiplicityConstraintUpdater(availableMultiplicity, unfinishedMultiplicityCalculator,
331 remainingInverseMultiplicityCalculator))
332 }
333 if (constraint.constrainsUnrepairable) {
334 if (queries.existingMultiplicityQuery.parameters.size < 5) {
335 throw new IllegalArgumentException("Reference constraints need repairable multiplicity queries: " +
336 constraint.relation)
337 }
338 val matcher = queries.existingMultiplicityQuery.getMatcher(queryEngine)
339 val calculator = new UnrepairableMultiplicityCalculator(matcher, constraint.lowerBound)
340 val targetTypeCardinality = typeBounds.get(constraint.targetType)
341 updatersBuilder.add(new UnrepairableMultiplicityConstraintUpdater(targetTypeCardinality, calculator))
342 }
343 }
344
345 private static def addCoefficients(Map<Dimension, Integer> accumulator, int scale, Map<Dimension, Integer> a) {
346 for (pair : a.entrySet) {
347 val dimension = pair.key
348 val currentValue = accumulator.get(pair.key) ?: 0
349 val newValue = currentValue + scale * pair.value
350 if (newValue == 0) {
351 accumulator.remove(dimension)
352 } else {
353 accumulator.put(dimension, newValue)
354 }
355 }
356 }
357
358 private def findSubtypeDimensions(Type type) {
359 val subtypes = new HashSet
360 val dimensions = new HashSet
361 val stack = new ArrayDeque
362 stack.addLast(type)
363 while (!stack.empty) {
364 val subtype = stack.removeLast
365 if (subtypes.add(subtype)) {
366 val dimension = instanceCounts.get(subtype)
367 if (dimension !== null) {
368 dimensions.add(dimension)
369 }
370 stack.addAll(subtype.subtypes)
371 }
372 }
373 dimensions
374 }
375
376 private def toExpression(Map<Dimension, Integer> coefficients) {
377 expressionsCache.computeIfAbsent(coefficients) [ c |
378 if (c.size == 1 && c.entrySet.head.value == 1) {
379 c.entrySet.head.key
380 } else {
381 new LinearConstraint(c, null, null)
382 }
383 ]
384 }
385
386 private def buildScopeBounds() {
387 val scopeBoundsBuilder = ImmutableMap.builder
388 for (scope : p.scopes) {
389 switch (targetTypeInterpretation : scope.targetTypeInterpretation) {
390 PartialPrimitiveInterpretation:
391 throw new IllegalStateException("Primitive type scopes are not yet implemented")
392 PartialComplexTypeInterpretation: {
393 val complexType = targetTypeInterpretation.interpretationOf
394 val typeBound = typeBounds.get(complexType)
395 if (typeBound === null) {
396 if (scope.minNewElements > 0) {
397 throw new IllegalArgumentException("Found scope for " + complexType.name +
398 ", but the type cannot be instantiated")
399 }
400 } else {
401 scopeBoundsBuilder.put(scope, typeBound)
402 }
403 }
404 default:
405 throw new IllegalArgumentException("Unknown PartialTypeInterpretation: " +
406 targetTypeInterpretation)
407 }
408 }
409 scopeBoundsBuilder.build
410 }
411
412 override createMatcher(String queryName) {
413 val querySpecification = allPatternsByName.get(queryName)
414 if (querySpecification === null) {
415 throw new IllegalArgumentException("Unknown pattern: " + queryName)
416 }
417 querySpecification.getMatcher(queryEngine)
418 }
419
420 override createBuilder() {
421 new PolyhedronBuilderLinearTypeExpressionBuilder(this)
422 }
423 }
424
425 @FinalFieldsConstructor
426 private static class PolyhedronBuilderLinearTypeExpressionBuilder implements LinearTypeExpressionBuilder {
427 val PolyhedronBuilder polyhedronBuilder
428 val Map<Dimension, Integer> coefficients = new HashMap
429
430 override add(int scale, Type type) {
431 val typeCoefficients = polyhedronBuilder.subtypeDimensions.get(type)
432 if (typeCoefficients === null) {
433 throw new IllegalArgumentException("Unknown type: " + type)
434 }
435 PolyhedronBuilder.addCoefficients(coefficients, scale, typeCoefficients)
436 this
437 }
438
439 override build() {
440 polyhedronBuilder.toExpression(coefficients)
441 }
442 }
443
444 @FinalFieldsConstructor
445 private static class ContainmentConstraintUpdater implements RelationConstraintUpdater {
446 val LinearBoundedExpression orphansLowerBound
447 val LinearBoundedExpression orphansUpperBound
448 val List<MultiplicityCalculator<? extends IPatternMatch>> unfinishedMultiplicities
449 val List<MultiplicityCalculator<? extends IPatternMatch>> remainingContents
450
451 override update(PartialInterpretation p) {
452 tightenLowerBound(p)
453 tightenUpperBound(p)
454 }
455
456 private def tightenLowerBound(PartialInterpretation p) {
457 var int sum = 0
458 for (calculator : remainingContents) {
459 val value = calculator.getMultiplicity(p)
460 if (value < 0) {
461 // Infinite upper bound, no need to tighten.
462 return
463 }
464 sum += value
465 }
466 orphansLowerBound.tightenUpperBound(sum)
467 }
468
469 private def tightenUpperBound(PartialInterpretation p) {
470 var int sum = 0
471 for (calculator : unfinishedMultiplicities) {
472 val value = calculator.getMultiplicity(p)
473 sum += value
474 }
475 orphansUpperBound.tightenLowerBound(sum)
476 }
477 }
478
479 @FinalFieldsConstructor
480 private static class ContainmentRootConstraintUpdater implements RelationConstraintUpdater {
481 val LinearBoundedExpression typeCardinality
482 val ViatraQueryMatcher<? extends IPatternMatch> hasElementInContainmentMatcher
483
484 override update(PartialInterpretation p) {
485 if (hasElementInContainmentMatcher.hasMatch(p)) {
486 typeCardinality.tightenUpperBound(0)
487 } else {
488 typeCardinality.tightenUpperBound(1)
489 }
490 }
491
492 private static def <T extends IPatternMatch> hasMatch(ViatraQueryMatcher<T> matcher, PartialInterpretation p) {
493 val match = matcher.newMatch(p.problem, p)
494 matcher.countMatches(match) != 0
495 }
496 }
497
498 @FinalFieldsConstructor
499 private static class UnfinishedMultiplicityConstraintUpdater implements RelationConstraintUpdater {
500 val LinearBoundedExpression availableMultiplicityExpression
501 val MultiplicityCalculator<? extends IPatternMatch> unfinishedMultiplicityCalculator
502 val MultiplicityCalculator<? extends IPatternMatch> remainingInverseMultiplcityCalculator
503
504 override update(PartialInterpretation p) {
505 val unfinishedMultiplicity = unfinishedMultiplicityCalculator.getMultiplicity(p)
506 val remainingInverseMultiplicity = remainingInverseMultiplcityCalculator.getMultiplicity(p)
507 val int requiredMultiplicity = unfinishedMultiplicity - remainingInverseMultiplicity
508 availableMultiplicityExpression.tightenLowerBound(requiredMultiplicity)
509 }
510 }
511
512 @FinalFieldsConstructor
513 private static class UnrepairableMultiplicityConstraintUpdater implements RelationConstraintUpdater {
514 val LinearBoundedExpression targetCardinalityExpression
515 val MultiplicityCalculator<? extends IPatternMatch> calculator
516
517 override update(PartialInterpretation p) {
518 val value = calculator.getMultiplicity(p)
519 targetCardinalityExpression.tightenLowerBound(value)
520 }
521 }
522}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronScopePropagatorStrategy.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronScopePropagatorStrategy.xtend
new file mode 100644
index 00000000..f93dcd18
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronScopePropagatorStrategy.xtend
@@ -0,0 +1,92 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import com.google.common.cache.Cache
4import com.google.common.cache.CacheBuilder
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
7import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics
8import java.util.Map
9import org.eclipse.xtend.lib.annotations.Accessors
10import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
11
12@FinalFieldsConstructor
13abstract class PolyhedronScopePropagatorStrategy {
14 val ModelGenerationStatistics statistics
15
16 @Accessors(PUBLIC_GETTER) var Polyhedron polyhedron
17
18 def void setPolyhedron(Polyhedron polyhedron, Map<Type, LinearBoundedExpression> typeBounds,
19 Map<Map<Dimension, Integer>, LinearBoundedExpression> initialExpressionsCache) {
20 if (this.polyhedron !== null) {
21 throw new IllegalStateException("polyhedron was already set")
22 }
23 this.polyhedron = polyhedron
24 initialize()
25 }
26
27 def boolean saturate() {
28 if (polyhedron === null) {
29 throw new IllegalStateException("polyhedron was not set")
30 }
31 doSaturate()
32 }
33
34 def boolean isRelevantRelation(Relation relation) {
35 false
36 }
37
38 protected def incrementScopePropagationSolverCount() {
39 statistics.incrementScopePropagationSolverCount()
40 }
41
42 protected def void initialize() {
43 }
44
45 protected def boolean doSaturate()
46}
47
48@FinalFieldsConstructor
49class CachingSimplePolyhedronScopePropagatorStrategy extends PolyhedronScopePropagatorStrategy {
50 static val CACHE_SIZE = 10000
51
52 val PolyhedronSolver solver
53
54 val Cache<PolyhedronSignature, PolyhedronSignature> cache = CacheBuilder.newBuilder.maximumSize(CACHE_SIZE).build
55 var PolyhedronSaturationOperator operator
56
57 new(PolyhedronSolver solver, ModelGenerationStatistics statistics) {
58 super(statistics)
59 this.solver = solver
60 }
61
62 override protected initialize() {
63 operator = solver.createSaturationOperator(polyhedron)
64 }
65
66 override protected doSaturate() {
67 val signature = polyhedron.createSignature
68 val cachedSignature = cache.getIfPresent(signature)
69 switch (cachedSignature) {
70 case null: {
71 incrementScopePropagationSolverCount()
72 val result = operator.saturate()
73 if (result == PolyhedronSaturationResult.EMPTY) {
74 cache.put(signature, PolyhedronSignature.EMPTY)
75 false
76 } else {
77 val resultSignature = polyhedron.createSignature
78 cache.put(signature, resultSignature)
79 true
80 }
81 }
82 case PolyhedronSignature.EMPTY:
83 false
84 PolyhedronSignature.Bounds: {
85 polyhedron.applySignature(signature)
86 true
87 }
88 default:
89 throw new IllegalStateException("Unknown polyhedron signature: " + signature)
90 }
91 }
92}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronSolver.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronSolver.xtend
new file mode 100644
index 00000000..21bd2d9e
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/PolyhedronSolver.xtend
@@ -0,0 +1,186 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import java.util.List
4import java.util.Map
5import org.eclipse.xtend.lib.annotations.Accessors
6import org.eclipse.xtend.lib.annotations.Data
7import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
8
9interface PolyhedronSolver {
10 def PolyhedronSaturationOperator createSaturationOperator(Polyhedron polyhedron)
11}
12
13enum PolyhedronSaturationResult {
14 SATURATED,
15 EMPTY,
16 UNKNOWN
17}
18
19interface PolyhedronSaturationOperator extends AutoCloseable {
20 def Polyhedron getPolyhedron()
21
22 def PolyhedronSaturationResult saturate()
23}
24
25@FinalFieldsConstructor
26@Accessors
27class Polyhedron {
28 /**
29 * The list of dimensions (variables) for this polyhedron.
30 *
31 * This list must not be modified after the polyhedron was created.
32 * However, lower and upper bounds of the dimensions may be changed.
33 *
34 * Names of dimensions in this list are assumed to be unique.
35 */
36 val List<Dimension> dimensions
37
38 /**
39 * The list of constraints defining this polyhedron.
40 *
41 * The list and its elements may be freely modified.
42 */
43 val List<LinearConstraint> constraints
44
45 /**
46 * The list of constraints that should be saturated (tightened)
47 * when a {@link PolyhedronSaturationOperator} is invoked.
48 *
49 * This list may be freely modified.
50 *
51 * Place all dimensions and constraints here to saturate all the bounds.
52 */
53 val List<LinearBoundedExpression> expressionsToSaturate
54
55 override toString() '''
56 Dimensions:
57 «FOR dimension : dimensions»
58 «dimension»
59 «ENDFOR»
60 Constraints:
61 «FOR constraint : constraints»
62 «constraint»
63 «ENDFOR»
64 '''
65
66 def createSignature() {
67 val size = dimensions.size + constraints.size
68 val lowerBounds = newArrayOfSize(size)
69 val upperBounds = newArrayOfSize(size)
70 var int i = 0
71 for (dimension : dimensions) {
72 lowerBounds.set(i, dimension.lowerBound)
73 upperBounds.set(i, dimension.upperBound)
74 i++
75 }
76 for (constraint : constraints) {
77 lowerBounds.set(i, constraint.lowerBound)
78 upperBounds.set(i, constraint.upperBound)
79 i++
80 }
81 new PolyhedronSignature.Bounds(lowerBounds, upperBounds)
82 }
83
84 def applySignature(PolyhedronSignature.Bounds signature) {
85 val lowerBounds = signature.lowerBounds
86 val upperBounds = signature.upperBounds
87 var int i = 0
88 for (dimension : dimensions) {
89 dimension.lowerBound = lowerBounds.get(i)
90 dimension.upperBound = upperBounds.get(i)
91 i++
92 }
93 for (constraint : constraints) {
94 constraint.lowerBound = lowerBounds.get(i)
95 constraint.upperBound = upperBounds.get(i)
96 i++
97 }
98 }
99}
100
101abstract class PolyhedronSignature {
102 public static val EMPTY = new PolyhedronSignature {
103 override toString() {
104 "PolyhedronSignature.EMPTY"
105 }
106 }
107
108 private new() {
109 }
110
111 @Data
112 static class Bounds extends PolyhedronSignature {
113 val Integer[] lowerBounds
114 val Integer[] upperBounds
115 }
116}
117
118@Accessors
119class Bounds {
120 var Integer lowerBound
121 var Integer upperBound
122
123 def void tightenLowerBound(Integer tighterBound) {
124 if (lowerBound === null || (tighterBound !== null && lowerBound < tighterBound)) {
125 lowerBound = tighterBound
126 }
127 }
128
129 def void tightenUpperBound(Integer tighterBound) {
130 if (upperBound === null || (tighterBound !== null && upperBound > tighterBound)) {
131 upperBound = tighterBound
132 }
133 }
134
135 def void assertBetween(Integer tighterLowerBound, Integer tighterUpperBound) {
136 tightenLowerBound(tighterLowerBound)
137 tightenUpperBound(tighterUpperBound)
138 }
139
140 def void assertEqualsTo(int bound) {
141 assertBetween(bound, bound)
142 }
143}
144
145abstract class LinearBoundedExpression extends Bounds {
146}
147
148@Accessors
149class Dimension extends LinearBoundedExpression {
150 val String name
151
152 @FinalFieldsConstructor
153 new() {
154 }
155
156 new(String name, Integer lowerBound, Integer upperBound) {
157 this(name)
158 this.lowerBound = lowerBound
159 this.upperBound = upperBound
160 }
161
162 override toString() {
163 '''«IF lowerBound !== null»«lowerBound» <= «ENDIF»«name»«IF upperBound !== null» <= «upperBound»«ENDIF»'''
164 }
165
166}
167
168@Accessors
169class LinearConstraint extends LinearBoundedExpression {
170 val Map<Dimension, Integer> coefficients
171
172 @FinalFieldsConstructor
173 new() {
174 }
175
176 new(Map<Dimension, Integer> coefficients, Integer lowerBound, Integer upperBound) {
177 this(coefficients)
178 this.lowerBound = lowerBound
179 this.upperBound = upperBound
180 }
181
182 override toString() {
183 '''«IF lowerBound !== null»«lowerBound» <= «ENDIF»«FOR pair : coefficients.entrySet SEPARATOR " + "»«IF pair.value != 1»«pair.value» * «ENDIF»«pair.key.name»«ENDFOR»«IF upperBound !== null» <= «upperBound»«ENDIF»'''
184 }
185
186}
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
new file mode 100644
index 00000000..abf65be3
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/RelationConstraintCalculator.xtend
@@ -0,0 +1,156 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import com.google.common.collect.ImmutableList
4import com.google.common.collect.ImmutableSet
5import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.InverseRelationAssertion
6import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.LowerMultiplicityAssertion
7import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.UpperMultiplicityAssertion
8import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference
9import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
10import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
11import java.util.HashMap
12import java.util.List
13import org.eclipse.xtend.lib.annotations.Data
14
15@Data
16class RelationConstraints {
17 val List<RelationMultiplicityConstraint> multiplicityConstraints
18}
19
20@Data
21class RelationMultiplicityConstraint {
22 Relation relation
23 Relation inverseRelation
24 boolean containment
25 boolean container
26 int lowerBound
27 int upperBound
28 int inverseUpperBound
29
30 def isUpperBoundFinite() {
31 upperBound >= 0
32 }
33
34 private def isInverseUpperBoundFinite() {
35 inverseUpperBound >= 0
36 }
37
38 private def canHaveMultipleSourcesPerTarget() {
39 inverseUpperBound != 1
40 }
41
42 def constrainsUnfinished() {
43 lowerBound >= 1 && (!container || lowerBound >= 2)
44 }
45
46 def constrainsUnrepairable() {
47 // TODO Optimize the unrepairable matches computation,
48 // or come up with a heuristic when does computing unrepairables worth the overhead.
49 false && constrainsUnfinished && canHaveMultipleSourcesPerTarget && reference
50 }
51
52 def constrainsRemainingInverse() {
53 lowerBound >= 1 && !containment && !container && inverseUpperBoundFinite && reference
54 }
55
56 def constrainsRemainingContents() {
57 containment
58 }
59
60 def isActive() {
61 constrainsUnfinished || constrainsUnrepairable || constrainsRemainingInverse || constrainsRemainingContents
62 }
63
64 def isSourceTypeComplex() {
65 getParamTypeReference(0) instanceof ComplexTypeReference
66 }
67
68 def isTargetTypeComplex() {
69 getParamTypeReference(1) instanceof ComplexTypeReference
70 }
71
72 def isReference() {
73 sourceTypeComplex && targetTypeComplex
74 }
75
76 def getSourceType() {
77 getParamType(0)
78 }
79
80 def getTargetType() {
81 getParamType(1)
82 }
83
84 private def getParamTypeReference(int i) {
85 val parameters = relation.parameters
86 if (i < parameters.size) {
87 return parameters.get(i)
88 }
89 throw new IllegalArgumentException("Argument index out of range")
90 }
91
92 private def getParamType(int i) {
93 val reference = getParamTypeReference(i)
94 if (reference instanceof ComplexTypeReference) {
95 return reference.referred
96 }
97 throw new IllegalArgumentException("Constraint with primitive type")
98 }
99}
100
101class RelationConstraintCalculator {
102 def calculateRelationConstraints(LogicProblem problem) {
103 val containmentRelations = switch (problem.containmentHierarchies.size) {
104 case 0:
105 <Relation>emptySet
106 case 1:
107 ImmutableSet.copyOf(problem.containmentHierarchies.head.containmentRelations)
108 default:
109 throw new IllegalArgumentException("Only a single containment hierarchy is supported")
110 }
111 val inverseRelations = new HashMap<Relation, Relation>
112 val lowerMultiplicities = new HashMap<Relation, Integer>
113 val upperMultiplicities = new HashMap<Relation, Integer>
114 for (relation : problem.relations) {
115 lowerMultiplicities.put(relation, 0)
116 upperMultiplicities.put(relation, -1)
117 }
118 for (annotation : problem.annotations) {
119 switch (annotation) {
120 InverseRelationAssertion: {
121 inverseRelations.put(annotation.inverseA, annotation.inverseB)
122 inverseRelations.put(annotation.inverseB, annotation.inverseA)
123 }
124 LowerMultiplicityAssertion:
125 lowerMultiplicities.put(annotation.relation, annotation.lower)
126 UpperMultiplicityAssertion:
127 upperMultiplicities.put(annotation.relation, annotation.upper)
128 }
129 }
130 val multiplicityConstraintsBuilder = ImmutableList.builder()
131 for (relation : problem.relations) {
132 val containment = containmentRelations.contains(relation)
133 val lowerMultiplicity = lowerMultiplicities.get(relation)
134 val upperMultiplicity = upperMultiplicities.get(relation)
135 var container = false
136 var inverseUpperMultiplicity = -1
137 val inverseRelation = inverseRelations.get(relation)
138 if (inverseRelation !== null) {
139 inverseUpperMultiplicity = upperMultiplicities.get(inverseRelation)
140 container = containmentRelations.contains(inverseRelation)
141 }
142 if (containment) {
143 inverseUpperMultiplicity = 1
144 }
145 val constraint = new RelationMultiplicityConstraint(relation, inverseRelation, containment, container,
146 lowerMultiplicity, upperMultiplicity, inverseUpperMultiplicity)
147 if (constraint.isActive) {
148 if (relation.parameters.size != 2) {
149 throw new IllegalArgumentException('''Relation «relation.name» has multiplicity or containment constraints, but it is not binary''')
150 }
151 multiplicityConstraintsBuilder.add(constraint)
152 }
153 }
154 new RelationConstraints(multiplicityConstraintsBuilder.build)
155 }
156}
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 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
4import java.util.Iterator
5import org.eclipse.viatra.query.runtime.api.IPatternMatch
6import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
7import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
8
9@FinalFieldsConstructor
10abstract class MultiplicityCalculator<Match extends IPatternMatch> {
11 val ViatraQueryMatcher<Match> matcher
12
13 def getMultiplicity() {
14 val iterator = matcher.streamAllMatches.iterator
15 getMultiplicity(iterator)
16 }
17
18 def getMultiplicity(PartialInterpretation interpretation) {
19 val partialMatch = matcher.newEmptyMatch
20 partialMatch.set(0, interpretation.problem)
21 partialMatch.set(1, interpretation)
22 val iterator = matcher.streamAllMatches(partialMatch).iterator
23 getMultiplicity(iterator)
24 }
25
26 protected def int getMultiplicity(Iterator<? extends Match> iterator)
27}
28
29class RemainingMultiplicityCalculator<Match extends IPatternMatch> extends MultiplicityCalculator<Match> {
30 val int bound
31
32 @FinalFieldsConstructor
33 private new() {
34 }
35
36 protected override getMultiplicity(Iterator<? extends Match> iterator) {
37 var res = 0
38 while (iterator.hasNext) {
39 val match = iterator.next
40 val existingMultiplicity = match.get(3) as Integer
41 if (existingMultiplicity < bound) {
42 res += bound - existingMultiplicity
43 }
44 }
45 res
46 }
47
48 static def <Match extends IPatternMatch> of(ViatraQueryMatcher<Match> matcher, int bound) {
49 if (bound < 0) {
50 new RemainingInfiniteMultiplicityCalculator(matcher)
51 } else {
52 new RemainingMultiplicityCalculator(matcher, bound)
53 }
54 }
55}
56
57package class RemainingInfiniteMultiplicityCalculator<Match extends IPatternMatch> extends MultiplicityCalculator<Match> {
58
59 @FinalFieldsConstructor
60 package new() {
61 }
62
63 protected override getMultiplicity(Iterator<? extends Match> iterator) {
64 if (iterator.hasNext) {
65 -1
66 } else {
67 0
68 }
69 }
70}
71
72@FinalFieldsConstructor
73class UnrepairableMultiplicityCalculator<Match extends IPatternMatch> extends MultiplicityCalculator<Match> {
74 val int lowerBound
75
76 override protected getMultiplicity(Iterator<? extends Match> iterator) {
77 var res = 0
78 while (iterator.hasNext) {
79 val match = iterator.next
80 val existingMultiplicity = match.get(3) as Integer
81 if (existingMultiplicity < lowerBound) {
82 val missingMultiplcity = lowerBound - existingMultiplicity
83 val numerOfRepairMatches = match.get(4) as Integer
84 val unrepairableMultiplicty = missingMultiplcity - numerOfRepairMatches
85 if (unrepairableMultiplicty > res) {
86 res = unrepairableMultiplicty
87 }
88 }
89 }
90 res
91 }
92}
93
94@FinalFieldsConstructor
95class RemainingInverseMultiplicityCalculator<Match extends IPatternMatch> extends MultiplicityCalculator<Match> {
96 val int upperBound
97
98 override protected getMultiplicity(Iterator<? extends Match> iterator) {
99 var res = 0
100 while (iterator.hasNext) {
101 val match = iterator.next
102 val existingMultiplicity = match.get(3) as Integer
103 if (existingMultiplicity < upperBound) {
104 val availableMultiplicity = upperBound - existingMultiplicity
105 val numberOfRepairMatches = match.get(4) as Integer
106 res += Math.min(availableMultiplicity, numberOfRepairMatches)
107 }
108 }
109 res
110 }
111}
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
new file mode 100644
index 00000000..cacba3c6
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ScopePropagator.xtend
@@ -0,0 +1,161 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
4import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope
10import java.util.HashMap
11import java.util.HashSet
12import java.util.Map
13import java.util.Set
14import org.eclipse.xtend.lib.annotations.Accessors
15
16class ScopePropagator {
17 @Accessors(PROTECTED_GETTER) val PartialInterpretation partialInterpretation
18 @Accessors(PROTECTED_GETTER) val ModelGenerationStatistics statistics
19 val Map<PartialTypeInterpratation, Scope> type2Scope
20 @Accessors(PROTECTED_GETTER) val Map<Scope, Set<Scope>> superScopes
21 @Accessors(PROTECTED_GETTER) val Map<Scope, Set<Scope>> subScopes
22
23 @Accessors(PUBLIC_GETTER) var scopePropagationNeeded = false
24
25 new(PartialInterpretation p, ModelGenerationStatistics statistics) {
26 partialInterpretation = p
27 this.statistics = statistics
28 type2Scope = new HashMap
29 for (scope : p.scopes) {
30 type2Scope.put(scope.targetTypeInterpretation, scope)
31 }
32
33 superScopes = new HashMap
34 subScopes = new HashMap
35 for (scope : p.scopes) {
36 superScopes.put(scope, new HashSet)
37 subScopes.put(scope, new HashSet)
38 }
39
40 for (scope : p.scopes) {
41 val target = scope.targetTypeInterpretation
42 if (target instanceof PartialComplexTypeInterpretation) {
43 val supertypeInterpretations = target.supertypeInterpretation
44 for (supertypeInterpretation : supertypeInterpretations) {
45 val supertypeScope = type2Scope.get(supertypeInterpretation)
46 superScopes.get(scope).add(supertypeScope)
47 subScopes.get(supertypeScope).add(scope)
48 }
49 }
50 }
51 var boolean changed
52 do {
53 changed = false
54 for (scope : p.scopes) {
55 val subScopeSet = subScopes.get(scope)
56 val superScopeSet = superScopes.get(scope)
57 for (subScope : subScopeSet) {
58 changed = changed || superScopes.get(subScope).addAll(superScopeSet)
59 }
60 for (superScope : superScopeSet) {
61 changed = changed || subScopes.get(superScope).addAll(subScopeSet)
62 }
63 }
64 } while (changed)
65
66 copyScopeBoundsToHeuristic()
67 }
68
69 def void propagateAllScopeConstraints() {
70 scopePropagationNeeded = false
71 if (!valid) {
72 return
73 }
74 statistics.incrementScopePropagationCount()
75 doPropagateAllScopeConstraints()
76 }
77
78 def isValid() {
79 partialInterpretation.maxNewElements == -1 ||
80 partialInterpretation.minNewElements <= partialInterpretation.maxNewElements
81 }
82
83 protected def copyScopeBoundsToHeuristic() {
84 partialInterpretation.minNewElementsHeuristic = partialInterpretation.minNewElements
85 for (scope : partialInterpretation.scopes) {
86 scope.minNewElementsHeuristic = scope.minNewElements
87 }
88 }
89
90 protected def void doPropagateAllScopeConstraints() {
91 // Nothing to propagate.
92 }
93
94 def decrementTypeScope(PartialTypeInterpratation t) {
95 val isPrimitive = t instanceof PartialPrimitiveInterpretation || t === null
96 if (isPrimitive) {
97 return
98 }
99 scopePropagationNeeded = true
100// println('''Adding to «(t as PartialComplexTypeInterpretation).interpretationOf.name»''')
101 val targetScope = type2Scope.get(t)
102 if (targetScope !== null) {
103 targetScope.removeOne
104 val sups = superScopes.get(targetScope)
105 sups.forEach[removeOne]
106 }
107 if (this.partialInterpretation.minNewElements > 0) {
108 this.partialInterpretation.minNewElements = this.partialInterpretation.minNewElements - 1
109 }
110 if (this.partialInterpretation.minNewElementsHeuristic > 0) {
111 this.partialInterpretation.minNewElementsHeuristic = this.partialInterpretation.minNewElementsHeuristic - 1
112 }
113 if (this.partialInterpretation.maxNewElements > 0) {
114 this.partialInterpretation.maxNewElements = this.partialInterpretation.maxNewElements - 1
115 } else if (this.partialInterpretation.maxNewElements === 0) {
116 setScopesInvalid()
117 }
118
119// println('''Target Scope: «targetScope.minNewElements» - «targetScope.maxNewElements»''')
120// println(''' «this.partialInterpretation.minNewElements» - «this.partialInterpretation.maxNewElements»''')
121// this.partialInterpretation.scopes.forEach[println(''' «(it.targetTypeInterpretation as PartialComplexTypeInterpretation).interpretationOf.name»: «it.minNewElements»-«it.maxNewElements»''')]
122// println('''All constraints are propagated upon increasing «(t as PartialComplexTypeInterpretation).interpretationOf.name»''')
123 }
124
125 def addedToRelation(Relation r) {
126 if (isPropagationNeededAfterAdditionToRelation(r)) {
127 scopePropagationNeeded = true
128 }
129 }
130
131 protected def setScopesInvalid() {
132 partialInterpretation.minNewElements = Integer.MAX_VALUE
133 partialInterpretation.maxNewElements = 0
134 for (scope : partialInterpretation.scopes) {
135 scope.minNewElements = Integer.MAX_VALUE
136 scope.maxNewElements = 0
137 }
138 }
139
140 protected def isPropagationNeededAfterAdditionToRelation(Relation r) {
141 false
142 }
143
144 def isQueryEngineFlushRequiredBeforePropagation() {
145 false
146 }
147
148 private def removeOne(Scope scope) {
149 if (scope.minNewElements > 0) {
150 scope.minNewElements = scope.minNewElements - 1
151 }
152 if (scope.minNewElementsHeuristic > 0) {
153 scope.minNewElementsHeuristic = scope.minNewElementsHeuristic - 1
154 }
155 if (scope.maxNewElements > 0) {
156 scope.maxNewElements = scope.maxNewElements - 1
157 } else if (scope.maxNewElements === 0) {
158 setScopesInvalid()
159 }
160 }
161}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ScopePropagatorStrategy.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ScopePropagatorStrategy.xtend
new file mode 100644
index 00000000..3165917a
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/ScopePropagatorStrategy.xtend
@@ -0,0 +1,71 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import org.eclipse.xtend.lib.annotations.Data
4import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
5
6enum PolyhedralScopePropagatorConstraints {
7 TypeHierarchy,
8 Relational
9}
10
11enum PolyhedralScopePropagatorSolver {
12 Z3Real,
13 Z3Integer,
14 Cbc,
15 Clp
16}
17
18abstract class ScopePropagatorStrategy {
19 public static val None = new Simple("None")
20
21 public static val Basic = new Simple("Basic")
22
23 public static val BasicTypeHierarchy = new Simple("BasicTypeHierarchy")
24
25 private new() {
26 }
27
28 def boolean requiresUpperBoundIndexing()
29
30 static class Simple extends ScopePropagatorStrategy {
31 val String name
32
33 @FinalFieldsConstructor
34 private new() {
35 }
36
37 override requiresUpperBoundIndexing() {
38 false
39 }
40
41 override toString() {
42 name
43 }
44 }
45
46 @Data
47 static class Polyhedral extends ScopePropagatorStrategy {
48 public static val UNLIMITED_TIME = -1
49
50 val PolyhedralScopePropagatorConstraints constraints
51 val PolyhedralScopePropagatorSolver solver
52 val boolean updateHeuristic
53 val double timeoutSeconds
54
55 @FinalFieldsConstructor
56 new() {
57 }
58
59 new(PolyhedralScopePropagatorConstraints constraints, PolyhedralScopePropagatorSolver solver, boolean updateHeuristic) {
60 this(constraints, solver, updateHeuristic, UNLIMITED_TIME)
61 }
62
63 new(PolyhedralScopePropagatorConstraints constraints, PolyhedralScopePropagatorSolver solver) {
64 this(constraints, solver, true)
65 }
66
67 override requiresUpperBoundIndexing() {
68 constraints == PolyhedralScopePropagatorConstraints.Relational
69 }
70 }
71}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/TypeHierarchyScopePropagator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/TypeHierarchyScopePropagator.xtend
new file mode 100644
index 00000000..d1704b39
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/TypeHierarchyScopePropagator.xtend
@@ -0,0 +1,85 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope
6
7class TypeHierarchyScopePropagator extends ScopePropagator {
8
9 new(PartialInterpretation p, ModelGenerationStatistics statistics) {
10 super(p, statistics)
11 }
12
13 protected override doPropagateAllScopeConstraints() {
14 var boolean hadChanged
15 do {
16 hadChanged = false
17 for (superScopeEntry : superScopes.entrySet) {
18 val sub = superScopeEntry.key
19 hadChanged = propagateLowerLimitUp(sub, partialInterpretation) || hadChanged
20 hadChanged = propagateUpperLimitDown(sub, partialInterpretation) || hadChanged
21 for (sup : superScopeEntry.value) {
22 hadChanged = propagateLowerLimitUp(sub, sup) || hadChanged
23 hadChanged = propagateUpperLimitDown(sub, sup) || hadChanged
24 }
25 }
26 } while (hadChanged)
27 }
28
29 private def propagateLowerLimitUp(Scope subScope, Scope superScope) {
30 var changed = false
31 if (subScope.minNewElements > superScope.minNewElements) {
32 superScope.minNewElements = subScope.minNewElements
33 changed = true
34 }
35 if (subScope.minNewElementsHeuristic > superScope.minNewElementsHeuristic) {
36 superScope.minNewElementsHeuristic = subScope.minNewElementsHeuristic
37 changed = true
38 }
39 changed
40 }
41
42 private def propagateUpperLimitDown(Scope subScope, Scope superScope) {
43 if (superScope.maxNewElements >= 0 &&
44 (superScope.maxNewElements < subScope.maxNewElements || subScope.maxNewElements < 0)) {
45// println('''
46// «(subScope.targetTypeInterpretation as PartialComplexTypeInterpretation).interpretationOf.name» -> «(superScope.targetTypeInterpretation as PartialComplexTypeInterpretation).interpretationOf.name»
47// subScope.maxNewElements «subScope.maxNewElements» = superScope.maxNewElements «superScope.maxNewElements»
48// ''')
49 subScope.maxNewElements = superScope.maxNewElements
50 return true
51 } else {
52 return false
53 }
54 }
55
56 private def propagateLowerLimitUp(Scope subScope, PartialInterpretation p) {
57 var changed = false
58 if (subScope.minNewElements > p.minNewElements) {
59// println('''
60// «(subScope.targetTypeInterpretation as PartialComplexTypeInterpretation).interpretationOf.name» -> nodes
61// p.minNewElements «p.minNewElements» = subScope.minNewElements «subScope.minNewElements»
62// ''')
63 p.minNewElements = subScope.minNewElements
64 changed = true
65 }
66 if (subScope.minNewElementsHeuristic > p.minNewElementsHeuristic) {
67 p.minNewElementsHeuristic = subScope.minNewElementsHeuristic
68 changed = true
69 }
70 changed
71 }
72
73 private def propagateUpperLimitDown(Scope subScope, PartialInterpretation p) {
74 if (p.maxNewElements >= 0 && (p.maxNewElements < subScope.maxNewElements || subScope.maxNewElements < 0)) {
75// println('''
76// «(subScope.targetTypeInterpretation as PartialComplexTypeInterpretation).interpretationOf.name» -> nodes
77// subScope.maxNewElements «subScope.maxNewElements» = p.maxNewElements «p.maxNewElements»
78// ''')
79 subScope.maxNewElements = p.maxNewElements
80 return true
81 } else {
82 return false
83 }
84 }
85}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/Z3PolyhedronSolver.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/Z3PolyhedronSolver.xtend
new file mode 100644
index 00000000..3b831433
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/Z3PolyhedronSolver.xtend
@@ -0,0 +1,272 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality
2
3import com.microsoft.z3.AlgebraicNum
4import com.microsoft.z3.ArithExpr
5import com.microsoft.z3.Context
6import com.microsoft.z3.Expr
7import com.microsoft.z3.IntNum
8import com.microsoft.z3.Optimize
9import com.microsoft.z3.RatNum
10import com.microsoft.z3.Status
11import com.microsoft.z3.Symbol
12import java.math.BigDecimal
13import java.math.MathContext
14import java.math.RoundingMode
15import java.util.Map
16import org.eclipse.xtend.lib.annotations.Accessors
17import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
18
19class Z3PolyhedronSolver implements PolyhedronSolver {
20 val boolean lpRelaxation
21 val double timeoutSeconds
22
23 @FinalFieldsConstructor
24 new() {
25 }
26
27 new() {
28 this(false, -1)
29 }
30
31 override createSaturationOperator(Polyhedron polyhedron) {
32 new DisposingZ3SaturationOperator(this, polyhedron)
33 }
34
35 def createPersistentSaturationOperator(Polyhedron polyhedron) {
36 new Z3SaturationOperator(polyhedron, lpRelaxation, timeoutSeconds)
37 }
38}
39
40@FinalFieldsConstructor
41class DisposingZ3SaturationOperator implements PolyhedronSaturationOperator {
42 val Z3PolyhedronSolver solver
43 @Accessors val Polyhedron polyhedron
44
45 override saturate() {
46 val persistentOperator = solver.createPersistentSaturationOperator(polyhedron)
47 try {
48 persistentOperator.saturate
49 } finally {
50 persistentOperator.close
51 }
52 }
53
54 override close() throws Exception {
55 // Nothing to close.
56 }
57}
58
59class Z3SaturationOperator extends AbstractPolyhedronSaturationOperator {
60 static val INFINITY_SYMBOL_NAME = "oo"
61 static val MULT_SYMBOL_NAME = "*"
62 static val TIMEOUT_SYMBOL_NAME = "timeout"
63 static val INTEGER_PRECISION = new BigDecimal(Integer.MAX_VALUE).precision
64 static val ROUND_DOWN = new MathContext(INTEGER_PRECISION, RoundingMode.FLOOR)
65 static val ROUND_UP = new MathContext(INTEGER_PRECISION, RoundingMode.CEILING)
66 // The interval isolating the number is smaller than 1/10^precision.
67 static val ALGEBRAIC_NUMBER_ROUNDING = 0
68
69 extension val Context context
70 val Symbol infinitySymbol
71 val Symbol multSymbol
72 val Map<Dimension, ArithExpr> variables
73 val int timeoutMilliseconds
74
75 new(Polyhedron polyhedron, boolean lpRelaxation, double timeoutSeconds) {
76 super(polyhedron)
77 context = new Context
78 infinitySymbol = context.mkSymbol(INFINITY_SYMBOL_NAME)
79 multSymbol = context.mkSymbol(MULT_SYMBOL_NAME)
80 variables = polyhedron.dimensions.toInvertedMap [ dimension |
81 val name = dimension.name
82 if (lpRelaxation) {
83 mkRealConst(name)
84 } else {
85 mkIntConst(name)
86 }
87 ]
88 timeoutMilliseconds = Math.ceil(timeoutSeconds * 1000) as int
89 }
90
91 override doSaturate() {
92 val status = executeSolver()
93 convertStatusToSaturationResult(status)
94 }
95
96 private def convertStatusToSaturationResult(Status status) {
97 switch (status) {
98 case SATISFIABLE:
99 PolyhedronSaturationResult.SATURATED
100 case UNSATISFIABLE:
101 PolyhedronSaturationResult.EMPTY
102 case UNKNOWN:
103 PolyhedronSaturationResult.UNKNOWN
104 default:
105 throw new IllegalArgumentException("Unknown Status: " + status)
106 }
107 }
108
109 private def executeSolver() {
110 for (expressionToSaturate : polyhedron.expressionsToSaturate) {
111 val expr = expressionToSaturate.toExpr
112 val lowerResult = saturateLowerBound(expr, expressionToSaturate)
113 if (lowerResult != Status.SATISFIABLE) {
114 return lowerResult
115 }
116 val upperResult = saturateUpperBound(expr, expressionToSaturate)
117 if (upperResult != Status.SATISFIABLE) {
118 return upperResult
119 }
120 }
121 Status.SATISFIABLE
122 }
123
124 private def saturateLowerBound(ArithExpr expr, LinearBoundedExpression expressionToSaturate) {
125 val optimize = prepareOptimize
126 val handle = optimize.MkMinimize(expr)
127 val status = optimize.Check()
128 if (status == Status.SATISFIABLE) {
129 val value = switch (resultExpr : handle.lower) {
130 IntNum:
131 resultExpr.getInt()
132 RatNum:
133 ceil(resultExpr)
134 AlgebraicNum:
135 ceil(resultExpr.toUpper(ALGEBRAIC_NUMBER_ROUNDING))
136 default:
137 if (isNegativeInfinity(resultExpr)) {
138 null
139 } else {
140 throw new IllegalArgumentException("Integer result expected, got: " + resultExpr)
141 }
142 }
143 expressionToSaturate.lowerBound = value
144 }
145 status
146 }
147
148 private def floor(RatNum ratNum) {
149 val numerator = new BigDecimal(ratNum.numerator.bigInteger)
150 val denominator = new BigDecimal(ratNum.denominator.bigInteger)
151 numerator.divide(denominator, ROUND_DOWN).setScale(0, RoundingMode.FLOOR).intValue
152 }
153
154 private def saturateUpperBound(ArithExpr expr, LinearBoundedExpression expressionToSaturate) {
155 val optimize = prepareOptimize
156 val handle = optimize.MkMaximize(expr)
157 val status = optimize.Check()
158 if (status == Status.SATISFIABLE) {
159 val value = switch (resultExpr : handle.upper) {
160 IntNum:
161 resultExpr.getInt()
162 RatNum:
163 floor(resultExpr)
164 AlgebraicNum:
165 floor(resultExpr.toLower(ALGEBRAIC_NUMBER_ROUNDING))
166 default:
167 if (isPositiveInfinity(resultExpr)) {
168 null
169 } else {
170 throw new IllegalArgumentException("Integer result expected, got: " + resultExpr)
171 }
172 }
173 expressionToSaturate.upperBound = value
174 }
175 status
176 }
177
178 private def ceil(RatNum ratNum) {
179 val numerator = new BigDecimal(ratNum.numerator.bigInteger)
180 val denominator = new BigDecimal(ratNum.denominator.bigInteger)
181 numerator.divide(denominator, ROUND_UP).setScale(0, RoundingMode.CEILING).intValue
182 }
183
184 private def isPositiveInfinity(Expr expr) {
185 expr.app && expr.getFuncDecl.name == infinitySymbol
186 }
187
188 private def isNegativeInfinity(Expr expr) {
189 // Negative infinity is represented as (* (- 1) oo)
190 if (!expr.app || expr.getFuncDecl.name != multSymbol || expr.numArgs != 2) {
191 return false
192 }
193 isPositiveInfinity(expr.args.get(1))
194 }
195
196 private def prepareOptimize() {
197 val optimize = mkOptimize()
198 if (timeoutMilliseconds >= 0) {
199 val params = mkParams()
200 // We cannot turn TIMEOUT_SYMBOL_NAME into a Symbol in the constructor,
201 // because there is no add(Symbol, int) overload.
202 params.add(TIMEOUT_SYMBOL_NAME, timeoutMilliseconds)
203 optimize.parameters = params
204 }
205 assertConstraints(optimize)
206 optimize
207 }
208
209 private def assertConstraints(Optimize it) {
210 for (pair : variables.entrySet) {
211 assertBounds(pair.value, pair.key)
212 }
213 for (constraint : nonTrivialConstraints) {
214 val expr = createLinearCombination(constraint.coefficients)
215 assertBounds(expr, constraint)
216 }
217 }
218
219 private def assertBounds(Optimize it, ArithExpr expression, LinearBoundedExpression bounds) {
220 val lowerBound = bounds.lowerBound
221 val upperBound = bounds.upperBound
222 if (lowerBound == upperBound) {
223 if (lowerBound === null) {
224 return
225 }
226 Assert(mkEq(expression, mkInt(lowerBound)))
227 } else {
228 if (lowerBound !== null) {
229 Assert(mkGe(expression, mkInt(lowerBound)))
230 }
231 if (upperBound !== null) {
232 Assert(mkLe(expression, mkInt(upperBound)))
233 }
234 }
235 }
236
237 private def toExpr(LinearBoundedExpression linearBoundedExpression) {
238 switch (linearBoundedExpression) {
239 Dimension: variables.get(linearBoundedExpression)
240 LinearConstraint: createLinearCombination(linearBoundedExpression.coefficients)
241 default: throw new IllegalArgumentException("Unknown linear bounded expression:" + linearBoundedExpression)
242 }
243 }
244
245 private def createLinearCombination(Map<Dimension, Integer> coefficients) {
246 val size = coefficients.size
247 if (size == 0) {
248 return mkInt(0)
249 }
250 val array = newArrayOfSize(size)
251 var int i = 0
252 for (pair : coefficients.entrySet) {
253 val variable = variables.get(pair.key)
254 if (variable === null) {
255 throw new IllegalArgumentException("Unknown dimension: " + pair.key.name)
256 }
257 val coefficient = pair.value
258 val term = if (coefficient == 1) {
259 variable
260 } else {
261 mkMul(mkInt(coefficient), variable)
262 }
263 array.set(i, term)
264 i++
265 }
266 mkAdd(array)
267 }
268
269 override close() throws Exception {
270 context.close()
271 }
272}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/formulacanonization/CanonisedFormulae.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/formulacanonization/CanonisedFormulae.xtend
index e511a961..fd4374f5 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/formulacanonization/CanonisedFormulae.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/formulacanonization/CanonisedFormulae.xtend
@@ -11,7 +11,5 @@ import org.eclipse.xtend.lib.annotations.Data
11class CanonisedFormulae { 11class CanonisedFormulae {
12 CharSequence viatraCode 12 CharSequence viatraCode
13 Map<Assertion,String> assertion2ConstraintPattern 13 Map<Assertion,String> assertion2ConstraintPattern
14 Map<ConstantDefinition,String> constant2ValuePattern
15 Map<RelationDefinition,String> relation2ValuePattern 14 Map<RelationDefinition,String> relation2ValuePattern
16 Map<FunctionDefinition,String> function2ValuePattern
17} \ No newline at end of file 15} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/formulacanonization/FormulaCanoniser.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/formulacanonization/FormulaCanoniser.xtend
index 0af0b36a..182f3a3a 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/formulacanonization/FormulaCanoniser.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/formulacanonization/FormulaCanoniser.xtend
@@ -5,17 +5,35 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ConstantDefinition
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.FunctionDefinition 5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.FunctionDefinition
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDefinition 6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDefinition
7import java.util.List 7import java.util.List
8import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Term
9import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.SymbolicValue
10import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Variable
8 11
9/** 12/**
10 * Translates a set of assertions and definitions to viatra patterns. 13 * Translates a Terms into format
14 * <P(x1,...,xn)> := Bodies(x1,...,xn)
15 * <Bodies(x1,...,xn)> := <Body(x1,...,xn)> | <Body(x1,...,xn)> or <Bodies(x1,...,xn)>
16 * <Body(x1,...,xn)> := Exists y1,...,ym : <Constraints(x1,...,xn,y1,....,ym)>
17 * <Constraints(x1,...,xn)> := Constraint(x1,...xn) | Constraint(x1,...,xn) and <Constraints(x1,...,xn)>
11 */ 18 */
12class FormulaCanoniser { 19class FormulaCanoniser {
13 def canonise( 20// def canonise(
14 List<Assertion> assertions, 21// List<Assertion> assertions,
15 List<RelationDefinition> relations, 22// List<RelationDefinition> relations)
16 List<ConstantDefinition> constants, 23// {
17 List<FunctionDefinition> functions) 24//
18 { 25// }
19 26//
20 } 27//
28// def canoniseToConstraintBlock(Term predicate, List<Variable> variables) {
29// val
30// }
31//
32// def freeVariables(Term t) {
33// val subterms = #[t]+t.eAllContents.toList
34// val variables = subterms.filter(Variable).toSet
35// val variableReferences = subterms.filter(SymbolicValue).filter[it.symbolicReference instanceof Variable]
36// val freeVariables = variableReferences.filter[!variables.contains(it.symbolicReference)]
37// return freeVariables.map
38// }
21} \ No newline at end of file 39} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/Interval.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/Interval.xtend
new file mode 100644
index 00000000..691c8783
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/Interval.xtend
@@ -0,0 +1,584 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval
2
3import java.math.BigDecimal
4import java.math.MathContext
5import java.math.RoundingMode
6import org.eclipse.xtend.lib.annotations.Data
7
8abstract class Interval implements Comparable<Interval> {
9 static val PRECISION = 32
10 package static val ROUND_DOWN = new MathContext(PRECISION, RoundingMode.FLOOR)
11 package static val ROUND_UP = new MathContext(PRECISION, RoundingMode.CEILING)
12
13 private new() {
14 }
15
16 abstract def boolean mustEqual(Interval other)
17
18 abstract def boolean mayEqual(Interval other)
19
20 def mustNotEqual(Interval other) {
21 !mayEqual(other)
22 }
23
24 def mayNotEqual(Interval other) {
25 !mustEqual(other)
26 }
27
28 abstract def boolean mustBeLessThan(Interval other)
29
30 abstract def boolean mayBeLessThan(Interval other)
31
32 def mustBeLessThanOrEqual(Interval other) {
33 !mayBeGreaterThan(other)
34 }
35
36 def mayBeLessThanOrEqual(Interval other) {
37 !mustBeGreaterThan(other)
38 }
39
40 def mustBeGreaterThan(Interval other) {
41 other.mustBeLessThan(this)
42 }
43
44 def mayBeGreaterThan(Interval other) {
45 other.mayBeLessThan(this)
46 }
47
48 def mustBeGreaterThanOrEqual(Interval other) {
49 other.mustBeLessThanOrEqual(this)
50 }
51
52 def mayBeGreaterThanOrEqual(Interval other) {
53 other.mayBeLessThanOrEqual(this)
54 }
55
56 abstract def Interval min(Interval other)
57
58 abstract def Interval max(Interval other)
59
60 abstract def Interval join(Interval other)
61
62 def +() {
63 this
64 }
65
66 abstract def Interval -()
67
68 abstract def Interval +(Interval other)
69
70 abstract def Interval -(Interval other)
71
72 abstract def Interval *(int count)
73
74 abstract def Interval *(Interval other)
75
76 abstract def Interval /(Interval other)
77
78 abstract def Interval **(Interval other)
79
80 public static val EMPTY = new Interval {
81 override mustEqual(Interval other) {
82 true
83 }
84
85 override mayEqual(Interval other) {
86 false
87 }
88
89 override mustBeLessThan(Interval other) {
90 true
91 }
92
93 override mayBeLessThan(Interval other) {
94 false
95 }
96
97 override min(Interval other) {
98 EMPTY
99 }
100
101 override max(Interval other) {
102 EMPTY
103 }
104
105 override join(Interval other) {
106 other
107 }
108
109 override -() {
110 EMPTY
111 }
112
113 override +(Interval other) {
114 EMPTY
115 }
116
117 override -(Interval other) {
118 EMPTY
119 }
120
121 override *(int count) {
122 EMPTY
123 }
124
125 override *(Interval other) {
126 EMPTY
127 }
128
129 override /(Interval other) {
130 EMPTY
131 }
132
133 override **(Interval other) {
134 EMPTY
135 }
136
137 override toString() {
138 "∅"
139 }
140
141 override compareTo(Interval o) {
142 if (o == EMPTY) {
143 0
144 } else {
145 -1
146 }
147 }
148
149 }
150
151 public static val Interval ZERO = new NonEmpty(BigDecimal.ZERO, BigDecimal.ZERO)
152
153 public static val Interval UNBOUNDED = new NonEmpty(null, null)
154
155 static def Interval of(BigDecimal lower, BigDecimal upper) {
156 new NonEmpty(lower, upper)
157 }
158
159 static def between(double lower, double upper) {
160 of(new BigDecimal(lower, ROUND_DOWN), new BigDecimal(upper, ROUND_UP))
161 }
162
163 static def upTo(double upper) {
164 of(null, new BigDecimal(upper, ROUND_UP))
165 }
166
167 static def above(double lower) {
168 of(new BigDecimal(lower, ROUND_DOWN), null)
169 }
170
171 @Data
172 private static class NonEmpty extends Interval {
173 val BigDecimal lower
174 val BigDecimal upper
175
176 /**
177 * Construct a new non-empty interval.
178 *
179 * @param lower The lower bound of the interval. Use <code>null</code> for negative infinity.
180 * @param upper The upper bound of the interval. Use <code>null</code> for positive infinity.
181 */
182 new(BigDecimal lower, BigDecimal upper) {
183 if (lower !== null && upper !== null && lower > upper) {
184 throw new IllegalArgumentException("Lower bound of interval must not be larger than upper bound")
185 }
186 this.lower = lower
187 this.upper = upper
188 }
189
190 override mustEqual(Interval other) {
191 switch (other) {
192 case EMPTY: true
193 NonEmpty: lower == upper && lower == other.lower && lower == other.upper
194 default: throw new IllegalArgumentException("Unknown interval: " + other)
195 }
196 }
197
198 override mayEqual(Interval other) {
199 if (other instanceof NonEmpty) {
200 (lower === null || other.upper === null || lower <= other.upper) &&
201 (other.lower === null || upper === null || other.lower <= upper)
202 } else {
203 false
204 }
205 }
206
207 override mustBeLessThan(Interval other) {
208 switch (other) {
209 case EMPTY: true
210 NonEmpty: upper !== null && other.lower !== null && upper < other.lower
211 default: throw new IllegalArgumentException("Unknown interval: " + other)
212 }
213 }
214
215 override mayBeLessThan(Interval other) {
216 if (other instanceof NonEmpty) {
217 lower === null || other.upper === null || lower < other.upper
218 } else {
219 false
220 }
221 }
222
223 override min(Interval other) {
224 switch (other) {
225 case EMPTY: this
226 NonEmpty: min(other)
227 default: throw new IllegalArgumentException("Unknown interval: " + other)
228 }
229 }
230
231 def min(NonEmpty other) {
232 new NonEmpty(
233 lower.tryMin(other.lower),
234 if(other.upper === null) upper else if(upper === null) other.upper else upper.min(other.upper)
235 )
236 }
237
238 override max(Interval other) {
239 switch (other) {
240 case EMPTY: this
241 NonEmpty: max(other)
242 default: throw new IllegalArgumentException("Unknown interval: " + other)
243 }
244 }
245
246 def max(NonEmpty other) {
247 new NonEmpty(
248 if(other.lower === null) lower else if(lower === null) other.lower else lower.max(other.lower),
249 upper.tryMax(other.upper)
250 )
251 }
252
253 override join(Interval other) {
254 switch (other) {
255 case EMPTY: this
256 NonEmpty: new NonEmpty(lower.tryMin(other.lower), upper.tryMax(other.upper))
257 default: throw new IllegalArgumentException("Unknown interval: " + other)
258 }
259 }
260
261 override -() {
262 new NonEmpty(upper?.negate(ROUND_DOWN), lower?.negate(ROUND_UP))
263 }
264
265 override +(Interval other) {
266 switch (other) {
267 case EMPTY: EMPTY
268 NonEmpty: this + other
269 default: throw new IllegalArgumentException("Unknown interval: " + other)
270 }
271 }
272
273 def +(NonEmpty other) {
274 new NonEmpty(
275 lower.tryAdd(other.lower, ROUND_DOWN),
276 upper.tryAdd(other.upper, ROUND_UP)
277 )
278 }
279
280 private static def tryAdd(BigDecimal a, BigDecimal b, MathContext mc) {
281 if (b === null) {
282 null
283 } else {
284 a?.add(b, mc)
285 }
286 }
287
288 override -(Interval other) {
289 switch (other) {
290 case EMPTY: EMPTY
291 NonEmpty: this - other
292 default: throw new IllegalArgumentException("Unknown interval: " + other)
293 }
294 }
295
296 def -(NonEmpty other) {
297 new NonEmpty(
298 lower.trySubtract(other.upper, ROUND_DOWN),
299 upper.trySubtract(other.lower, ROUND_UP)
300 )
301 }
302
303 private static def trySubtract(BigDecimal a, BigDecimal b, MathContext mc) {
304 if (b === null) {
305 null
306 } else {
307 a?.subtract(b, mc)
308 }
309 }
310
311 override *(int count) {
312 val bigCount = new BigDecimal(count)
313 new NonEmpty(
314 lower.tryMultiply(bigCount, ROUND_DOWN),
315 upper.tryMultiply(bigCount, ROUND_UP)
316 )
317 }
318
319 override *(Interval other) {
320 switch (other) {
321 case EMPTY: EMPTY
322 NonEmpty: this * other
323 default: throw new IllegalArgumentException("Unknown interval: " + other)
324 }
325 }
326
327 def *(NonEmpty other) {
328 if (this == ZERO || other == ZERO) {
329 ZERO
330 } else if (nonpositive) {
331 if (other.nonpositive) {
332 new NonEmpty(
333 upper.multiply(other.upper, ROUND_DOWN),
334 lower.tryMultiply(other.lower, ROUND_UP)
335 )
336 } else if (other.nonnegative) {
337 new NonEmpty(
338 lower.tryMultiply(other.upper, ROUND_DOWN),
339 upper.multiply(other.lower, ROUND_UP)
340 )
341 } else {
342 new NonEmpty(
343 lower.tryMultiply(other.upper, ROUND_DOWN),
344 lower.tryMultiply(other.lower, ROUND_UP)
345 )
346 }
347 } else if (nonnegative) {
348 if (other.nonpositive) {
349 new NonEmpty(
350 upper.tryMultiply(other.lower, ROUND_DOWN),
351 lower.multiply(other.upper, ROUND_UP)
352 )
353 } else if (other.nonnegative) {
354 new NonEmpty(
355 lower.multiply(other.lower, ROUND_DOWN),
356 upper.tryMultiply(other.upper, ROUND_UP)
357 )
358 } else {
359 new NonEmpty(
360 upper.tryMultiply(other.lower, ROUND_DOWN),
361 upper.tryMultiply(other.upper, ROUND_UP)
362 )
363 }
364 } else {
365 if (other.nonpositive) {
366 new NonEmpty(
367 upper.tryMultiply(other.lower, ROUND_DOWN),
368 lower.tryMultiply(other.lower, ROUND_UP)
369 )
370 } else if (other.nonnegative) {
371 new NonEmpty(
372 lower.tryMultiply(other.upper, ROUND_DOWN),
373 upper.tryMultiply(other.upper, ROUND_UP)
374 )
375 } else {
376 new NonEmpty(
377 lower.tryMultiply(other.upper, ROUND_DOWN).tryMin(upper.tryMultiply(other.lower, ROUND_DOWN)),
378 lower.tryMultiply(other.lower, ROUND_UP).tryMax(upper.tryMultiply(other.upper, ROUND_UP))
379 )
380 }
381 }
382 }
383
384 private def isNonpositive() {
385 upper !== null && upper <= BigDecimal.ZERO
386 }
387
388 private def isNonnegative() {
389 lower !== null && lower >= BigDecimal.ZERO
390 }
391
392 private static def tryMultiply(BigDecimal a, BigDecimal b, MathContext mc) {
393 if (b === null) {
394 null
395 } else {
396 a?.multiply(b, mc)
397 }
398 }
399
400 private static def tryMin(BigDecimal a, BigDecimal b) {
401 if (b === null) {
402 null
403 } else {
404 a?.min(b)
405 }
406 }
407
408 private static def tryMax(BigDecimal a, BigDecimal b) {
409 if (b === null) {
410 null
411 } else {
412 a?.max(b)
413 }
414 }
415
416 override /(Interval other) {
417 switch (other) {
418 case EMPTY: EMPTY
419 NonEmpty: this / other
420 default: throw new IllegalArgumentException("Unknown interval: " + other)
421 }
422 }
423
424 def /(NonEmpty other) {
425 if (other == ZERO) {
426 EMPTY
427 } else if (this == ZERO) {
428 ZERO
429 } else if (other.strictlyNegative) {
430 if (nonpositive) {
431 new NonEmpty(
432 upper.tryDivide(other.lower, ROUND_DOWN),
433 lower.tryDivide(other.upper, ROUND_UP)
434 )
435 } else if (nonnegative) {
436 new NonEmpty(
437 upper.tryDivide(other.upper, ROUND_DOWN),
438 lower.tryDivide(other.lower, ROUND_UP)
439 )
440 } else { // lower < 0 < upper
441 new NonEmpty(
442 upper.tryDivide(other.upper, ROUND_DOWN),
443 lower.tryDivide(other.upper, ROUND_UP)
444 )
445 }
446 } else if (other.strictlyPositive) {
447 if (nonpositive) {
448 new NonEmpty(
449 lower.tryDivide(other.lower, ROUND_DOWN),
450 upper.tryDivide(other.upper, ROUND_UP)
451 )
452 } else if (nonnegative) {
453 new NonEmpty(
454 lower.tryDivide(other.upper, ROUND_DOWN),
455 upper.tryDivide(other.lower, ROUND_UP)
456 )
457 } else { // lower < 0 < upper
458 new NonEmpty(
459 lower.tryDivide(other.lower, ROUND_DOWN),
460 upper.tryDivide(other.lower, ROUND_UP)
461 )
462 }
463 } else { // other contains 0
464 if (other.lower == BigDecimal.ZERO) { // 0 == other.lower < other.upper, because [0, 0] was exluded earlier
465 if (nonpositive) {
466 new NonEmpty(null, upper.tryDivide(other.upper, ROUND_UP))
467 } else if (nonnegative) {
468 new NonEmpty(lower.tryDivide(other.upper, ROUND_DOWN), null)
469 } else { // lower < 0 < upper
470 UNBOUNDED
471 }
472 } else if (other.upper == BigDecimal.ZERO) { // other.lower < other.upper == 0
473 if (nonpositive) {
474 new NonEmpty(upper.tryDivide(other.lower, ROUND_DOWN), null)
475 } else if (nonnegative) {
476 new NonEmpty(null, lower.tryDivide(other.lower, ROUND_UP))
477 } else { // lower < 0 < upper
478 UNBOUNDED
479 }
480 } else { // other.lower < 0 < other.upper
481 UNBOUNDED
482 }
483 }
484 }
485
486 private def isStrictlyNegative() {
487 upper !== null && upper < BigDecimal.ZERO
488 }
489
490 private def isStrictlyPositive() {
491 lower !== null && lower > BigDecimal.ZERO
492 }
493
494 private static def tryDivide(BigDecimal a, BigDecimal b, MathContext mc) {
495 if (b === null) {
496 BigDecimal.ZERO
497 } else {
498 a?.divide(b, mc)
499 }
500 }
501
502 override **(Interval other) {
503 switch (other) {
504 case EMPTY: EMPTY
505 NonEmpty: this ** other
506 default: throw new IllegalArgumentException("Unknown interval: " + other)
507 }
508 }
509
510 def **(NonEmpty other) {
511 // XXX This should use proper rounding for log and exp instead of
512 // converting to double.
513 // XXX We should not ignore (integer) powers of negative numbers.
514 val lowerLog = if (lower === null || lower <= BigDecimal.ZERO) {
515 null
516 } else {
517 new BigDecimal(Math.log(lower.doubleValue), ROUND_DOWN)
518 }
519 val upperLog = if (upper === null) {
520 null
521 } else if (upper == BigDecimal.ZERO) {
522 return ZERO
523 } else if (upper < BigDecimal.ZERO) {
524 return EMPTY
525 } else {
526 new BigDecimal(Math.log(upper.doubleValue), ROUND_UP)
527 }
528 val log = new NonEmpty(lowerLog, upperLog)
529 val product = log * other
530 if (product instanceof NonEmpty) {
531 val lowerResult = if (product.lower === null) {
532 BigDecimal.ZERO
533 } else {
534 new BigDecimal(Math.exp(product.lower.doubleValue), ROUND_DOWN)
535 }
536 val upperResult = if (product.upper === null) {
537 null
538 } else {
539 new BigDecimal(Math.exp(product.upper.doubleValue), ROUND_UP)
540 }
541 new NonEmpty(lowerResult, upperResult)
542 } else {
543 throw new IllegalArgumentException("Unknown interval: " + product)
544 }
545 }
546
547 override toString() {
548 '''«IF lower === null»(-∞«ELSE»[«lower»«ENDIF», «IF upper === null»∞)«ELSE»«upper»]«ENDIF»'''
549 }
550
551 override compareTo(Interval o) {
552 switch (o) {
553 case EMPTY: 1
554 NonEmpty: compareTo(o)
555 default: throw new IllegalArgumentException("Unknown interval: " + o)
556 }
557 }
558
559 def compareTo(NonEmpty o) {
560 if (lower === null) {
561 if (o.lower !== null) {
562 return -1
563 }
564 } else if (o.lower === null) { // lower !== null
565 return 1
566 } else { // both lower and o.lower are finite
567 val lowerDifference = lower.compareTo(o.lower)
568 if (lowerDifference != 0) {
569 return lowerDifference
570 }
571 }
572 if (upper === null) {
573 if (o.upper === null) {
574 return 0
575 } else {
576 return 1
577 }
578 } else if (o.upper === null) { // upper !== null
579 return -1
580 }
581 upper.compareTo(o.upper)
582 }
583 }
584}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalAggregationMode.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalAggregationMode.java
new file mode 100644
index 00000000..f106e305
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalAggregationMode.java
@@ -0,0 +1,99 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval;
2
3import java.util.function.BinaryOperator;
4
5public enum IntervalAggregationMode implements BinaryOperator<Interval> {
6 SUM("intervalSum", "Sum a set of intervals") {
7 @Override
8 public IntervalRedBlackNode createNode(Interval interval) {
9 return new IntervalRedBlackNode(interval) {
10 public boolean isMultiplicitySensitive() {
11 return true;
12 }
13
14 public Interval multiply(Interval interval, int count) {
15 return interval.operator_multiply(count);
16 };
17
18 @Override
19 public Interval op(Interval left, Interval right) {
20 return left.operator_plus(right);
21 }
22 };
23 }
24
25 @Override
26 public Interval getNeutral() {
27 return Interval.ZERO;
28 }
29 },
30
31 MIN("intervalMin", "Find the minimum a set of intervals") {
32 @Override
33 public IntervalRedBlackNode createNode(Interval interval) {
34 return new IntervalRedBlackNode(interval) {
35 @Override
36 public Interval op(Interval left, Interval right) {
37 return left.min(right);
38 }
39 };
40 }
41 },
42
43 MAX("intervalMax", "Find the maximum a set of intervals") {
44 @Override
45 public IntervalRedBlackNode createNode(Interval interval) {
46 return new IntervalRedBlackNode(interval) {
47 @Override
48 public Interval op(Interval left, Interval right) {
49 return left.max(right);
50 }
51 };
52 }
53 },
54
55 JOIN("intervalJoin", "Calculate the smallest interval containing all the intervals in a set") {
56 @Override
57 public IntervalRedBlackNode createNode(Interval interval) {
58 return new IntervalRedBlackNode(interval) {
59 @Override
60 public Interval op(Interval left, Interval right) {
61 return left.join(right);
62 }
63 };
64 }
65 };
66
67 private final String modeName;
68 private final String description;
69 private final IntervalRedBlackNode empty;
70
71 IntervalAggregationMode(String modeName, String description) {
72 this.modeName = modeName;
73 this.description = description;
74 empty = createNode(null);
75 }
76
77 public String getModeName() {
78 return modeName;
79 }
80
81 public String getDescription() {
82 return description;
83 }
84
85 public IntervalRedBlackNode getEmpty() {
86 return empty;
87 }
88
89 @Override
90 public Interval apply(Interval left, Interval right) {
91 return empty.op(left, right);
92 }
93
94 public abstract IntervalRedBlackNode createNode(Interval interval);
95
96 public Interval getNeutral() {
97 return Interval.EMPTY;
98 }
99}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalAggregationOperator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalAggregationOperator.xtend
new file mode 100644
index 00000000..21d3d73b
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalAggregationOperator.xtend
@@ -0,0 +1,48 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval
2
3import java.util.stream.Stream
4import org.eclipse.viatra.query.runtime.matchers.psystem.aggregations.IMultisetAggregationOperator
5import org.eclipse.xtend.lib.annotations.Accessors
6import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
7
8@FinalFieldsConstructor
9class IntervalAggregationOperator implements IMultisetAggregationOperator<Interval, IntervalRedBlackNode, Interval> {
10 @Accessors val IntervalAggregationMode mode
11
12 override getName() {
13 mode.modeName
14 }
15
16 override getShortDescription() {
17 mode.description
18 }
19
20 override createNeutral() {
21 mode.empty
22 }
23
24 override isNeutral(IntervalRedBlackNode result) {
25 result.leaf
26 }
27
28 override update(IntervalRedBlackNode oldResult, Interval updateValue, boolean isInsertion) {
29 if (isInsertion) {
30 val newNode = mode.createNode(updateValue)
31 oldResult.add(newNode)
32 } else {
33 oldResult.remove(updateValue)
34 }
35 }
36
37 override getAggregate(IntervalRedBlackNode result) {
38 if (result.leaf) {
39 mode.neutral
40 } else {
41 result.result
42 }
43 }
44
45 override aggregateStream(Stream<Interval> stream) {
46 stream.reduce(mode).orElse(mode.neutral)
47 }
48}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalHullAggregatorOperator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalHullAggregatorOperator.xtend
new file mode 100644
index 00000000..ce48eca1
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalHullAggregatorOperator.xtend
@@ -0,0 +1,87 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval
2
3import java.math.BigDecimal
4import java.math.MathContext
5import java.util.SortedMap
6import java.util.TreeMap
7import java.util.stream.Stream
8import org.eclipse.viatra.query.runtime.matchers.psystem.aggregations.IMultisetAggregationOperator
9
10abstract class IntervalHullAggregatorOperator<T extends Comparable<T>> implements IMultisetAggregationOperator<T, SortedMap<T, Integer>, Interval> {
11 protected new() {
12 }
13
14 override getName() {
15 "intervalHull"
16 }
17
18 override getShortDescription() {
19 "Calculates the interval hull of a set of numbers"
20 }
21
22 override createNeutral() {
23 new TreeMap
24 }
25
26 override getAggregate(SortedMap<T, Integer> result) {
27 if (result.neutral) {
28 Interval.EMPTY
29 } else {
30 toInterval(result.firstKey, result.lastKey)
31 }
32 }
33
34 protected abstract def BigDecimal toBigDecimal(T value, MathContext mc)
35
36 private def toInterval(T min, T max) {
37 Interval.of(min.toBigDecimal(Interval.ROUND_DOWN), max.toBigDecimal(Interval.ROUND_UP))
38 }
39
40 override isNeutral(SortedMap<T, Integer> result) {
41 result.empty
42 }
43
44 override update(SortedMap<T, Integer> oldResult, T updateValue, boolean isInsertion) {
45 if (isInsertion) {
46 oldResult.compute(updateValue) [ key, value |
47 if (value === null) {
48 1
49 } else if (value > 0) {
50 value + 1
51 } else {
52 throw new IllegalStateException("Invalid count: " + value)
53 }
54 ]
55 } else {
56 oldResult.compute(updateValue) [ key, value |
57 if (value === 1) {
58 null
59 } else if (value > 1) {
60 value - 1
61 } else {
62 throw new IllegalStateException("Invalid count: " + value)
63 }
64 ]
65 }
66 oldResult
67 }
68
69 override aggregateStream(Stream<T> stream) {
70 val iterator = stream.iterator
71 if (!iterator.hasNext) {
72 return Interval.EMPTY
73 }
74 var min = iterator.next
75 var max = min
76 while (iterator.hasNext) {
77 val element = iterator.next
78 if (element.compareTo(min) < 0) {
79 min = element
80 }
81 if (element.compareTo(max) > 0) {
82 max = element
83 }
84 }
85 toInterval(min, max)
86 }
87}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalRedBlackNode.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalRedBlackNode.xtend
new file mode 100644
index 00000000..3aa575bc
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/IntervalRedBlackNode.xtend
@@ -0,0 +1,177 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval
2
3abstract class IntervalRedBlackNode extends RedBlackNode<IntervalRedBlackNode> {
4 public val Interval interval
5 public var int count = 1
6 public var Interval result
7
8 new(Interval interval) {
9 this.interval = interval
10 }
11
12 def boolean isMultiplicitySensitive() {
13 false
14 }
15
16 def Interval multiply(Interval interval, int count) {
17 interval
18 }
19
20 abstract def Interval op(Interval left, Interval right)
21
22 override augment() {
23 val value = calcualteAugmentation()
24 if (result == value) {
25 false
26 } else {
27 result = value
28 true
29 }
30 }
31
32 private def calcualteAugmentation() {
33 var value = multiply(interval, count)
34 if (!left.leaf) {
35 value = op(value, left.result)
36 }
37 if (!right.leaf) {
38 value = op(value, right.result)
39 }
40 value
41 }
42
43 override assertNodeIsValid() {
44 super.assertNodeIsValid()
45 if (leaf) {
46 return
47 }
48 if (count <= 0) {
49 throw new IllegalStateException("Node with nonpositive count")
50 }
51 val value = calcualteAugmentation()
52 if (result != value) {
53 throw new IllegalStateException("Node with invalid augmentation: " + result + " != " + value)
54 }
55 }
56
57 override assertSubtreeIsValid() {
58 super.assertSubtreeIsValid()
59 assertNodeIsValid()
60 }
61
62 override compareTo(IntervalRedBlackNode other) {
63 if (leaf || other.leaf) {
64 throw new IllegalArgumentException("One of the nodes is a leaf node")
65 }
66 interval.compareTo(other.interval)
67 }
68
69 def add(IntervalRedBlackNode newNode) {
70 if (parent !== null) {
71 throw new IllegalArgumentException("This is not the root of a tree")
72 }
73 if (leaf) {
74 newNode.isRed = false
75 newNode.left = this
76 newNode.right = this
77 newNode.parent = null
78 newNode.augment
79 return newNode
80 }
81 val modifiedNode = addWithoutFixup(newNode)
82 if (modifiedNode === newNode) {
83 // Must augment here, because fixInsertion() might call augment()
84 // on a node repeatedly, which might lose the change notification the
85 // second time it is called, and the augmentation will fail to
86 // reach the root.
87 modifiedNode.augmentRecursively
88 modifiedNode.isRed = true
89 return modifiedNode.fixInsertion
90 }
91 if (multiplicitySensitive) {
92 modifiedNode.augmentRecursively
93 }
94 this
95 }
96
97 private def addWithoutFixup(IntervalRedBlackNode newNode) {
98 var node = this
99 while (!node.leaf) {
100 val comparison = node.interval.compareTo(newNode.interval)
101 if (comparison < 0) {
102 if (node.left.leaf) {
103 newNode.left = node.left
104 newNode.right = node.left
105 node.left = newNode
106 newNode.parent = node
107 return newNode
108 } else {
109 node = node.left
110 }
111 } else if (comparison > 0) {
112 if (node.right.leaf) {
113 newNode.left = node.right
114 newNode.right = node.right
115 node.right = newNode
116 newNode.parent = node
117 return newNode
118 } else {
119 node = node.right
120 }
121 } else { // comparison == 0
122 newNode.parent = null
123 node.count++
124 return node
125 }
126 }
127 throw new IllegalStateException("Reached leaf node while searching for insertion point")
128 }
129
130 private def augmentRecursively() {
131 for (var node = this; node !== null; node = node.parent) {
132 if (!node.augment) {
133 return
134 }
135 }
136 }
137
138 def remove(Interval interval) {
139 val node = find(interval)
140 node.count--
141 if (node.count == 0) {
142 return node.remove
143 }
144 if (multiplicitySensitive) {
145 node.augmentRecursively
146 }
147 this
148 }
149
150 private def find(Interval interval) {
151 var node = this
152 while (!node.leaf) {
153 val comparison = node.interval.compareTo(interval)
154 if (comparison < 0) {
155 node = node.left
156 } else if (comparison > 0) {
157 node = node.right
158 } else { // comparison == 0
159 return node
160 }
161 }
162 throw new IllegalStateException("Reached leaf node while searching for interval to remove")
163 }
164
165 override toString() {
166 if (leaf) {
167 "L"
168 } else {
169 '''
170 «IF isRed»R«ELSE»B«ENDIF» «count»«interval» : «result»
171 «left»
172 «right»
173 '''
174 }
175 }
176
177}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/RedBlackNode.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/RedBlackNode.java
new file mode 100644
index 00000000..8c40816b
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/RedBlackNode.java
@@ -0,0 +1,1392 @@
1/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2016 btrekkie
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval;
25
26import java.lang.reflect.Array;
27import java.util.Collection;
28import java.util.Comparator;
29import java.util.HashSet;
30import java.util.Iterator;
31import java.util.Set;
32
33/**
34 * A node in a red-black tree ( https://en.wikipedia.org/wiki/Red%E2%80%93black_tree ). Compared to a class like Java's
35 * TreeMap, RedBlackNode is a low-level data structure. The internals of a node are exposed as public fields, allowing
36 * clients to directly observe and manipulate the structure of the tree. This gives clients flexibility, although it
37 * also enables them to violate the red-black or BST properties. The RedBlackNode class provides methods for performing
38 * various standard operations, such as insertion and removal.
39 *
40 * Unlike most implementations of binary search trees, RedBlackNode supports arbitrary augmentation. By subclassing
41 * RedBlackNode, clients can add arbitrary data and augmentation information to each node. For example, if we were to
42 * use a RedBlackNode subclass to implement a sorted set, the subclass would have a field storing an element in the set.
43 * If we wanted to keep track of the number of non-leaf nodes in each subtree, we would store this as a "size" field and
44 * override augment() to update this field. All RedBlackNode methods (such as "insert" and remove()) call augment() as
45 * necessary to correctly maintain the augmentation information, unless otherwise indicated.
46 *
47 * The values of the tree are stored in the non-leaf nodes. RedBlackNode does not support use cases where values must be
48 * stored in the leaf nodes. It is recommended that all of the leaf nodes in a given tree be the same (black)
49 * RedBlackNode instance, to save space. The root of an empty tree is a leaf node, as opposed to null.
50 *
51 * For reference, a red-black tree is a binary search tree satisfying the following properties:
52 *
53 * - Every node is colored red or black.
54 * - The leaf nodes, which are dummy nodes that do not store any values, are colored black.
55 * - The root is black.
56 * - Both children of each red node are black.
57 * - Every path from the root to a leaf contains the same number of black nodes.
58 *
59 * @param <N> The type of node in the tree. For example, we might have
60 * "class FooNode<T> extends RedBlackNode<FooNode<T>>".
61 * @author Bill Jacobs
62 */
63public abstract class RedBlackNode<N extends RedBlackNode<N>> implements Comparable<N> {
64 /** A Comparator that compares Comparable elements using their natural order. */
65 private static final Comparator<Comparable<Object>> NATURAL_ORDER = new Comparator<Comparable<Object>>() {
66 @Override
67 public int compare(Comparable<Object> value1, Comparable<Object> value2) {
68 return value1.compareTo(value2);
69 }
70 };
71
72 /** The parent of this node, if any. "parent" is null if this is a leaf node. */
73 public N parent;
74
75 /** The left child of this node. "left" is null if this is a leaf node. */
76 public N left;
77
78 /** The right child of this node. "right" is null if this is a leaf node. */
79 public N right;
80
81 /** Whether the node is colored red, as opposed to black. */
82 public boolean isRed;
83
84 /**
85 * Sets any augmentation information about the subtree rooted at this node that is stored in this node. For
86 * example, if we augment each node by subtree size (the number of non-leaf nodes in the subtree), this method would
87 * set the size field of this node to be equal to the size field of the left child plus the size field of the right
88 * child plus one.
89 *
90 * "Augmentation information" is information that we can compute about a subtree rooted at some node, preferably
91 * based only on the augmentation information in the node's two children and the information in the node. Examples
92 * of augmentation information are the sum of the values in a subtree and the number of non-leaf nodes in a subtree.
93 * Augmentation information may not depend on the colors of the nodes.
94 *
95 * This method returns whether the augmentation information in any of the ancestors of this node might have been
96 * affected by changes in this subtree since the last call to augment(). In the usual case, where the augmentation
97 * information depends only on the information in this node and the augmentation information in its immediate
98 * children, this is equivalent to whether the augmentation information changed as a result of this call to
99 * augment(). For example, in the case of subtree size, this returns whether the value of the size field prior to
100 * calling augment() differed from the size field of the left child plus the size field of the right child plus one.
101 * False positives are permitted. The return value is unspecified if we have not called augment() on this node
102 * before.
103 *
104 * This method may assume that this is not a leaf node. It may not assume that the augmentation information stored
105 * in any of the tree's nodes is correct. However, if the augmentation information stored in all of the node's
106 * descendants is correct, then the augmentation information stored in this node must be correct after calling
107 * augment().
108 */
109 public boolean augment() {
110 return false;
111 }
112
113 /**
114 * Throws a RuntimeException if we detect that this node locally violates any invariants specific to this subclass
115 * of RedBlackNode. For example, if this stores the size of the subtree rooted at this node, this should throw a
116 * RuntimeException if the size field of this is not equal to the size field of the left child plus the size field
117 * of the right child plus one. Note that we may call this on a leaf node.
118 *
119 * assertSubtreeIsValid() calls assertNodeIsValid() on each node, or at least starts to do so until it detects a
120 * problem. assertNodeIsValid() should assume the node is in a tree that satisfies all properties common to all
121 * red-black trees, as assertSubtreeIsValid() is responsible for such checks. assertNodeIsValid() should be
122 * "downward-looking", i.e. it should ignore any information in "parent", and it should be "local", i.e. it should
123 * only check a constant number of descendants. To include "global" checks, such as verifying the BST property
124 * concerning ordering, override assertSubtreeIsValid(). assertOrderIsValid is useful for checking the BST
125 * property.
126 */
127 public void assertNodeIsValid() {
128
129 }
130
131 /** Returns whether this is a leaf node. */
132 public boolean isLeaf() {
133 return left == null;
134 }
135
136 /** Returns the root of the tree that contains this node. */
137 public N root() {
138 @SuppressWarnings("unchecked")
139 N node = (N)this;
140 while (node.parent != null) {
141 node = node.parent;
142 }
143 return node;
144 }
145
146 /** Returns the first node in the subtree rooted at this node, if any. */
147 public N min() {
148 if (isLeaf()) {
149 return null;
150 }
151 @SuppressWarnings("unchecked")
152 N node = (N)this;
153 while (!node.left.isLeaf()) {
154 node = node.left;
155 }
156 return node;
157 }
158
159 /** Returns the last node in the subtree rooted at this node, if any. */
160 public N max() {
161 if (isLeaf()) {
162 return null;
163 }
164 @SuppressWarnings("unchecked")
165 N node = (N)this;
166 while (!node.right.isLeaf()) {
167 node = node.right;
168 }
169 return node;
170 }
171
172 /** Returns the node immediately before this in the tree that contains this node, if any. */
173 public N predecessor() {
174 if (!left.isLeaf()) {
175 N node;
176 for (node = left; !node.right.isLeaf(); node = node.right);
177 return node;
178 } else if (parent == null) {
179 return null;
180 } else {
181 @SuppressWarnings("unchecked")
182 N node = (N)this;
183 while (node.parent != null && node.parent.left == node) {
184 node = node.parent;
185 }
186 return node.parent;
187 }
188 }
189
190 /** Returns the node immediately after this in the tree that contains this node, if any. */
191 public N successor() {
192 if (!right.isLeaf()) {
193 N node;
194 for (node = right; !node.left.isLeaf(); node = node.left);
195 return node;
196 } else if (parent == null) {
197 return null;
198 } else {
199 @SuppressWarnings("unchecked")
200 N node = (N)this;
201 while (node.parent != null && node.parent.right == node) {
202 node = node.parent;
203 }
204 return node.parent;
205 }
206 }
207
208 /**
209 * Performs a left rotation about this node. This method assumes that !isLeaf() && !right.isLeaf(). It calls
210 * augment() on this node and on its resulting parent. However, it does not call augment() on any of the resulting
211 * parent's ancestors, because that is normally the responsibility of the caller.
212 * @return The return value from calling augment() on the resulting parent.
213 */
214 public boolean rotateLeft() {
215 if (isLeaf() || right.isLeaf()) {
216 throw new IllegalArgumentException("The node or its right child is a leaf");
217 }
218 N newParent = right;
219 right = newParent.left;
220 @SuppressWarnings("unchecked")
221 N nThis = (N)this;
222 if (!right.isLeaf()) {
223 right.parent = nThis;
224 }
225 newParent.parent = parent;
226 parent = newParent;
227 newParent.left = nThis;
228 if (newParent.parent != null) {
229 if (newParent.parent.left == this) {
230 newParent.parent.left = newParent;
231 } else {
232 newParent.parent.right = newParent;
233 }
234 }
235 augment();
236 return newParent.augment();
237 }
238
239 /**
240 * Performs a right rotation about this node. This method assumes that !isLeaf() && !left.isLeaf(). It calls
241 * augment() on this node and on its resulting parent. However, it does not call augment() on any of the resulting
242 * parent's ancestors, because that is normally the responsibility of the caller.
243 * @return The return value from calling augment() on the resulting parent.
244 */
245 public boolean rotateRight() {
246 if (isLeaf() || left.isLeaf()) {
247 throw new IllegalArgumentException("The node or its left child is a leaf");
248 }
249 N newParent = left;
250 left = newParent.right;
251 @SuppressWarnings("unchecked")
252 N nThis = (N)this;
253 if (!left.isLeaf()) {
254 left.parent = nThis;
255 }
256 newParent.parent = parent;
257 parent = newParent;
258 newParent.right = nThis;
259 if (newParent.parent != null) {
260 if (newParent.parent.left == this) {
261 newParent.parent.left = newParent;
262 } else {
263 newParent.parent.right = newParent;
264 }
265 }
266 augment();
267 return newParent.augment();
268 }
269
270 /**
271 * Performs red-black insertion fixup. To be more precise, this fixes a tree that satisfies all of the requirements
272 * of red-black trees, except that this may be a red child of a red node, and if this is the root, the root may be
273 * red. node.isRed must initially be true. This method assumes that this is not a leaf node. The method performs
274 * any rotations by calling rotateLeft() and rotateRight(). This method is more efficient than fixInsertion if
275 * "augment" is false or augment() might return false.
276 * @param augment Whether to set the augmentation information for "node" and its ancestors, by calling augment().
277 */
278 public void fixInsertionWithoutGettingRoot(boolean augment) {
279 if (!isRed) {
280 throw new IllegalArgumentException("The node must be red");
281 }
282 boolean changed = augment;
283 if (augment) {
284 augment();
285 }
286
287 RedBlackNode<N> node = this;
288 while (node.parent != null && node.parent.isRed) {
289 N parent = node.parent;
290 N grandparent = parent.parent;
291 if (grandparent.left.isRed && grandparent.right.isRed) {
292 grandparent.left.isRed = false;
293 grandparent.right.isRed = false;
294 grandparent.isRed = true;
295
296 if (changed) {
297 changed = parent.augment();
298 if (changed) {
299 changed = grandparent.augment();
300 }
301 }
302 node = grandparent;
303 } else {
304 if (parent.left == node) {
305 if (grandparent.right == parent) {
306 parent.rotateRight();
307 node = parent;
308 parent = node.parent;
309 }
310 } else if (grandparent.left == parent) {
311 parent.rotateLeft();
312 node = parent;
313 parent = node.parent;
314 }
315
316 if (parent.left == node) {
317 boolean grandparentChanged = grandparent.rotateRight();
318 if (augment) {
319 changed = grandparentChanged;
320 }
321 } else {
322 boolean grandparentChanged = grandparent.rotateLeft();
323 if (augment) {
324 changed = grandparentChanged;
325 }
326 }
327
328 parent.isRed = false;
329 grandparent.isRed = true;
330 node = parent;
331 break;
332 }
333 }
334
335 if (node.parent == null) {
336 node.isRed = false;
337 }
338 if (changed) {
339 for (node = node.parent; node != null; node = node.parent) {
340 if (!node.augment()) {
341 break;
342 }
343 }
344 }
345 }
346
347 /**
348 * Performs red-black insertion fixup. To be more precise, this fixes a tree that satisfies all of the requirements
349 * of red-black trees, except that this may be a red child of a red node, and if this is the root, the root may be
350 * red. node.isRed must initially be true. This method assumes that this is not a leaf node. The method performs
351 * any rotations by calling rotateLeft() and rotateRight(). This method is more efficient than fixInsertion() if
352 * augment() might return false.
353 */
354 public void fixInsertionWithoutGettingRoot() {
355 fixInsertionWithoutGettingRoot(true);
356 }
357
358 /**
359 * Performs red-black insertion fixup. To be more precise, this fixes a tree that satisfies all of the requirements
360 * of red-black trees, except that this may be a red child of a red node, and if this is the root, the root may be
361 * red. node.isRed must initially be true. This method assumes that this is not a leaf node. The method performs
362 * any rotations by calling rotateLeft() and rotateRight().
363 * @param augment Whether to set the augmentation information for "node" and its ancestors, by calling augment().
364 * @return The root of the resulting tree.
365 */
366 public N fixInsertion(boolean augment) {
367 fixInsertionWithoutGettingRoot(augment);
368 return root();
369 }
370
371 /**
372 * Performs red-black insertion fixup. To be more precise, this fixes a tree that satisfies all of the requirements
373 * of red-black trees, except that this may be a red child of a red node, and if this is the root, the root may be
374 * red. node.isRed must initially be true. This method assumes that this is not a leaf node. The method performs
375 * any rotations by calling rotateLeft() and rotateRight().
376 * @return The root of the resulting tree.
377 */
378 public N fixInsertion() {
379 fixInsertionWithoutGettingRoot(true);
380 return root();
381 }
382
383 /** Returns a Comparator that compares instances of N using their natural order, as in N.compareTo. */
384 @SuppressWarnings({"rawtypes", "unchecked"})
385 private Comparator<N> naturalOrder() {
386 Comparator comparator = (Comparator)NATURAL_ORDER;
387 return (Comparator<N>)comparator;
388 }
389
390 /**
391 * Inserts the specified node into the tree rooted at this node. Assumes this is the root. We treat newNode as a
392 * solitary node that does not belong to any tree, and we ignore its initial "parent", "left", "right", and isRed
393 * fields.
394 *
395 * If it is not efficient or convenient to find the location for a node using a Comparator, then you should manually
396 * add the node to the appropriate location, color it red, and call fixInsertion().
397 *
398 * @param newNode The node to insert.
399 * @param allowDuplicates Whether to insert newNode if there is an equal node in the tree. To check whether we
400 * inserted newNode, check whether newNode.parent is null and the return value differs from newNode.
401 * @param comparator A comparator indicating where to put the node. If this is null, we use the nodes' natural
402 * order, as in N.compareTo. If you are passing null, then you must override the compareTo method, because the
403 * default implementation requires the nodes to already be in the same tree.
404 * @return The root of the resulting tree.
405 */
406 public N insert(N newNode, boolean allowDuplicates, Comparator<? super N> comparator) {
407 if (parent != null) {
408 throw new IllegalArgumentException("This is not the root of a tree");
409 }
410 @SuppressWarnings("unchecked")
411 N nThis = (N)this;
412 if (isLeaf()) {
413 newNode.isRed = false;
414 newNode.left = nThis;
415 newNode.right = nThis;
416 newNode.parent = null;
417 newNode.augment();
418 return newNode;
419 }
420 if (comparator == null) {
421 comparator = naturalOrder();
422 }
423
424 N node = nThis;
425 int comparison;
426 while (true) {
427 comparison = comparator.compare(newNode, node);
428 if (comparison < 0) {
429 if (!node.left.isLeaf()) {
430 node = node.left;
431 } else {
432 newNode.left = node.left;
433 newNode.right = node.left;
434 node.left = newNode;
435 newNode.parent = node;
436 break;
437 }
438 } else if (comparison > 0 || allowDuplicates) {
439 if (!node.right.isLeaf()) {
440 node = node.right;
441 } else {
442 newNode.left = node.right;
443 newNode.right = node.right;
444 node.right = newNode;
445 newNode.parent = node;
446 break;
447 }
448 } else {
449 newNode.parent = null;
450 return nThis;
451 }
452 }
453 newNode.isRed = true;
454 return newNode.fixInsertion();
455 }
456
457 /**
458 * Moves this node to its successor's former position in the tree and vice versa, i.e. sets the "left", "right",
459 * "parent", and isRed fields of each. This method assumes that this is not a leaf node.
460 * @return The node with which we swapped.
461 */
462 private N swapWithSuccessor() {
463 N replacement = successor();
464 boolean oldReplacementIsRed = replacement.isRed;
465 N oldReplacementLeft = replacement.left;
466 N oldReplacementRight = replacement.right;
467 N oldReplacementParent = replacement.parent;
468
469 replacement.isRed = isRed;
470 replacement.left = left;
471 replacement.right = right;
472 replacement.parent = parent;
473 if (parent != null) {
474 if (parent.left == this) {
475 parent.left = replacement;
476 } else {
477 parent.right = replacement;
478 }
479 }
480
481 @SuppressWarnings("unchecked")
482 N nThis = (N)this;
483 isRed = oldReplacementIsRed;
484 left = oldReplacementLeft;
485 right = oldReplacementRight;
486 if (oldReplacementParent == this) {
487 parent = replacement;
488 parent.right = nThis;
489 } else {
490 parent = oldReplacementParent;
491 parent.left = nThis;
492 }
493
494 replacement.right.parent = replacement;
495 if (!replacement.left.isLeaf()) {
496 replacement.left.parent = replacement;
497 }
498 if (!right.isLeaf()) {
499 right.parent = nThis;
500 }
501 return replacement;
502 }
503
504 /**
505 * Performs red-black deletion fixup. To be more precise, this fixes a tree that satisfies all of the requirements
506 * of red-black trees, except that all paths from the root to a leaf that pass through the sibling of this node have
507 * one fewer black node than all other root-to-leaf paths. This method assumes that this is not a leaf node.
508 */
509 private void fixSiblingDeletion() {
510 RedBlackNode<N> sibling = this;
511 boolean changed = true;
512 boolean haveAugmentedParent = false;
513 boolean haveAugmentedGrandparent = false;
514 while (true) {
515 N parent = sibling.parent;
516 if (sibling.isRed) {
517 parent.isRed = true;
518 sibling.isRed = false;
519 if (parent.left == sibling) {
520 changed = parent.rotateRight();
521 sibling = parent.left;
522 } else {
523 changed = parent.rotateLeft();
524 sibling = parent.right;
525 }
526 haveAugmentedParent = true;
527 haveAugmentedGrandparent = true;
528 } else if (!sibling.left.isRed && !sibling.right.isRed) {
529 sibling.isRed = true;
530 if (parent.isRed) {
531 parent.isRed = false;
532 break;
533 } else {
534 if (changed && !haveAugmentedParent) {
535 changed = parent.augment();
536 }
537 N grandparent = parent.parent;
538 if (grandparent == null) {
539 break;
540 } else if (grandparent.left == parent) {
541 sibling = grandparent.right;
542 } else {
543 sibling = grandparent.left;
544 }
545 haveAugmentedParent = haveAugmentedGrandparent;
546 haveAugmentedGrandparent = false;
547 }
548 } else {
549 if (sibling == parent.left) {
550 if (!sibling.left.isRed) {
551 sibling.rotateLeft();
552 sibling = sibling.parent;
553 }
554 } else if (!sibling.right.isRed) {
555 sibling.rotateRight();
556 sibling = sibling.parent;
557 }
558 sibling.isRed = parent.isRed;
559 parent.isRed = false;
560 if (sibling == parent.left) {
561 sibling.left.isRed = false;
562 changed = parent.rotateRight();
563 } else {
564 sibling.right.isRed = false;
565 changed = parent.rotateLeft();
566 }
567 haveAugmentedParent = haveAugmentedGrandparent;
568 haveAugmentedGrandparent = false;
569 break;
570 }
571 }
572
573 // Update augmentation info
574 N parent = sibling.parent;
575 if (changed && parent != null) {
576 if (!haveAugmentedParent) {
577 changed = parent.augment();
578 }
579 if (changed && parent.parent != null) {
580 parent = parent.parent;
581 if (!haveAugmentedGrandparent) {
582 changed = parent.augment();
583 }
584 if (changed) {
585 for (parent = parent.parent; parent != null; parent = parent.parent) {
586 if (!parent.augment()) {
587 break;
588 }
589 }
590 }
591 }
592 }
593 }
594
595 /**
596 * Removes this node from the tree that contains it. The effect of this method on the fields of this node is
597 * unspecified. This method assumes that this is not a leaf node. This method is more efficient than remove() if
598 * augment() might return false.
599 *
600 * If the node has two children, we begin by moving the node's successor to its former position, by changing the
601 * successor's "left", "right", "parent", and isRed fields.
602 */
603 public void removeWithoutGettingRoot() {
604 if (isLeaf()) {
605 throw new IllegalArgumentException("Attempted to remove a leaf node");
606 }
607 N replacement;
608 if (left.isLeaf() || right.isLeaf()) {
609 replacement = null;
610 } else {
611 replacement = swapWithSuccessor();
612 }
613
614 N child;
615 if (!left.isLeaf()) {
616 child = left;
617 } else if (!right.isLeaf()) {
618 child = right;
619 } else {
620 child = null;
621 }
622
623 if (child != null) {
624 // Replace this node with its child
625 child.parent = parent;
626 if (parent != null) {
627 if (parent.left == this) {
628 parent.left = child;
629 } else {
630 parent.right = child;
631 }
632 }
633 child.isRed = false;
634
635 if (child.parent != null) {
636 N parent;
637 for (parent = child.parent; parent != null; parent = parent.parent) {
638 if (!parent.augment()) {
639 break;
640 }
641 }
642 }
643 } else if (parent != null) {
644 // Replace this node with a leaf node
645 N leaf = left;
646 N parent = this.parent;
647 N sibling;
648 if (parent.left == this) {
649 parent.left = leaf;
650 sibling = parent.right;
651 } else {
652 parent.right = leaf;
653 sibling = parent.left;
654 }
655
656 if (!isRed) {
657 RedBlackNode<N> siblingNode = sibling;
658 siblingNode.fixSiblingDeletion();
659 } else {
660 while (parent != null) {
661 if (!parent.augment()) {
662 break;
663 }
664 parent = parent.parent;
665 }
666 }
667 }
668
669 if (replacement != null) {
670 replacement.augment();
671 for (N parent = replacement.parent; parent != null; parent = parent.parent) {
672 if (!parent.augment()) {
673 break;
674 }
675 }
676 }
677
678 // Clear any previously existing links, so that we're more likely to encounter an exception if we attempt to
679 // access the removed node
680 parent = null;
681 left = null;
682 right = null;
683 isRed = true;
684 }
685
686 /**
687 * Removes this node from the tree that contains it. The effect of this method on the fields of this node is
688 * unspecified. This method assumes that this is not a leaf node.
689 *
690 * If the node has two children, we begin by moving the node's successor to its former position, by changing the
691 * successor's "left", "right", "parent", and isRed fields.
692 *
693 * @return The root of the resulting tree.
694 */
695 public N remove() {
696 if (isLeaf()) {
697 throw new IllegalArgumentException("Attempted to remove a leaf node");
698 }
699
700 // Find an arbitrary non-leaf node in the tree other than this node
701 N node;
702 if (parent != null) {
703 node = parent;
704 } else if (!left.isLeaf()) {
705 node = left;
706 } else if (!right.isLeaf()) {
707 node = right;
708 } else {
709 return left;
710 }
711
712 removeWithoutGettingRoot();
713 return node.root();
714 }
715
716 /**
717 * Returns the root of a perfectly height-balanced subtree containing the next "size" (non-leaf) nodes from
718 * "iterator", in iteration order. This method is responsible for setting the "left", "right", "parent", and isRed
719 * fields of the nodes, and calling augment() as appropriate. It ignores the initial values of the "left", "right",
720 * "parent", and isRed fields.
721 * @param iterator The nodes.
722 * @param size The number of nodes.
723 * @param height The "height" of the subtree's root node above the deepest leaf in the tree that contains it. Since
724 * insertion fixup is slow if there are too many red nodes and deleteion fixup is slow if there are too few red
725 * nodes, we compromise and have red nodes at every fourth level. We color a node red iff its "height" is equal
726 * to 1 mod 4.
727 * @param leaf The leaf node.
728 * @return The root of the subtree.
729 */
730 private static <N extends RedBlackNode<N>> N createTree(
731 Iterator<? extends N> iterator, int size, int height, N leaf) {
732 if (size == 0) {
733 return leaf;
734 } else {
735 N left = createTree(iterator, (size - 1) / 2, height - 1, leaf);
736 N node = iterator.next();
737 N right = createTree(iterator, size / 2, height - 1, leaf);
738
739 node.isRed = height % 4 == 1;
740 node.left = left;
741 node.right = right;
742 if (!left.isLeaf()) {
743 left.parent = node;
744 }
745 if (!right.isLeaf()) {
746 right.parent = node;
747 }
748
749 node.augment();
750 return node;
751 }
752 }
753
754 /**
755 * Returns the root of a perfectly height-balanced tree containing the specified nodes, in iteration order. This
756 * method is responsible for setting the "left", "right", "parent", and isRed fields of the nodes (excluding
757 * "leaf"), and calling augment() as appropriate. It ignores the initial values of the "left", "right", "parent",
758 * and isRed fields.
759 * @param nodes The nodes.
760 * @param leaf The leaf node.
761 * @return The root of the tree.
762 */
763 public static <N extends RedBlackNode<N>> N createTree(Collection<? extends N> nodes, N leaf) {
764 int size = nodes.size();
765 if (size == 0) {
766 return leaf;
767 }
768
769 int height = 0;
770 for (int subtreeSize = size; subtreeSize > 0; subtreeSize /= 2) {
771 height++;
772 }
773
774 N node = createTree(nodes.iterator(), size, height, leaf);
775 node.parent = null;
776 node.isRed = false;
777 return node;
778 }
779
780 /**
781 * Concatenates to the end of the tree rooted at this node. To be precise, given that all of the nodes in this
782 * precede the node "pivot", which precedes all of the nodes in "last", this returns the root of a tree containing
783 * all of these nodes. This method destroys the trees rooted at "this" and "last". We treat "pivot" as a solitary
784 * node that does not belong to any tree, and we ignore its initial "parent", "left", "right", and isRed fields.
785 * This method assumes that this node and "last" are the roots of their respective trees.
786 *
787 * This method takes O(log N) time. It is more efficient than inserting "pivot" and then calling concatenate(last).
788 * It is considerably more efficient than inserting "pivot" and all of the nodes in "last".
789 */
790 public N concatenate(N last, N pivot) {
791 // If the black height of "first", where first = this, is less than or equal to that of "last", starting at the
792 // root of "last", we keep going left until we reach a black node whose black height is equal to that of
793 // "first". Then, we make "pivot" the parent of that node and of "first", coloring it red, and perform
794 // insertion fixup on the pivot. If the black height of "first" is greater than that of "last", we do the
795 // mirror image of the above.
796
797 if (parent != null) {
798 throw new IllegalArgumentException("This is not the root of a tree");
799 }
800 if (last.parent != null) {
801 throw new IllegalArgumentException("\"last\" is not the root of a tree");
802 }
803
804 // Compute the black height of the trees
805 int firstBlackHeight = 0;
806 @SuppressWarnings("unchecked")
807 N first = (N)this;
808 for (N node = first; node != null; node = node.right) {
809 if (!node.isRed) {
810 firstBlackHeight++;
811 }
812 }
813 int lastBlackHeight = 0;
814 for (N node = last; node != null; node = node.right) {
815 if (!node.isRed) {
816 lastBlackHeight++;
817 }
818 }
819
820 // Identify the children and parent of pivot
821 N firstChild = first;
822 N lastChild = last;
823 N parent;
824 if (firstBlackHeight <= lastBlackHeight) {
825 parent = null;
826 int blackHeight = lastBlackHeight;
827 while (blackHeight > firstBlackHeight) {
828 if (!lastChild.isRed) {
829 blackHeight--;
830 }
831 parent = lastChild;
832 lastChild = lastChild.left;
833 }
834 if (lastChild.isRed) {
835 parent = lastChild;
836 lastChild = lastChild.left;
837 }
838 } else {
839 parent = null;
840 int blackHeight = firstBlackHeight;
841 while (blackHeight > lastBlackHeight) {
842 if (!firstChild.isRed) {
843 blackHeight--;
844 }
845 parent = firstChild;
846 firstChild = firstChild.right;
847 }
848 if (firstChild.isRed) {
849 parent = firstChild;
850 firstChild = firstChild.right;
851 }
852 }
853
854 // Add "pivot" to the tree
855 pivot.isRed = true;
856 pivot.parent = parent;
857 if (parent != null) {
858 if (firstBlackHeight < lastBlackHeight) {
859 parent.left = pivot;
860 } else {
861 parent.right = pivot;
862 }
863 }
864 pivot.left = firstChild;
865 if (!firstChild.isLeaf()) {
866 firstChild.parent = pivot;
867 }
868 pivot.right = lastChild;
869 if (!lastChild.isLeaf()) {
870 lastChild.parent = pivot;
871 }
872
873 // Perform insertion fixup
874 return pivot.fixInsertion();
875 }
876
877 /**
878 * Concatenates the tree rooted at "last" to the end of the tree rooted at this node. To be precise, given that all
879 * of the nodes in this precede all of the nodes in "last", this returns the root of a tree containing all of these
880 * nodes. This method destroys the trees rooted at "this" and "last". It assumes that this node and "last" are the
881 * roots of their respective trees. This method takes O(log N) time. It is considerably more efficient than
882 * inserting all of the nodes in "last".
883 */
884 public N concatenate(N last) {
885 if (parent != null || last.parent != null) {
886 throw new IllegalArgumentException("The node is not the root of a tree");
887 }
888 if (isLeaf()) {
889 return last;
890 } else if (last.isLeaf()) {
891 @SuppressWarnings("unchecked")
892 N nThis = (N)this;
893 return nThis;
894 } else {
895 N node = last.min();
896 last = node.remove();
897 return concatenate(last, node);
898 }
899 }
900
901 /**
902 * Splits the tree rooted at this node into two trees, so that the first element of the return value is the root of
903 * a tree consisting of the nodes that were before the specified node, and the second element of the return value is
904 * the root of a tree consisting of the nodes that were equal to or after the specified node. This method is
905 * destructive, meaning it does not preserve the original tree. It assumes that this node is the root and is in the
906 * same tree as splitNode. It takes O(log N) time. It is considerably more efficient than removing all of the
907 * nodes at or after splitNode and then creating a new tree from those nodes.
908 * @param The node at which to split the tree.
909 * @return An array consisting of the resulting trees.
910 */
911 public N[] split(N splitNode) {
912 // To split the tree, we accumulate a pre-split tree and a post-split tree. We walk down the tree toward the
913 // position where we are splitting. Whenever we go left, we concatenate the right subtree with the post-split
914 // tree, and whenever we go right, we concatenate the pre-split tree with the left subtree. We use the
915 // concatenation algorithm described in concatenate(Object, Object). For the pivot, we use the last node where
916 // we went left in the case of a left move, and the last node where we went right in the case of a right move.
917 //
918 // The method uses the following variables:
919 //
920 // node: The current node in our walk down the tree.
921 // first: A node on the right spine of the pre-split tree. At the beginning of each iteration, it is the black
922 // node with the same black height as "node". If the pre-split tree is empty, this is null instead.
923 // firstParent: The parent of "first". If the pre-split tree is empty, this is null. Otherwise, this is the
924 // same as first.parent, unless first.isLeaf().
925 // firstPivot: The node where we last went right, i.e. the next node to use as a pivot when concatenating with
926 // the pre-split tree.
927 // advanceFirst: Whether to set "first" to be its next black descendant at the end of the loop.
928 // last, lastParent, lastPivot, advanceLast: Analogous to "first", firstParent, firstPivot, and advanceFirst,
929 // but for the post-split tree.
930 if (parent != null) {
931 throw new IllegalArgumentException("This is not the root of a tree");
932 }
933 if (isLeaf() || splitNode.isLeaf()) {
934 throw new IllegalArgumentException("The root or the split node is a leaf");
935 }
936
937 // Create an array containing the path from the root to splitNode
938 int depth = 1;
939 N parent;
940 for (parent = splitNode; parent.parent != null; parent = parent.parent) {
941 depth++;
942 }
943 if (parent != this) {
944 throw new IllegalArgumentException("The split node does not belong to this tree");
945 }
946 RedBlackNode<?>[] path = new RedBlackNode<?>[depth];
947 for (parent = splitNode; parent != null; parent = parent.parent) {
948 depth--;
949 path[depth] = parent;
950 }
951
952 @SuppressWarnings("unchecked")
953 N node = (N)this;
954 N first = null;
955 N firstParent = null;
956 N last = null;
957 N lastParent = null;
958 N firstPivot = null;
959 N lastPivot = null;
960 while (!node.isLeaf()) {
961 boolean advanceFirst = !node.isRed && firstPivot != null;
962 boolean advanceLast = !node.isRed && lastPivot != null;
963 if ((depth + 1 < path.length && path[depth + 1] == node.left) || depth + 1 == path.length) {
964 // Left move
965 if (lastPivot == null) {
966 // The post-split tree is empty
967 last = node.right;
968 last.parent = null;
969 if (last.isRed) {
970 last.isRed = false;
971 lastParent = last;
972 last = last.left;
973 }
974 } else {
975 // Concatenate node.right and the post-split tree
976 if (node.right.isRed) {
977 node.right.isRed = false;
978 } else if (!node.isRed) {
979 lastParent = last;
980 last = last.left;
981 if (last.isRed) {
982 lastParent = last;
983 last = last.left;
984 }
985 advanceLast = false;
986 }
987 lastPivot.isRed = true;
988 lastPivot.parent = lastParent;
989 if (lastParent != null) {
990 lastParent.left = lastPivot;
991 }
992 lastPivot.left = node.right;
993 if (!lastPivot.left.isLeaf()) {
994 lastPivot.left.parent = lastPivot;
995 }
996 lastPivot.right = last;
997 if (!last.isLeaf()) {
998 last.parent = lastPivot;
999 }
1000 last = lastPivot.left;
1001 lastParent = lastPivot;
1002 lastPivot.fixInsertionWithoutGettingRoot(false);
1003 }
1004 lastPivot = node;
1005 node = node.left;
1006 } else {
1007 // Right move
1008 if (firstPivot == null) {
1009 // The pre-split tree is empty
1010 first = node.left;
1011 first.parent = null;
1012 if (first.isRed) {
1013 first.isRed = false;
1014 firstParent = first;
1015 first = first.right;
1016 }
1017 } else {
1018 // Concatenate the post-split tree and node.left
1019 if (node.left.isRed) {
1020 node.left.isRed = false;
1021 } else if (!node.isRed) {
1022 firstParent = first;
1023 first = first.right;
1024 if (first.isRed) {
1025 firstParent = first;
1026 first = first.right;
1027 }
1028 advanceFirst = false;
1029 }
1030 firstPivot.isRed = true;
1031 firstPivot.parent = firstParent;
1032 if (firstParent != null) {
1033 firstParent.right = firstPivot;
1034 }
1035 firstPivot.right = node.left;
1036 if (!firstPivot.right.isLeaf()) {
1037 firstPivot.right.parent = firstPivot;
1038 }
1039 firstPivot.left = first;
1040 if (!first.isLeaf()) {
1041 first.parent = firstPivot;
1042 }
1043 first = firstPivot.right;
1044 firstParent = firstPivot;
1045 firstPivot.fixInsertionWithoutGettingRoot(false);
1046 }
1047 firstPivot = node;
1048 node = node.right;
1049 }
1050
1051 depth++;
1052
1053 // Update "first" and "last" to be the nodes at the proper black height
1054 if (advanceFirst) {
1055 firstParent = first;
1056 first = first.right;
1057 if (first.isRed) {
1058 firstParent = first;
1059 first = first.right;
1060 }
1061 }
1062 if (advanceLast) {
1063 lastParent = last;
1064 last = last.left;
1065 if (last.isRed) {
1066 lastParent = last;
1067 last = last.left;
1068 }
1069 }
1070 }
1071
1072 // Add firstPivot to the pre-split tree
1073 N leaf = node;
1074 if (first == null) {
1075 first = leaf;
1076 } else {
1077 firstPivot.isRed = true;
1078 firstPivot.parent = firstParent;
1079 if (firstParent != null) {
1080 firstParent.right = firstPivot;
1081 }
1082 firstPivot.left = leaf;
1083 firstPivot.right = leaf;
1084 firstPivot.fixInsertionWithoutGettingRoot(false);
1085 for (first = firstPivot; first.parent != null; first = first.parent) {
1086 first.augment();
1087 }
1088 first.augment();
1089 }
1090
1091 // Add lastPivot to the post-split tree
1092 lastPivot.isRed = true;
1093 lastPivot.parent = lastParent;
1094 if (lastParent != null) {
1095 lastParent.left = lastPivot;
1096 }
1097 lastPivot.left = leaf;
1098 lastPivot.right = leaf;
1099 lastPivot.fixInsertionWithoutGettingRoot(false);
1100 for (last = lastPivot; last.parent != null; last = last.parent) {
1101 last.augment();
1102 }
1103 last.augment();
1104
1105 @SuppressWarnings("unchecked")
1106 N[] result = (N[])Array.newInstance(getClass(), 2);
1107 result[0] = first;
1108 result[1] = last;
1109 return result;
1110 }
1111
1112 /**
1113 * Returns the lowest common ancestor of this node and "other" - the node that is an ancestor of both and is not the
1114 * parent of a node that is an ancestor of both. Assumes that this is in the same tree as "other". Assumes that
1115 * neither "this" nor "other" is a leaf node. This method may return "this" or "other".
1116 *
1117 * Note that while it is possible to compute the lowest common ancestor in O(P) time, where P is the length of the
1118 * path from this node to "other", the "lca" method is not guaranteed to take O(P) time. If your application
1119 * requires this, then you should write your own lowest common ancestor method.
1120 */
1121 public N lca(N other) {
1122 if (isLeaf() || other.isLeaf()) {
1123 throw new IllegalArgumentException("One of the nodes is a leaf node");
1124 }
1125
1126 // Compute the depth of each node
1127 int depth = 0;
1128 for (N parent = this.parent; parent != null; parent = parent.parent) {
1129 depth++;
1130 }
1131 int otherDepth = 0;
1132 for (N parent = other.parent; parent != null; parent = parent.parent) {
1133 otherDepth++;
1134 }
1135
1136 // Go up to nodes of the same depth
1137 @SuppressWarnings("unchecked")
1138 N parent = (N)this;
1139 N otherParent = other;
1140 if (depth <= otherDepth) {
1141 for (int i = otherDepth; i > depth; i--) {
1142 otherParent = otherParent.parent;
1143 }
1144 } else {
1145 for (int i = depth; i > otherDepth; i--) {
1146 parent = parent.parent;
1147 }
1148 }
1149
1150 // Find the LCA
1151 while (parent != otherParent) {
1152 parent = parent.parent;
1153 otherParent = otherParent.parent;
1154 }
1155 if (parent != null) {
1156 return parent;
1157 } else {
1158 throw new IllegalArgumentException("The nodes do not belong to the same tree");
1159 }
1160 }
1161
1162 /**
1163 * Returns an integer comparing the position of this node in the tree that contains it with that of "other". Returns
1164 * a negative number if this is earlier, a positive number if this is later, and 0 if this is at the same position.
1165 * Assumes that this is in the same tree as "other". Assumes that neither "this" nor "other" is a leaf node.
1166 *
1167 * The base class's implementation takes O(log N) time. If a RedBlackNode subclass stores a value used to order the
1168 * nodes, then it could override compareTo to compare the nodes' values, which would take O(1) time.
1169 *
1170 * Note that while it is possible to compare the positions of two nodes in O(P) time, where P is the length of the
1171 * path from this node to "other", the default implementation of compareTo is not guaranteed to take O(P) time. If
1172 * your application requires this, then you should write your own comparison method.
1173 */
1174 @Override
1175 public int compareTo(N other) {
1176 if (isLeaf() || other.isLeaf()) {
1177 throw new IllegalArgumentException("One of the nodes is a leaf node");
1178 }
1179
1180 // The algorithm operates as follows: compare the depth of this node to that of "other". If the depth of
1181 // "other" is greater, keep moving up from "other" until we find the ancestor at the same depth. Then, keep
1182 // moving up from "this" and from that node until we reach the lowest common ancestor. The node that arrived
1183 // from the left child of the common ancestor is earlier. The algorithm is analogous if the depth of "other" is
1184 // not greater.
1185 if (this == other) {
1186 return 0;
1187 }
1188
1189 // Compute the depth of each node
1190 int depth = 0;
1191 RedBlackNode<N> parent;
1192 for (parent = this; parent.parent != null; parent = parent.parent) {
1193 depth++;
1194 }
1195 int otherDepth = 0;
1196 N otherParent;
1197 for (otherParent = other; otherParent.parent != null; otherParent = otherParent.parent) {
1198 otherDepth++;
1199 }
1200
1201 // Go up to nodes of the same depth
1202 if (depth < otherDepth) {
1203 otherParent = other;
1204 for (int i = otherDepth - 1; i > depth; i--) {
1205 otherParent = otherParent.parent;
1206 }
1207 if (otherParent.parent != this) {
1208 otherParent = otherParent.parent;
1209 } else if (left == otherParent) {
1210 return 1;
1211 } else {
1212 return -1;
1213 }
1214 parent = this;
1215 } else if (depth > otherDepth) {
1216 parent = this;
1217 for (int i = depth - 1; i > otherDepth; i--) {
1218 parent = parent.parent;
1219 }
1220 if (parent.parent != other) {
1221 parent = parent.parent;
1222 } else if (other.left == parent) {
1223 return -1;
1224 } else {
1225 return 1;
1226 }
1227 otherParent = other;
1228 } else {
1229 parent = this;
1230 otherParent = other;
1231 }
1232
1233 // Keep going up until we reach the lowest common ancestor
1234 while (parent.parent != otherParent.parent) {
1235 parent = parent.parent;
1236 otherParent = otherParent.parent;
1237 }
1238 if (parent.parent == null) {
1239 throw new IllegalArgumentException("The nodes do not belong to the same tree");
1240 }
1241 if (parent.parent.left == parent) {
1242 return -1;
1243 } else {
1244 return 1;
1245 }
1246 }
1247
1248 /** Throws a RuntimeException if the RedBlackNode fields of this are not correct for a leaf node. */
1249 private void assertIsValidLeaf() {
1250 if (left != null || right != null || parent != null || isRed) {
1251 throw new RuntimeException("A leaf node's \"left\", \"right\", \"parent\", or isRed field is incorrect");
1252 }
1253 }
1254
1255 /**
1256 * Throws a RuntimeException if the subtree rooted at this node does not satisfy the red-black properties, excluding
1257 * the requirement that the root be black, or it contains a repeated node other than a leaf node.
1258 * @param blackHeight The required number of black nodes in each path from this to a leaf node, including this and
1259 * the leaf node.
1260 * @param visited The nodes we have reached thus far, other than leaf nodes. This method adds the non-leaf nodes in
1261 * the subtree rooted at this node to "visited".
1262 */
1263 private void assertSubtreeIsValidRedBlack(int blackHeight, Set<Reference<N>> visited) {
1264 @SuppressWarnings("unchecked")
1265 N nThis = (N)this;
1266 if (left == null || right == null) {
1267 assertIsValidLeaf();
1268 if (blackHeight != 1) {
1269 throw new RuntimeException("Not all root-to-leaf paths have the same number of black nodes");
1270 }
1271 return;
1272 } else if (!visited.add(new Reference<N>(nThis))) {
1273 throw new RuntimeException("The tree contains a repeated non-leaf node");
1274 } else {
1275 int childBlackHeight;
1276 if (isRed) {
1277 if ((!left.isLeaf() && left.isRed) || (!right.isLeaf() && right.isRed)) {
1278 throw new RuntimeException("A red node has a red child");
1279 }
1280 childBlackHeight = blackHeight;
1281 } else if (blackHeight == 0) {
1282 throw new RuntimeException("Not all root-to-leaf paths have the same number of black nodes");
1283 } else {
1284 childBlackHeight = blackHeight - 1;
1285 }
1286
1287 if (!left.isLeaf() && left.parent != this) {
1288 throw new RuntimeException("left.parent != this");
1289 }
1290 if (!right.isLeaf() && right.parent != this) {
1291 throw new RuntimeException("right.parent != this");
1292 }
1293 RedBlackNode<N> leftNode = left;
1294 RedBlackNode<N> rightNode = right;
1295 leftNode.assertSubtreeIsValidRedBlack(childBlackHeight, visited);
1296 rightNode.assertSubtreeIsValidRedBlack(childBlackHeight, visited);
1297 }
1298 }
1299
1300 /** Calls assertNodeIsValid() on every node in the subtree rooted at this node. */
1301 private void assertNodesAreValid() {
1302 assertNodeIsValid();
1303 if (left != null) {
1304 RedBlackNode<N> leftNode = left;
1305 RedBlackNode<N> rightNode = right;
1306 leftNode.assertNodesAreValid();
1307 rightNode.assertNodesAreValid();
1308 }
1309 }
1310
1311 /**
1312 * Throws a RuntimeException if the subtree rooted at this node is not a valid red-black tree, e.g. if a red node
1313 * has a red child or it contains a non-leaf node "node" for which node.left.parent != node. (If parent != null,
1314 * it's okay if isRed is true.) This method is useful for debugging. See also assertSubtreeIsValid().
1315 */
1316 public void assertSubtreeIsValidRedBlack() {
1317 if (isLeaf()) {
1318 assertIsValidLeaf();
1319 } else {
1320 if (parent == null && isRed) {
1321 throw new RuntimeException("The root is red");
1322 }
1323
1324 // Compute the black height of the tree
1325 Set<Reference<N>> nodes = new HashSet<Reference<N>>();
1326 int blackHeight = 0;
1327 @SuppressWarnings("unchecked")
1328 N node = (N)this;
1329 while (node != null) {
1330 if (!nodes.add(new Reference<N>(node))) {
1331 throw new RuntimeException("The tree contains a repeated non-leaf node");
1332 }
1333 if (!node.isRed) {
1334 blackHeight++;
1335 }
1336 node = node.left;
1337 }
1338
1339 assertSubtreeIsValidRedBlack(blackHeight, new HashSet<Reference<N>>());
1340 }
1341 }
1342
1343 /**
1344 * Throws a RuntimeException if we detect a problem with the subtree rooted at this node, such as a red child of a
1345 * red node or a non-leaf descendant "node" for which node.left.parent != node. This method is useful for
1346 * debugging. RedBlackNode subclasses may want to override assertSubtreeIsValid() to call assertOrderIsValid.
1347 */
1348 public void assertSubtreeIsValid() {
1349 assertSubtreeIsValidRedBlack();
1350 assertNodesAreValid();
1351 }
1352
1353 /**
1354 * Throws a RuntimeException if the nodes in the subtree rooted at this node are not in the specified order or they
1355 * do not lie in the specified range. Assumes that the subtree rooted at this node is a valid binary tree, i.e. it
1356 * has no repeated nodes other than leaf nodes.
1357 * @param comparator A comparator indicating how the nodes should be ordered.
1358 * @param start The lower limit for nodes in the subtree, if any.
1359 * @param end The upper limit for nodes in the subtree, if any.
1360 */
1361 private void assertOrderIsValid(Comparator<? super N> comparator, N start, N end) {
1362 if (!isLeaf()) {
1363 @SuppressWarnings("unchecked")
1364 N nThis = (N)this;
1365 if (start != null && comparator.compare(nThis, start) < 0) {
1366 throw new RuntimeException("The nodes are not ordered correctly");
1367 }
1368 if (end != null && comparator.compare(nThis, end) > 0) {
1369 throw new RuntimeException("The nodes are not ordered correctly");
1370 }
1371 RedBlackNode<N> leftNode = left;
1372 RedBlackNode<N> rightNode = right;
1373 leftNode.assertOrderIsValid(comparator, start, nThis);
1374 rightNode.assertOrderIsValid(comparator, nThis, end);
1375 }
1376 }
1377
1378 /**
1379 * Throws a RuntimeException if the nodes in the subtree rooted at this node are not in the specified order.
1380 * Assumes that this is a valid binary tree, i.e. there are no repeated nodes other than leaf nodes. This method is
1381 * useful for debugging. RedBlackNode subclasses may want to override assertSubtreeIsValid() to call
1382 * assertOrderIsValid.
1383 * @param comparator A comparator indicating how the nodes should be ordered. If this is null, we use the nodes'
1384 * natural order, as in N.compareTo.
1385 */
1386 public void assertOrderIsValid(Comparator<? super N> comparator) {
1387 if (comparator == null) {
1388 comparator = naturalOrder();
1389 }
1390 assertOrderIsValid(comparator, null, null);
1391 }
1392}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/Reference.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/Reference.java
new file mode 100644
index 00000000..a25c167d
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/Reference.java
@@ -0,0 +1,51 @@
1/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2016 btrekkie
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval;
25
26/**
27 * Wraps a value using reference equality. In other words, two references are equal only if their values are the same
28 * object instance, as in ==.
29 * @param <T> The type of value.
30 */
31class Reference<T> {
32 /** The value this wraps. */
33 private final T value;
34
35 public Reference(T value) {
36 this.value = value;
37 }
38
39 public boolean equals(Object obj) {
40 if (!(obj instanceof Reference)) {
41 return false;
42 }
43 Reference<?> reference = (Reference<?>)obj;
44 return value == reference.value;
45 }
46
47 @Override
48 public int hashCode() {
49 return System.identityHashCode(value);
50 }
51}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/aggregators/IntervalAggregatorFactory.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/aggregators/IntervalAggregatorFactory.xtend
new file mode 100644
index 00000000..dee31f67
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/aggregators/IntervalAggregatorFactory.xtend
@@ -0,0 +1,50 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval.aggregators
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval.Interval
4import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval.IntervalAggregationMode
5import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval.IntervalAggregationOperator
6import org.eclipse.viatra.query.runtime.matchers.psystem.aggregations.AggregatorType
7import org.eclipse.viatra.query.runtime.matchers.psystem.aggregations.BoundAggregator
8import org.eclipse.viatra.query.runtime.matchers.psystem.aggregations.IAggregatorFactory
9import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
10
11@AggregatorType(parameterTypes=#[Interval], returnTypes=#[Interval])
12abstract class IntervalAggregatorFactory implements IAggregatorFactory {
13 val IntervalAggregationMode mode
14
15 @FinalFieldsConstructor
16 protected new() {
17 }
18
19 override getAggregatorLogic(Class<?> domainClass) {
20 if (domainClass == Interval) {
21 new BoundAggregator(new IntervalAggregationOperator(mode), Interval, Interval)
22 } else {
23 throw new IllegalArgumentException("Unknown domain class: " + domainClass)
24 }
25 }
26}
27
28class intervalSum extends IntervalAggregatorFactory {
29 new() {
30 super(IntervalAggregationMode.SUM)
31 }
32}
33
34class intervalMin extends IntervalAggregatorFactory {
35 new() {
36 super(IntervalAggregationMode.MIN)
37 }
38}
39
40class intervalMax extends IntervalAggregatorFactory {
41 new() {
42 super(IntervalAggregationMode.MAX)
43 }
44}
45
46class intervalJoin extends IntervalAggregatorFactory {
47 new() {
48 super(IntervalAggregationMode.JOIN)
49 }
50}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/aggregators/intervalHull.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/aggregators/intervalHull.xtend
new file mode 100644
index 00000000..72605f57
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/aggregators/intervalHull.xtend
@@ -0,0 +1,74 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval.aggregators
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval.Interval
4import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.interval.IntervalHullAggregatorOperator
5import java.math.BigDecimal
6import java.math.BigInteger
7import java.math.MathContext
8import org.eclipse.viatra.query.runtime.matchers.psystem.aggregations.AggregatorType
9import org.eclipse.viatra.query.runtime.matchers.psystem.aggregations.BoundAggregator
10import org.eclipse.viatra.query.runtime.matchers.psystem.aggregations.IAggregatorFactory
11
12@AggregatorType(parameterTypes=#[BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short], returnTypes=#[
13 Interval, Interval, Interval, Interval, Interval, Interval, Interval, Interval])
14class intervalHull implements IAggregatorFactory {
15
16 override getAggregatorLogic(Class<?> domainClass) {
17 new BoundAggregator(getAggregationOperator(domainClass), domainClass, Interval)
18 }
19
20 private def getAggregationOperator(Class<?> domainClass) {
21 switch (domainClass) {
22 case BigDecimal:
23 new IntervalHullAggregatorOperator<BigDecimal>() {
24 override protected toBigDecimal(BigDecimal value, MathContext mc) {
25 value.round(mc)
26 }
27 }
28 case BigInteger:
29 new IntervalHullAggregatorOperator<BigInteger>() {
30 override protected toBigDecimal(BigInteger value, MathContext mc) {
31 new BigDecimal(value, mc)
32 }
33 }
34 case Byte:
35 new IntervalHullAggregatorOperator<Byte>() {
36 override protected toBigDecimal(Byte value, MathContext mc) {
37 new BigDecimal(value, mc)
38 }
39 }
40 case Double:
41 new IntervalHullAggregatorOperator<Double>() {
42 override protected toBigDecimal(Double value, MathContext mc) {
43 new BigDecimal(value, mc)
44 }
45 }
46 case Float:
47 new IntervalHullAggregatorOperator<Float>() {
48 override protected toBigDecimal(Float value, MathContext mc) {
49 new BigDecimal(value, mc)
50 }
51 }
52 case Integer:
53 new IntervalHullAggregatorOperator<Integer>() {
54 override protected toBigDecimal(Integer value, MathContext mc) {
55 new BigDecimal(value, mc)
56 }
57 }
58 case Long:
59 new IntervalHullAggregatorOperator<Long>() {
60 override protected toBigDecimal(Long value, MathContext mc) {
61 new BigDecimal(value, mc)
62 }
63 }
64 case Short:
65 new IntervalHullAggregatorOperator<Short>() {
66 override protected toBigDecimal(Short value, MathContext mc) {
67 new BigDecimal(value, mc)
68 }
69 }
70 default:
71 throw new IllegalArgumentException("Unknown domain class: " + domainClass)
72 }
73 }
74}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/GenericTypeIndexer.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/GenericTypeIndexer.xtend
index d6a15c1a..0e0f1f02 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/GenericTypeIndexer.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/GenericTypeIndexer.xtend
@@ -1,209 +1,150 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns 1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns
2 2
3import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type 3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
5import org.eclipse.emf.ecore.EClass 4import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
6import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality 5import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeAnalysisResult 6import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeAnalysisResult
9 7
10class GenericTypeIndexer extends TypeIndexer { 8class GenericTypeIndexer extends TypeIndexer {
11 val PatternGenerator base;
12
13 new(PatternGenerator base) { 9 new(PatternGenerator base) {
14 this.base = base 10 super(base)
15 } 11 }
12
16 override requiresTypeAnalysis() { false } 13 override requiresTypeAnalysis() { false }
17 14
18 public override getRequiredQueries() ''' 15 override getRequiredQueries() '''
19 private pattern newELement(interpretation: PartialInterpretation, element: DefinedElement) { 16 «super.requiredQueries»
20 PartialInterpretation.newElements(interpretation,element); 17
21 } 18 /**
22 19 * Direct supertypes of a type.
23 private pattern typeInterpretation(problem:LogicProblem, interpetation:PartialInterpretation, type:TypeDeclaration, typeInterpretation:PartialComplexTypeInterpretation) { 20 */
24 find interpretation(problem,interpetation); 21 private pattern supertypeDirect(subtype : Type, supertype : Type) {
25 LogicProblem.types(problem,type); 22 Type.supertypes(subtype, supertype);
26 PartialInterpretation.partialtypeinterpratation(interpetation,typeInterpretation); 23 }
27 PartialComplexTypeInterpretation.interpretationOf(typeInterpretation,type); 24
28 } 25 /**
29 26 * All supertypes of a type.
30 private pattern directInstanceOf(problem:LogicProblem, interpetation:PartialInterpretation, element:DefinedElement, type:Type) { 27 */
31 find interpretation(problem,interpetation); 28 private pattern supertypeStar(subtype: Type, supertype: Type) {
32 find mustExist(problem,interpetation,element); 29 subtype == supertype;
33 LogicProblem.types(problem,type); 30 } or {
34 TypeDefinition.elements(type,element); 31 find supertypeDirect+(subtype,supertype);
35 } or { 32 }
36 find mustExist(problem,interpetation,element); 33
37 find typeInterpretation(problem,interpetation,type,typeInterpretation); 34 /// Complex type reasoning patterns ///
38 PartialComplexTypeInterpretation.elements(typeInterpretation,element); 35 //
39 } 36 // In a valid type system, for each element e there is exactly one type T where
40 37 // 1: T(e) - but we dont know this for type declaration
41 /** 38 // 2: For the dynamic type D and another type T, where D(e) && D-->T, T(e) is true.
42 * Direct supertypes of a type. 39 // 2e: A type hierarchy is invalid, if there is a supertype T for a dynamic type D which does no contains e:
43 */ 40 // D(e) && D-->T && !T(e)
44 private pattern supertypeDirect(subtype : Type, supertype : Type) { 41 // 3: There is no T' that T'->T and T'(e)
45 Type.supertypes(subtype, supertype); 42 // 3e: A type hierarcy is invalid, if there is a type T for a dynamic type D, which contains e, but not subtype of T:
46 } 43 // D(e) && ![T--->D] && T(e)
47
48 /**
49 * All supertypes of a type.
50 */
51 private pattern supertypeStar(subtype: Type, supertype: Type) {
52 subtype == supertype;
53 } or {
54 find supertypeDirect+(subtype,supertype);
55 }
56
57 /// Complex type reasoning patterns ///
58 //
59 // In a valid type system, for each element e there is exactly one type T where
60 // 1: T(e) - but we dont know this for type declaration
61 // 2: For the dynamic type D and another type T, where D(e) && D-->T, T(e) is true.
62 // 2e: A type hierarchy is invalid, if there is a supertype T for a dynamic type D which does no contains e:
63 // D(e) && D-->T && !T(e)
64 // 3: There is no T' that T'->T and T'(e)
65 // 3e: A type hierarcy is invalid, if there is a type T for a dynamic type D, which contains e, but not subtype of T:
66 // D(e) && ![T--->D] && T(e)
67 // 4: T is not abstract
68 // Such type T is called Dynamic type of e, while other types are called static types.
69 //
70 // The following patterns checks the possible dynamic types for an element
71
72 private pattern wellformedType(problem: LogicProblem, interpretation:PartialInterpretation, dynamic:Type, element:DefinedElement) {
73 // 1: T(e)
74 find directInstanceOf(problem,interpretation,element,dynamic);
75 // 2e is not true: D(e) && D-->T && !T(e)
76 neg find dynamicTypeNotSubtypeOfADefinition(problem,interpretation,element,dynamic);
77 // 3e is not true: D(e) && ![T--->D] && T(e)
78 neg find dynamicTypeIsSubtypeOfANonDefinition(problem,interpretation,element,dynamic);
79 // 4: T is not abstract
80 Type.isAbstract(dynamic,false);
81 }
82
83
84 private pattern isPrimitive(element: PrimitiveElement) {
85 PrimitiveElement(element);
86 }
87
88 private pattern possibleDynamicType(problem: LogicProblem, interpretation:PartialInterpretation, dynamic:Type, element:DefinedElement)
89 // case 1: element is defined at least once
90 {
91 LogicProblem.types(problem,dynamic);
92 // select a random definition 'randomType'
93 find directInstanceOf(problem,interpretation,element,randomType);
94 // dynamic is a subtype of 'randomType'
95 find supertypeStar(dynamic,randomType);
96 // 2e is not true: D(e) && D-->T && !T(e)
97 neg find dynamicTypeNotSubtypeOfADefinition(problem,interpretation,element,dynamic);
98 // 3e is not true: D(e) && ![T--->D] && T(e)
99 neg find dynamicTypeIsSubtypeOfANonDefinition(problem,interpretation,element,dynamic);
100 // 4: T is not abstract
101 Type.isAbstract(dynamic,false);
102 // 5. element is not primitive datatype
103 neg find isPrimitive(element);
104 } or
105 // case 2: element is not defined anywhere
106 {
107 find mayExist(problem,interpretation,element);
108 // there is no definition
109 neg find directInstanceOf(problem,interpretation,element,_);
110 // 2e is not true: D(e) && D-->T && !T(e)
111 // because non of the definition contains element, the type cannot have defined supertype
112 LogicProblem.types(problem,dynamic);
113 PartialInterpretation.problem(interpretation,problem);
114 neg find typeWithDefinedSupertype(dynamic);
115 // 3e is not true: D(e) && ![T--->D] && T(e)
116 // because there is no definition, dynamic covers all definition
117 // 4: T is not abstract 44 // 4: T is not abstract
118 Type.isAbstract(dynamic,false); 45 // Such type T is called Dynamic type of e, while other types are called static types.
119 // 5. element is not primitive datatype 46 //
120 neg find isPrimitive(element); 47 // The following patterns checks the possible dynamic types for an element
121 } 48
122 49 private pattern wellformedType(problem: LogicProblem, interpretation:PartialInterpretation, dynamic:Type, element:DefinedElement) {
123 /** 50 // 1: T(e)
124 * supertype -------> element <------- otherSupertype 51 find directInstanceOf(problem,interpretation,element,dynamic);
125 * A A 52 // 2e is not true: D(e) && D-->T && !T(e)
126 * | | 53 neg find dynamicTypeNotSubtypeOfADefinition(problem,interpretation,element,dynamic);
127 * wrongDynamic -----------------------------X 54 // 3e is not true: D(e) && ![T--->D] && T(e)
128 */ 55 neg find dynamicTypeIsSubtypeOfANonDefinition(problem,interpretation,element,dynamic);
129 private pattern dynamicTypeNotSubtypeOfADefinition(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement, wrongDynamic : Type) { 56 // 4: T is not abstract
130 find directInstanceOf(problem,interpretation,element,supertype); 57 Type.isAbstract(dynamic,false);
131 find directInstanceOf(problem,interpretation,element,otherSupertype); 58 }
132 find supertypeStar(wrongDynamic,supertype); 59
133 neg find supertypeStar(wrongDynamic,otherSupertype); 60 private pattern possibleDynamicType(problem: LogicProblem, interpretation:PartialInterpretation, dynamic:Type, element:DefinedElement)
134 } 61 // case 1: element is defined at least once
135 62 {
136 /** 63 LogicProblem.types(problem,dynamic);
137 * supertype -------> element <---X--- otherSupertype 64 // select a random definition 'randomType'
138 * A A 65 find directInstanceOf(problem,interpretation,element,randomType);
139 * | | 66 // dynamic is a subtype of 'randomType'
140 * wrongDynamic -----------------------------+ 67 find supertypeStar(dynamic,randomType);
141 */ 68 // 2e is not true: D(e) && D-->T && !T(e)
142 private pattern dynamicTypeIsSubtypeOfANonDefinition(problem: LogicProblem, interpretation:PartialInterpretation, element:DefinedElement, wrongDynamic:Type) { 69 neg find dynamicTypeNotSubtypeOfADefinition(problem,interpretation,element,dynamic);
143 find directInstanceOf(problem,interpretation,element,supertype); 70 // 3e is not true: D(e) && ![T--->D] && T(e)
144 neg find elementInTypeDefinition(element,otherSupertype); 71 neg find dynamicTypeIsSubtypeOfANonDefinition(problem,interpretation,element,dynamic);
145 TypeDefinition(otherSupertype); 72 // 4: T is not abstract
146 find supertypeStar(wrongDynamic, supertype); 73 Type.isAbstract(dynamic,false);
147 find supertypeStar(wrongDynamic, otherSupertype); 74 // 5. element is not primitive datatype
148 } 75 neg find isPrimitive(element);
149 76 } or
150 private pattern elementInTypeDefinition(element:DefinedElement, definition:TypeDefinition) { 77 // case 2: element is not defined anywhere
151 TypeDefinition.elements(definition,element); 78 {
152 } 79 find mayExist(problem,interpretation,element);
153 80 // there is no definition
154 private pattern typeWithDefinedSupertype(type:Type) { 81 neg find directInstanceOf(problem,interpretation,element,_);
155 find supertypeStar(type,definedSupertype); 82 // 2e is not true: D(e) && D-->T && !T(e)
156 TypeDefinition(definedSupertype); 83 // because non of the definition contains element, the type cannot have defined supertype
157 } 84 LogicProblem.types(problem,dynamic);
158 85 PartialInterpretation.problem(interpretation,problem);
159 private pattern scopeDisallowsNewElementsFromType(typeInterpretation:PartialComplexTypeInterpretation) { 86 neg find typeWithDefinedSupertype(dynamic);
160 Scope.targetTypeInterpretation(scope,typeInterpretation); 87 // 3e is not true: D(e) && ![T--->D] && T(e)
161 Scope.maxNewElements(scope,0); 88 // because there is no definition, dynamic covers all definition
162 } 89 // 4: T is not abstract
163 ''' 90 Type.isAbstract(dynamic,false);
164 91 // 5. element is not primitive datatype
165 public override generateInstanceOfQueries(LogicProblem problem, PartialInterpretation emptySolution,TypeAnalysisResult typeAnalysisResult) { 92 neg find isPrimitive(element);
166 ''' 93 }
167 «FOR type:problem.types» 94
168 «problem.generateMustInstenceOf(type)»
169 «problem.generateMayInstanceOf(type)»
170 «ENDFOR»
171 '''
172 }
173
174 private def patternName(Type type, Modality modality)
175 '''«modality.toString.toLowerCase»InstanceOf«base.canonizeName(type.name)»'''
176
177 private def generateMustInstenceOf(LogicProblem problem, Type type) {
178 '''
179 /** 95 /**
180 * An element must be an instance of type "«type.name»". 96 * supertype -------> element <------- otherSupertype
97 * A A
98 * | |
99 * wrongDynamic -----------------------------X
181 */ 100 */
182 private pattern «patternName(type,Modality.MUST)»(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement) { 101 private pattern dynamicTypeNotSubtypeOfADefinition(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement, wrongDynamic : Type) {
183 Type.name(type,"«type.name»"); 102 find directInstanceOf(problem,interpretation,element,supertype);
184 find directInstanceOf(problem,interpretation,element,type); 103 find directInstanceOf(problem,interpretation,element,otherSupertype);
104 find supertypeStar(wrongDynamic,supertype);
105 neg find supertypeStar(wrongDynamic,otherSupertype);
185 } 106 }
186 ''' 107
187 }
188
189 private def generateMayInstanceOf(LogicProblem problem, Type type) {
190 '''
191 /** 108 /**
192 * An element may be an instance of type "«type.name»". 109 * supertype -------> element <---X--- otherSupertype
110 * A A
111 * | |
112 * wrongDynamic -----------------------------+
193 */ 113 */
194 private pattern «patternName(type,Modality.MAY)»(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement) { 114 private pattern dynamicTypeIsSubtypeOfANonDefinition(problem: LogicProblem, interpretation:PartialInterpretation, element:DefinedElement, wrongDynamic:Type) {
195 Type.name(type,"«type.name»"); 115 find directInstanceOf(problem,interpretation,element,supertype);
196 find possibleDynamicType(problem,interpretation,dynamic,element); 116 neg find elementInTypeDefinition(element,otherSupertype);
197 find supertypeStar(dynamic,type); 117 TypeDefinition(otherSupertype);
198 neg find scopeDisallowsNewElementsFromType(dynamic); 118 find supertypeStar(wrongDynamic, supertype);
119 find supertypeStar(wrongDynamic, otherSupertype);
120 }
121
122 private pattern elementInTypeDefinition(element:DefinedElement, definition:TypeDefinition) {
123 TypeDefinition.elements(definition,element);
124 }
125
126 private pattern typeWithDefinedSupertype(type:Type) {
127 find supertypeStar(type,definedSupertype);
128 TypeDefinition(definedSupertype);
129 }
130
131 private pattern scopeDisallowsNewElementsFromType(typeInterpretation:PartialComplexTypeInterpretation) {
132 Scope.targetTypeInterpretation(scope,typeInterpretation);
133 Scope.maxNewElements(scope,0);
199 } 134 }
135 '''
136
137 protected override generateMayInstanceOf(LogicProblem problem, Type type, TypeAnalysisResult typeAnalysisResult) {
138 '''
139 /**
140 * An element may be an instance of type "«type.name»".
141 */
142 private pattern «patternName(type,Modality.MAY)»(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement) {
143 Type.name(type,"«type.name»");
144 find possibleDynamicType(problem,interpretation,dynamic,element);
145 find supertypeStar(dynamic,type);
146 neg find scopeDisallowsNewElementsFromType(dynamic);
147 }
200 ''' 148 '''
201 } 149 }
202 150}
203 public override referInstanceOf(Type type, Modality modality, String variableName) {
204 '''find «patternName(type,modality)»(problem,interpretation,«variableName»);'''
205 }
206 public override referInstanceOf(EClass type, Modality modality, String variableName) {
207 '''find «modality.toString.toLowerCase»InstanceOf«base.canonizeName('''«type.name» class''')»(problem,interpretation,«variableName»);'''
208 }
209} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/GenericTypeRefinementGenerator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/GenericTypeRefinementGenerator.xtend
index 2e03d6ed..52f0cbea 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/GenericTypeRefinementGenerator.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/GenericTypeRefinementGenerator.xtend
@@ -11,110 +11,114 @@ import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.par
11import java.util.HashMap 11import java.util.HashMap
12 12
13class GenericTypeRefinementGenerator extends TypeRefinementGenerator { 13class GenericTypeRefinementGenerator extends TypeRefinementGenerator {
14 public new(PatternGenerator base) { 14 new(PatternGenerator base) {
15 super(base) 15 super(base)
16 } 16 }
17
17 override requiresTypeAnalysis() { false } 18 override requiresTypeAnalysis() { false }
18 19
19 override generateRefineObjectQueries(LogicProblem p, PartialInterpretation emptySolution, TypeAnalysisResult typeAnalysisResult) { 20 override generateRefineObjectQueries(LogicProblem p, PartialInterpretation emptySolution,
21 TypeAnalysisResult typeAnalysisResult) {
20 val containment = p.containmentHierarchies.head 22 val containment = p.containmentHierarchies.head
21 val newObjectTypes = p.types.filter(TypeDeclaration).filter[!isAbstract] 23 val newObjectTypes = p.types.filter(TypeDeclaration).filter[!isAbstract]
22 val inverseRelations = new HashMap 24 val inverseRelations = new HashMap
23 p.annotations.filter(InverseRelationAssertion).forEach[ 25 p.annotations.filter(InverseRelationAssertion).forEach [
24 inverseRelations.put(it.inverseA,it.inverseB) 26 inverseRelations.put(it.inverseA, it.inverseB)
25 inverseRelations.put(it.inverseB,it.inverseA) 27 inverseRelations.put(it.inverseB, it.inverseA)
26 ] 28 ]
27 return ''' 29 return '''
28 private pattern hasElementInContainment(problem:LogicProblem, interpretation:PartialInterpretation) 30 pattern «hasElementInContainmentName»(problem:LogicProblem, interpretation:PartialInterpretation)
29 «FOR type :containment.typesOrderedInHierarchy SEPARATOR "or"»{ 31 «FOR type : containment.typesOrderedInHierarchy SEPARATOR "or"»{
30 find interpretation(problem,interpretation);
31 «base.typeIndexer.referInstanceOf(type,Modality.MUST,"root")»
32 find mustExist(problem, interpretation, root);
33 }«ENDFOR»
34 «FOR type:newObjectTypes»
35 «IF(containment.typesOrderedInHierarchy.contains(type))»
36 «FOR containmentRelation : containment.containmentRelations.filter[canBeContainedByRelation(it,type)]»
37 «IF inverseRelations.containsKey(containmentRelation)»
38 pattern «this.patternName(containmentRelation,inverseRelations.get(containmentRelation),type)»(
39 problem:LogicProblem, interpretation:PartialInterpretation,
40 relationInterpretation:PartialRelationInterpretation, inverseInterpretation:PartialRelationInterpretation ,typeInterpretation:PartialComplexTypeInterpretation,
41 container:DefinedElement)
42 {
43 find interpretation(problem,interpretation);
44 PartialInterpretation.partialtypeinterpratation(interpretation,typeInterpretation);
45 PartialComplexTypeInterpretation.interpretationOf.name(typeInterpretation,"«type.name»");
46 PartialInterpretation.partialrelationinterpretation(interpretation,relationInterpretation);
47 PartialRelationInterpretation.interpretationOf.name(relationInterpretation,"«containmentRelation.name»");
48 PartialInterpretation.partialrelationinterpretation(interpretation,inverseInterpretation);
49 PartialRelationInterpretation.interpretationOf.name(inverseInterpretation,"«inverseRelations.get(containmentRelation).name»");
50 «base.typeIndexer.referInstanceOf((containmentRelation.parameters.get(0) as ComplexTypeReference).referred,Modality.MUST,"container")»
51 «base.typeIndexer.referInstanceOf(type,Modality.MAY,"newObject")»
52 «base.relationDeclarationIndexer.referRelation(containmentRelation as RelationDeclaration,"container","newObject",Modality.MAY)»
53 find mustExist(problem, interpretation, container);
54 neg find mustExist(problem, interpretation, newObject);
55 }
56 «ELSE»
57 pattern «this.patternName(containmentRelation,null,type)»(
58 problem:LogicProblem, interpretation:PartialInterpretation,
59 relationInterpretation:PartialRelationInterpretation, typeInterpretation:PartialComplexTypeInterpretation,
60 container:DefinedElement)
61 {
62 find interpretation(problem,interpretation);
63 PartialInterpretation.partialtypeinterpratation(interpretation,typeInterpretation);
64 PartialComplexTypeInterpretation.interpretationOf.name(typeInterpretation,"«type.name»");
65 PartialInterpretation.partialrelationinterpretation(interpretation,relationInterpretation);
66 PartialRelationInterpretation.interpretationOf.name(relationInterpretation,"«containmentRelation.name»");
67 «base.typeIndexer.referInstanceOf((containmentRelation.parameters.get(0) as ComplexTypeReference).referred,Modality.MUST,"container")»
68 «base.typeIndexer.referInstanceOf(type,Modality.MAY,"newObject")»
69 «base.relationDeclarationIndexer.referRelation(containmentRelation as RelationDeclaration,"container","newObject",Modality.MAY)»
70 find mustExist(problem, interpretation, container);
71 neg find mustExist(problem, interpretation, newObject);
72 }
73 «ENDIF»
74 «ENDFOR»
75 pattern «patternName(null,null,type)»(
76 problem:LogicProblem, interpretation:PartialInterpretation,
77 typeInterpretation:PartialComplexTypeInterpretation)
78 {
79 find interpretation(problem,interpretation); 32 find interpretation(problem,interpretation);
80 neg find hasElementInContainment(problem,interpretation); 33 «base.typeIndexer.referInstanceOf(type,Modality.MUST,"root")»
81 PartialInterpretation.partialtypeinterpratation(interpretation,typeInterpretation); 34 find mustExist(problem, interpretation, root);
82 PartialComplexTypeInterpretation.interpretationOf.name(type,"«type.name»"); 35 }«ENDFOR»
83 «base.typeIndexer.referInstanceOf(type,Modality.MAY,"newObject")» 36 «FOR type : newObjectTypes»
84 find mayExist(problem, interpretation, newObject); 37 «IF(containment.typesOrderedInHierarchy.contains(type))»
85 neg find mustExist(problem, interpretation, newObject); 38 «FOR containmentRelation : containment.containmentRelations.filter[canBeContainedByRelation(it,type)]»
86 } 39 «IF inverseRelations.containsKey(containmentRelation)»
87 «ELSE» 40 pattern «this.patternName(containmentRelation,inverseRelations.get(containmentRelation),type)»(
88 pattern createObject_«this.patternName(null,null,type)»( 41 problem:LogicProblem, interpretation:PartialInterpretation,
89 problem:LogicProblem, interpretation:PartialInterpretation, 42 relationInterpretation:PartialRelationInterpretation, inverseInterpretation:PartialRelationInterpretation ,typeInterpretation:PartialComplexTypeInterpretation,
90 typeInterpretation:PartialComplexTypeInterpretation) 43 container:DefinedElement)
91 { 44 {
92 find interpretation(problem,interpretation); 45 find interpretation(problem,interpretation);
93 PartialInterpretation.partialtypeinterpratation(interpretation,typeInterpretation); 46 PartialInterpretation.partialtypeinterpratation(interpretation,typeInterpretation);
94 PartialComplexTypeInterpretation.interpretationOf.name(typeInterpretation,"«type.name»"); 47 PartialComplexTypeInterpretation.interpretationOf.name(typeInterpretation,"«type.name»");
95 «base.typeIndexer.referInstanceOf(type,Modality.MAY,"newObject")» 48 PartialInterpretation.partialrelationinterpretation(interpretation,relationInterpretation);
96 find mayExist(problem, interpretation, newObject); 49 PartialRelationInterpretation.interpretationOf.name(relationInterpretation,"«containmentRelation.name»");
97 neg find mustExist(problem, interpretation, newObject); 50 PartialInterpretation.partialrelationinterpretation(interpretation,inverseInterpretation);
98 } 51 PartialRelationInterpretation.interpretationOf.name(inverseInterpretation,"«inverseRelations.get(containmentRelation).name»");
99 «ENDIF» 52 «base.typeIndexer.referInstanceOf((containmentRelation.parameters.get(0) as ComplexTypeReference).referred,Modality.MUST,"container")»
100 «ENDFOR» 53 «base.typeIndexer.referInstanceOf(type,Modality.MAY,"newObject")»
54 «base.relationDeclarationIndexer.referRelation(containmentRelation as RelationDeclaration,"container","newObject",Modality.MAY)»
55 find mustExist(problem, interpretation, container);
56 neg find mustExist(problem, interpretation, newObject);
57 }
58 «ELSE»
59 pattern «this.patternName(containmentRelation,null,type)»(
60 problem:LogicProblem, interpretation:PartialInterpretation,
61 relationInterpretation:PartialRelationInterpretation, typeInterpretation:PartialComplexTypeInterpretation,
62 container:DefinedElement)
63 {
64 find interpretation(problem,interpretation);
65 PartialInterpretation.partialtypeinterpratation(interpretation,typeInterpretation);
66 PartialComplexTypeInterpretation.interpretationOf.name(typeInterpretation,"«type.name»");
67 PartialInterpretation.partialrelationinterpretation(interpretation,relationInterpretation);
68 PartialRelationInterpretation.interpretationOf.name(relationInterpretation,"«containmentRelation.name»");
69 «base.typeIndexer.referInstanceOf((containmentRelation.parameters.get(0) as ComplexTypeReference).referred,Modality.MUST,"container")»
70 «base.typeIndexer.referInstanceOf(type,Modality.MAY,"newObject")»
71 «base.relationDeclarationIndexer.referRelation(containmentRelation as RelationDeclaration,"container","newObject",Modality.MAY)»
72 find mustExist(problem, interpretation, container);
73 neg find mustExist(problem, interpretation, newObject);
74 }
75 «ENDIF»
76 «ENDFOR»
77 pattern «patternName(null,null,type)»(
78 problem:LogicProblem, interpretation:PartialInterpretation,
79 typeInterpretation:PartialComplexTypeInterpretation)
80 {
81 find interpretation(problem,interpretation);
82 neg find «hasElementInContainmentName»(problem,interpretation);
83 PartialInterpretation.partialtypeinterpratation(interpretation,typeInterpretation);
84 PartialComplexTypeInterpretation.interpretationOf.name(type,"«type.name»");
85 «base.typeIndexer.referInstanceOf(type,Modality.MAY,"newObject")»
86 find mayExist(problem, interpretation, newObject);
87 neg find mustExist(problem, interpretation, newObject);
88 }
89 «ELSE»
90 pattern createObject_«this.patternName(null,null,type)»(
91 problem:LogicProblem, interpretation:PartialInterpretation,
92 typeInterpretation:PartialComplexTypeInterpretation)
93 {
94 find interpretation(problem,interpretation);
95 PartialInterpretation.partialtypeinterpratation(interpretation,typeInterpretation);
96 PartialComplexTypeInterpretation.interpretationOf.name(typeInterpretation,"«type.name»");
97 «base.typeIndexer.referInstanceOf(type,Modality.MAY,"newObject")»
98 find mayExist(problem, interpretation, newObject);
99 neg find mustExist(problem, interpretation, newObject);
100 }
101 «ENDIF»
102 «ENDFOR»
101 ''' 103 '''
102 } 104 }
103 105
104 override generateRefineTypeQueries(LogicProblem p, PartialInterpretation emptySolution, TypeAnalysisResult typeAnalysisResult) { 106 override generateRefineTypeQueries(LogicProblem p, PartialInterpretation emptySolution,
107 TypeAnalysisResult typeAnalysisResult) {
105 return ''' 108 return '''
106 «FOR type : p.types.filter(TypeDeclaration).filter[!it.isAbstract]» 109 «FOR type : p.types.filter(TypeDeclaration).filter[!it.isAbstract]»
107 pattern refineTypeTo_«base.canonizeName(type.name)»(problem:LogicProblem, interpretation:PartialInterpretation, object: DefinedElement) { 110 pattern refineTypeTo_«base.canonizeName(type.name)»(problem:LogicProblem, interpretation:PartialInterpretation, object: DefinedElement) {
108 find interpretation(problem,interpretation); 111 find interpretation(problem,interpretation);
109 find mustExist(problem, interpretation, object); 112 find mustExist(problem, interpretation, object);
110 «base.typeIndexer.referInstanceOf(type,Modality.MAY,"object")» 113 «base.typeIndexer.referInstanceOf(type,Modality.MAY,"object")»
111 neg «base.typeIndexer.referInstanceOf(type,Modality.MUST,"object")» 114 neg «base.typeIndexer.referInstanceOf(type,Modality.MUST,"object")»
112 } 115 }
113 «ENDFOR» 116 «ENDFOR»
114 ''' 117 '''
115 } 118 }
116 119
117 override getRefineTypeQueryNames(LogicProblem p, PartialInterpretation emptySolution, TypeAnalysisResult typeAnalysisResult) { 120 override getRefineTypeQueryNames(LogicProblem p, PartialInterpretation emptySolution,
121 TypeAnalysisResult typeAnalysisResult) {
118 p.types.filter(TypeDeclaration).toInvertedMap['''refineTypeTo_«base.canonizeName(it.name)»'''] 122 p.types.filter(TypeDeclaration).toInvertedMap['''refineTypeTo_«base.canonizeName(it.name)»''']
119 } 123 }
120} \ No newline at end of file 124}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PConstraintTransformer.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PConstraintTransformer.xtend
new file mode 100644
index 00000000..dd5cade1
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PConstraintTransformer.xtend
@@ -0,0 +1,275 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns
2
3import hu.bme.mit.inf.dslreasoner.viatra2logic.XExpressionExtractor
4import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality
5import org.eclipse.emf.ecore.EAttribute
6import org.eclipse.emf.ecore.EEnumLiteral
7import org.eclipse.emf.ecore.EReference
8import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey
9import org.eclipse.viatra.query.runtime.emf.types.EDataTypeInSlotsKey
10import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey
11import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint
12import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable
13import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality
14import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter
15import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExpressionEvaluation
16import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality
17import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall
18import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.TypeFilterConstraint
19import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure
20import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.ConstantValue
21import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall
22import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint
23import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.VariableMapping
24import java.util.List
25import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeReference
26import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.PrimitiveTypeReference
27import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.StringTypeReference
28import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference
29import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntTypeReference
30import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference
31import java.util.Map
32
33class PConstraintTransformer {
34 val extension RelationDefinitionIndexer relationDefinitionIndexer;
35 val expressionExtractor = new XExpressionExtractor
36 val expressionGenerator = new PExpressionGenerator
37
38 new(RelationDefinitionIndexer relationDefinitionIndexer) {
39 this.relationDefinitionIndexer = relationDefinitionIndexer
40 }
41
42 dispatch def transformConstraint(TypeConstraint constraint, Modality modality, List<VariableMapping> variableMapping) {
43 val touple = constraint.variablesTuple
44 if(touple.size == 1) {
45 val inputKey = constraint.equivalentJudgement.inputKey
46 if(inputKey instanceof EClassTransitiveInstancesKey) {
47 return relationDefinitionIndexer.base.typeIndexer.referInstanceOf(inputKey.emfKey,modality.toMustMay,
48 constraint.getVariableInTuple(0).canonizeName)
49 } else if(inputKey instanceof EDataTypeInSlotsKey){
50 return '''// type constraint is enforced by construction'''
51 }
52
53 } else if(touple.size == 2){
54 val key = (constraint.equivalentJudgement.inputKey as EStructuralFeatureInstancesKey).emfKey
55 if(key instanceof EReference) {
56 return base.referRelationByName(
57 key,
58 constraint.getVariableInTuple(0).canonizeName,
59 constraint.getVariableInTuple(1).canonizeName,
60 modality.toMustMay)
61 } else if (key instanceof EAttribute) {
62 return base.referAttributeByName(key,
63 constraint.getVariableInTuple(0).canonizeName,
64 constraint.getVariableInTuple(1).canonizeName,
65 modality.toMustMay)
66 } else throw new UnsupportedOperationException('''unknown key: «key.class»''')
67 } else {
68 throw new UnsupportedOperationException('''Unsupported touple size: «touple.size»''')
69 }
70 }
71 dispatch def transformConstraint(TypeFilterConstraint constraint, Modality modality, List<VariableMapping> variableMapping) {
72 val touple = constraint.variablesTuple
73 if(touple.size == 1) {
74 val inputKey = constraint.equivalentJudgement.inputKey
75 if(inputKey instanceof EClassTransitiveInstancesKey) {
76 return base.typeIndexer.referInstanceOf(inputKey.emfKey,modality.toMustMay,
77 (constraint.getVariablesTuple.get(0) as PVariable).canonizeName)
78 } else if(inputKey instanceof EDataTypeInSlotsKey){
79 return '''// type constraint is enforced by construction'''
80 }
81
82 } else if(touple.size == 2){
83 val key = (constraint.equivalentJudgement.inputKey as EStructuralFeatureInstancesKey).emfKey
84 if(key instanceof EReference) {
85 return base.referRelationByName(
86 key,
87 (constraint.getVariablesTuple.get(0) as PVariable).canonizeName,
88 (constraint.getVariablesTuple.get(1) as PVariable).canonizeName,
89 modality.toMustMay)
90 } else if (key instanceof EAttribute) {
91 return base.referAttributeByName(key,
92 (constraint.getVariablesTuple.get(0) as PVariable).canonizeName,
93 (constraint.getVariablesTuple.get(1) as PVariable).canonizeName,
94 modality.toMustMay)
95 } else throw new UnsupportedOperationException('''unknown key: «key.class»''')
96 } else {
97 throw new UnsupportedOperationException('''Unsupported touple size: «touple.size»''')
98 }
99 }
100
101 dispatch def transformConstraint(Equality equality, Modality modality, List<VariableMapping> variableMapping) {
102 val a = equality.who
103 val b = equality.withWhom
104 transformEquality(modality.toMustMay, a, b)
105 }
106
107 private def CharSequence transformEquality(Modality modality, PVariable a, PVariable b) {
108 if(modality.isMustOrCurrent) '''find mustEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);'''
109 else '''find mayEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);'''
110 }
111
112 dispatch def transformConstraint(Inequality inequality, Modality modality, List<VariableMapping> variableMapping) {
113 val a = inequality.who
114 val b = inequality.withWhom
115 if(modality.isCurrent) {
116 return '''neg find mustEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);'''
117 } else if(modality.isMust) {
118 return '''neg find mayEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);'''
119 } else { // modality.isMay
120 return '''neg find mustEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);'''
121 }
122 }
123
124 dispatch def transformConstraint(NegativePatternCall pcall, Modality modality, List<VariableMapping> variableMapping) {
125 val params = (0..<pcall.actualParametersTuple.size).map[index |
126 val variable = pcall.actualParametersTuple.get(index) as PVariable
127 return variable.canonizeName
128 ]
129 return referPattern(pcall.referredQuery,params,modality.dual,false,false)
130 }
131
132 dispatch def transformConstraint(PositivePatternCall pcall, Modality modality, List<VariableMapping> variableMapping) {
133 val params = (0..<pcall.variablesTuple.size).map[index |
134 val variable = pcall.variablesTuple.get(index) as PVariable
135 return variable.canonizeName
136 ]
137 return referPattern(pcall.referredQuery,params,modality,true,false)
138 }
139 dispatch def transformConstraint(BinaryTransitiveClosure pcall, Modality modality, List<VariableMapping> variableMapping) {
140 val params = (0..1).map[index |
141 val variable = pcall.getVariableInTuple(index) as PVariable
142 return variable.canonizeName
143 ]
144 return referPattern(pcall.referredQuery,params,modality,true,true)
145 }
146 dispatch def transformConstraint(ExportedParameter e, Modality modality, List<VariableMapping> variableMapping) {
147 val v1 = '''var_«e.parameterName»'''
148 val v2 = e.parameterVariable.canonizeName
149 if(v1.compareTo(v2) == 0) {
150 return '''// «v1» exported'''
151 } else {
152 return '''«v1» == «v2»;'''
153 }
154 }
155 dispatch def transformConstraint(ConstantValue c, Modality modality, List<VariableMapping> variableMapping) {
156 val target = c.supplierKey
157
158 var String targetString;
159 var String additionalDefinition;
160 if(target instanceof EEnumLiteral) {
161 targetString = '''const_«target.name»_«target.EEnum.name»'''
162 additionalDefinition = '''DefinedElement.name(«targetString»,"«target.name» «target.EEnum.name»"); //LogicProblem.elements(problem,«targetString»);'''
163 } else if(target instanceof Integer) {
164 targetString = '''const_«target»_Integer'''
165 additionalDefinition = '''PrimitiveElement.valueSet(«targetString»,true); IntegerElement.value(«targetString»,«target»);'''
166 } else if(target instanceof Boolean) {
167 targetString = '''const_«target»_Boolean'''
168 additionalDefinition = '''PrimitiveElement.valueSet(«targetString»,true); BooleanElement.value(«targetString»,«target»);'''
169 } else if(target instanceof String) {
170 targetString = '''const_«target»_String'''
171 additionalDefinition = '''PrimitiveElement.valueSet(«targetString»,true); StringElement.value(«targetString»,"«target»");'''
172 } else if(target instanceof Double) {
173 targetString = '''const_«target»_Real'''
174 additionalDefinition = '''PrimitiveElement.valueSet(«targetString»,true); RealElement.value(«targetString»,«target»);'''
175 } else if(target instanceof Float) {
176 targetString = '''const_«target»_Real'''
177 additionalDefinition = '''PrimitiveElement.valueSet(«targetString»,true); RealElement.value(«targetString»,«target»);'''
178 } else {
179 throw new UnsupportedOperationException('''Unknown constant type: «target.class»''')
180 }
181
182 val source = c.variablesTuple
183 var String sourceName
184 if(source.size == 1)
185 sourceName = (source.get(0) as PVariable).canonizeName
186 else throw new UnsupportedOperationException("unknown source")
187 return '''«sourceName» == «targetString»;«additionalDefinition»''';
188 }
189
190 protected def valueVariable(PVariable v) {
191 "value_"+v.canonizeName
192 }
193 protected def valueSetted(PVariable v) {
194 "setted_"+v.canonizeName
195 }
196 def hasValue(PVariable v, String target, Modality m, List<VariableMapping> variableMapping) {
197 val typeReference = variableMapping.filter[it.sourcePVariable === v].head.targetLogicVariable.range as PrimitiveTypeReference
198 if(m.isMay) {
199 '''PrimitiveElement.valueSet(«v.canonizeName»,«v.valueSetted»); «hasValueExpressionByRef(typeReference,v,v.valueVariable)»
200««« check(!«v.valueSetted»||«v.valueVariable»==«target»));
201'''
202 } else { // Must or current
203 '''PrimitiveElement.valueSet(«v.canonizeName»,true);«hasValueExpressionByRef(typeReference,v,target)»'''
204 }
205 }
206
207 private def hasValueExpression(List<VariableMapping> variableMapping, PVariable v, String target) {
208 val mapping = variableMapping.filter[
209 val v2 = (it.sourcePVariable as PVariable)
210 v2 === v
211 ].head
212 val range = mapping.targetLogicVariable.range
213 hasValueExpressionByRef(
214 range,
215 v,
216 target
217 )
218 }
219 private def dispatch hasValueExpressionByRef(BoolTypeReference typeReference, PVariable v, String target) '''BooleanElement.value(«v.canonizeName»,«target»);'''
220 private def dispatch hasValueExpressionByRef(IntTypeReference typeReference, PVariable v, String target) '''IntegerElement.value(«v.canonizeName»,«target»);'''
221 private def dispatch hasValueExpressionByRef(RealTypeReference typeReference, PVariable v, String target) '''RealElement.value(«v.canonizeName»,«target»);'''
222 private def dispatch hasValueExpressionByRef(StringTypeReference typeReference, PVariable v, String target) '''StringElement.value(«v.canonizeName»,«target»);'''
223 private def dispatch hasValueExpressionByRef(TypeReference typeReference, PVariable v, String target) {
224 throw new UnsupportedOperationException('''Unsupported primitive type reference: «typeReference.class»''')
225 }
226
227 dispatch def transformConstraint(ExpressionEvaluation e, Modality modality, List<VariableMapping> variableMapping) {
228 if(e.outputVariable!==null) {
229 throw new UnsupportedOperationException('''Only check expressions are supported "«e.class.name»"!''')
230 } else {
231 val expression = expressionExtractor.extractExpression(e.evaluator)
232 val Map<PVariable, PrimitiveTypeReference> variable2Type = e.affectedVariables.toInvertedMap[v|variableMapping.filter[it.sourcePVariable === v].head.targetLogicVariable.range as PrimitiveTypeReference]
233 if(modality.isMay) {
234 return '''
235 «FOR variable: e.affectedVariables»
236 PrimitiveElement.valueSet(«variable.canonizeName»,«variable.valueSetted»); «hasValueExpression(variableMapping,variable,variable.valueVariable)»
237 «ENDFOR»
238««« check(
239««« «FOR variable: e.affectedVariables SEPARATOR " || "»!«variable.valueSetted»«ENDFOR»
240««« «IF variable2Type.values.filter(RealTypeReference).empty»
241««« ||
242««« («expressionGenerator.translateExpression(expression,e.affectedVariables.toInvertedMap[valueVariable],variable2Type)»)
243««« «ENDIF»
244««« );
245 '''
246 } else { // Must or Current
247 return '''
248 «FOR variable: e.affectedVariables»
249 PrimitiveElement.valueSet(«variable.canonizeName»,true); «hasValueExpression(variableMapping,variable,variable.valueVariable)»
250 «ENDFOR»
251««« «IF variable2Type.values.filter(RealTypeReference).empty»
252««« check(«expressionGenerator.translateExpression(expression,e.affectedVariables.toInvertedMap[valueVariable],variable2Type)»);
253««« «ENDIF»
254 '''
255 }
256 }
257 }
258
259 dispatch def transformConstraint(PConstraint c, Modality modality, List<VariableMapping> variableMapping) {
260 throw new UnsupportedOperationException('''Unknown constraint type: "«c.class.name»"!''')
261 }
262
263 dispatch def transformConstraintUnset(ExpressionEvaluation e, List<VariableMapping> variableMapping) {
264 return '''
265 «FOR variable: e.affectedVariables»
266 PrimitiveElement.valueSet(«variable.canonizeName»,«variable.valueSetted»); «hasValueExpression(variableMapping,variable,variable.valueVariable)»
267 «ENDFOR»
268««« check(«FOR variable: e.affectedVariables SEPARATOR " || "»!«variable.valueSetted»«ENDFOR»);
269 '''
270 }
271
272 dispatch def transformConstraintUnset(PConstraint c, List<VariableMapping> variableMapping) {
273 throw new UnsupportedOperationException('''Unknown constraint type: "«c.class.name»"!''')
274 }
275} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PExpressionGenerator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PExpressionGenerator.xtend
new file mode 100644
index 00000000..62ff92b2
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PExpressionGenerator.xtend
@@ -0,0 +1,116 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns
2
3import java.util.Map
4import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable
5import org.eclipse.xtext.xbase.XBinaryOperation
6import org.eclipse.xtext.xbase.XExpression
7import org.eclipse.xtext.xbase.XFeatureCall
8import org.eclipse.xtext.xbase.XMemberFeatureCall
9import org.eclipse.xtext.xbase.XNumberLiteral
10import org.eclipse.xtext.xbase.XUnaryOperation
11import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.PrimitiveTypeReference
12import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference
13
14class PExpressionGenerator {
15 static val N_Base = "org.eclipse.xtext.xbase.lib."
16
17 static val N_PLUS1 = "operator_plus"
18 static val N_MINUS1 = "operator_minus"
19
20 static val N_MINUS2 = "operator_minus"
21 static val N_PLUS2 = "operator_plus"
22 static val N_POWER = "operator_power"
23 static val N_MULTIPLY = "operator_multiply"
24 static val N_DIVIDE = "operator_divide"
25 static val N_MODULO = "operator_modulo"
26 static val N_LESSTHAN = "operator_lessThan"
27 static val N_LESSEQUALSTHAN = "operator_lessEqualsThan"
28 static val N_GREATERTHAN = "operator_greaterThan"
29 static val N_GREATEREQUALTHAN = "operator_greaterEqualsThan"
30 static val N_EQUALS = "operator_equals"
31 static val N_NOTEQUALS = "operator_notEquals"
32 static val N_EQUALS3 = "operator_tripleEquals"
33 static val N_NOTEQUALS3 = "operator_tripleNotEquals"
34
35 protected def isN(String name, String s) {
36 val res = name.startsWith(N_Base) && name.endsWith(s)
37 //println('''[«res»] «name» ?= «N_Base»*«s»''')
38 return res
39 }
40
41 static val N_POWER2 = "java.lang.Math.pow"
42
43 def dispatch CharSequence translateExpression(XBinaryOperation e, Map<PVariable,String> valueName, Map<PVariable, PrimitiveTypeReference> variable2Type) {
44 val left = e.leftOperand.translateExpression(valueName,variable2Type)
45 val right = e.rightOperand.translateExpression(valueName,variable2Type)
46 val feature = e.feature.qualifiedName
47 if(feature.isN(N_MINUS2)) { return '''(«left»-«right»)'''}
48 else if(feature.isN(N_PLUS2)) { return '''(«left»+«right»)''' }
49 else if(feature.isN(N_POWER)) { return '''(«left»^«right»)''' }
50 else if(feature.isN(N_MULTIPLY)) { return '''(«left»*«right»)''' }
51 else if(feature.isN(N_DIVIDE)) { return '''(«left»/«right»)''' }
52 else if(feature.isN(N_MODULO)) { return '''(«left»%«right»)''' }
53 else if(feature.isN(N_LESSTHAN)) { return '''(«left»<«right»)''' }
54 else if(feature.isN(N_LESSEQUALSTHAN)) { return '''(«left»<=«right»)''' }
55 else if(feature.isN(N_GREATERTHAN)) { return '''(«left»>«right»)''' }
56 else if(feature.isN(N_GREATEREQUALTHAN)) { return '''(«left»>=«right»)''' }
57 else if(feature.isN(N_EQUALS)) { return '''(«left»==«right»)''' }
58 else if(feature.isN(N_NOTEQUALS)) { return '''(«left»!=«right»)''' }
59 else if(feature.isN(N_EQUALS3)) { return '''(«left»===«right»)''' }
60 else if(feature.isN(N_NOTEQUALS3)) { return '''(«left»!==«right»)''' }
61 else {
62 println("-> " + e.feature+","+e.class)
63 println("-> " + e.leftOperand)
64 println("-> " + e.rightOperand)
65 println("-> " + e.feature.qualifiedName)
66 throw new UnsupportedOperationException('''Unsupported binary operator feature: "«e.feature.class.simpleName»" - «e»''')
67 }
68 }
69
70 def dispatch CharSequence translateExpression(XUnaryOperation e, Map<PVariable,String> valueName, Map<PVariable, PrimitiveTypeReference> variable2Type) {
71 val operand = e.operand.translateExpression(valueName,variable2Type)
72 val feature = e.feature.qualifiedName
73 if(feature.isN(N_MINUS1)) { return '''(-«operand»)'''}
74 else if(feature.isN(N_PLUS1)) { return '''(+«operand»)'''}
75 else{
76 println("-> " + e.feature+","+e.class)
77 println("-> " + e.operand)
78 println("-> " + e.feature.qualifiedName)
79 throw new UnsupportedOperationException('''Unsupported unary operator feature: "«e.feature.class.simpleName»" - «e»''')
80 }
81 }
82
83 def dispatch CharSequence translateExpression(XMemberFeatureCall e, Map<PVariable,String> valueName, Map<PVariable, PrimitiveTypeReference> variable2Type) {
84 val transformedArguments = e.actualArguments.map[translateExpression(valueName,variable2Type)]
85 val feature = e.feature.qualifiedName
86 if(feature == N_POWER2) {
87 return '''Math.pow(«transformedArguments.get(0)»,«transformedArguments.get(1)»)'''
88 }else {
89 println(e.feature+","+e.class)
90 println(e.actualArguments.join(", "))
91 println(e.feature.qualifiedName)
92 throw new UnsupportedOperationException('''Unsupported feature call: "«e.feature.qualifiedName»" - «e»''')
93 }
94 }
95
96 def dispatch CharSequence translateExpression(XFeatureCall e, Map<PVariable,String> valueName, Map<PVariable, PrimitiveTypeReference> variable2Type) {
97 val featureName = e.feature.qualifiedName
98 val type = variable2Type.entrySet.filter[it.key.name===featureName].head.value
99 val entryWithName = valueName.entrySet.filter[it.key.name == featureName].head
100 if(entryWithName !== null) {
101 if(type instanceof RealTypeReference) {
102 return '''(«entryWithName.value».doubleValue)'''
103 } else {
104 return entryWithName.value
105 }
106 } else {
107 throw new IllegalArgumentException('''Feature call reference to unavailable variable "«featureName»"''')
108 }
109 }
110
111 def dispatch CharSequence translateExpression(XNumberLiteral l, Map<PVariable,String> valueName, Map<PVariable, PrimitiveTypeReference> variable2Type) '''«l.value»'''
112
113 def dispatch CharSequence translateExpression(XExpression expression, Map<PVariable,String> valueName, Map<PVariable, PrimitiveTypeReference> variable2Type) {
114 throw new UnsupportedOperationException('''Unsupported expression in check or eval: «expression.class.name», «expression»"''')
115 }
116} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PatternGenerator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PatternGenerator.xtend
index d4c76bb4..edf92343 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PatternGenerator.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PatternGenerator.xtend
@@ -1,7 +1,6 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns 1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns
2 2
3import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.InverseRelationAssertion 3import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.InverseRelationAssertion
4import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.LowerMultiplicityAssertion
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference 4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntTypeReference 5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntTypeReference
7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference 6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference
@@ -17,31 +16,55 @@ import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.Transform
17import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality 16import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality
18import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeAnalysisResult 17import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeAnalysisResult
19import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeInferenceMethod 18import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeInferenceMethod
19import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeConstraintHint
20import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.RelationConstraints
21import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy
20import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 22import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
23import java.util.Collection
21import java.util.HashMap 24import java.util.HashMap
22import java.util.Map 25import java.util.Map
23import org.eclipse.emf.ecore.EAttribute 26import org.eclipse.emf.ecore.EAttribute
24import org.eclipse.emf.ecore.EReference 27import org.eclipse.emf.ecore.EReference
28import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint
25import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery 29import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
26import org.eclipse.xtend.lib.annotations.Accessors 30import org.eclipse.xtend.lib.annotations.Accessors
31import org.eclipse.xtend.lib.annotations.Data
32import org.eclipse.xtend2.lib.StringConcatenationClient
27 33
28import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* 34import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
29 35
36@Data class PatternGeneratorResult {
37 CharSequence patternText
38 HashMap<PConstraint,String> constraint2MustPreconditionName
39 HashMap<PConstraint,String> constraint2CurrentPreconditionName
40}
41
42interface UnitPropagationPatternGenerator {
43 def Map<Relation, String> getMustPatterns()
44
45 def Map<Relation, String> getMustNotPatterns()
46
47 def StringConcatenationClient getAdditionalPatterns(PatternGenerator generator, Map<String, PQuery> fqn2PQuery)
48}
49
30class PatternGenerator { 50class PatternGenerator {
31 @Accessors(PUBLIC_GETTER) val TypeIndexer typeIndexer //= new TypeIndexer(this) 51 @Accessors(PUBLIC_GETTER) val TypeIndexer typeIndexer // = new TypeIndexer(this)
32 @Accessors(PUBLIC_GETTER) val RelationDeclarationIndexer relationDeclarationIndexer = new RelationDeclarationIndexer(this) 52 @Accessors(PUBLIC_GETTER) val RelationDeclarationIndexer relationDeclarationIndexer = new RelationDeclarationIndexer(
33 @Accessors(PUBLIC_GETTER) val RelationDefinitionIndexer relationDefinitionIndexer = new RelationDefinitionIndexer(this) 53 this)
54 @Accessors(PUBLIC_GETTER) val RelationDefinitionIndexer relationDefinitionIndexer = new RelationDefinitionIndexer(
55 this)
34 @Accessors(PUBLIC_GETTER) val ContainmentIndexer containmentIndexer = new ContainmentIndexer(this) 56 @Accessors(PUBLIC_GETTER) val ContainmentIndexer containmentIndexer = new ContainmentIndexer(this)
35 @Accessors(PUBLIC_GETTER) val InvalidIndexer invalidIndexer = new InvalidIndexer(this) 57 @Accessors(PUBLIC_GETTER) val InvalidIndexer invalidIndexer = new InvalidIndexer(this)
36 @Accessors(PUBLIC_GETTER) val UnfinishedIndexer unfinishedIndexer = new UnfinishedIndexer(this) 58 @Accessors(PUBLIC_GETTER) val UnfinishedIndexer unfinishedIndexer
37 @Accessors(PUBLIC_GETTER) val TypeRefinementGenerator typeRefinementGenerator //= new RefinementGenerator(this) 59 @Accessors(PUBLIC_GETTER) val TypeRefinementGenerator typeRefinementGenerator //= new RefinementGenerator(this)
38 @Accessors(PUBLIC_GETTER) val RelationRefinementGenerator relationRefinementGenerator = new RelationRefinementGenerator(this) 60 @Accessors(PUBLIC_GETTER) val RelationRefinementGenerator relationRefinementGenerator = new RelationRefinementGenerator(this)
61 @Accessors(PUBLIC_GETTER) val UnitPropagationPreconditionGenerator unitPropagationPreconditionGenerator = new UnitPropagationPreconditionGenerator(this)
39 62
40 public new(TypeInferenceMethod typeInferenceMethod) { 63 new(TypeInferenceMethod typeInferenceMethod, ScopePropagatorStrategy scopePropagatorStrategy) {
41 if(typeInferenceMethod == TypeInferenceMethod.Generic) { 64 if(typeInferenceMethod == TypeInferenceMethod.Generic) {
42 this.typeIndexer = new GenericTypeIndexer(this) 65 this.typeIndexer = new GenericTypeIndexer(this)
43 this.typeRefinementGenerator = new GenericTypeRefinementGenerator(this) 66 this.typeRefinementGenerator = new GenericTypeRefinementGenerator(this)
44 } else if(typeInferenceMethod == TypeInferenceMethod.PreliminaryAnalysis) { 67 } else if (typeInferenceMethod == TypeInferenceMethod.PreliminaryAnalysis) {
45 this.typeIndexer = new TypeIndexerWithPreliminaryTypeAnalysis(this) 68 this.typeIndexer = new TypeIndexerWithPreliminaryTypeAnalysis(this)
46 this.typeRefinementGenerator = new TypeRefinementWithPreliminaryTypeAnalysis(this) 69 this.typeRefinementGenerator = new TypeRefinementWithPreliminaryTypeAnalysis(this)
47 } else { 70 } else {
@@ -49,113 +72,105 @@ class PatternGenerator {
49 this.typeRefinementGenerator = null 72 this.typeRefinementGenerator = null
50 throw new IllegalArgumentException('''Unknown type indexing technique : «typeInferenceMethod.name»''') 73 throw new IllegalArgumentException('''Unknown type indexing technique : «typeInferenceMethod.name»''')
51 } 74 }
75 this.unfinishedIndexer = new UnfinishedIndexer(this, scopePropagatorStrategy.requiresUpperBoundIndexing)
52 } 76 }
53 77
54 public def requiresTypeAnalysis() { 78 def requiresTypeAnalysis() {
55 typeIndexer.requiresTypeAnalysis || typeRefinementGenerator.requiresTypeAnalysis 79 typeIndexer.requiresTypeAnalysis || typeRefinementGenerator.requiresTypeAnalysis
56 } 80 }
57 81
58 public dispatch def referRelation( 82 dispatch def CharSequence referRelation(RelationDeclaration referred, String sourceVariable, String targetVariable,
59 RelationDeclaration referred, 83 Modality modality, Map<String, PQuery> fqn2PQuery) {
60 String sourceVariable, 84 return this.relationDeclarationIndexer.referRelation(referred, sourceVariable, targetVariable, modality)
61 String targetVariable,
62 Modality modality,
63 Map<String,PQuery> fqn2PQuery)
64 {
65 return this.relationDeclarationIndexer.referRelation(referred,sourceVariable,targetVariable,modality)
66 } 85 }
67 public dispatch def referRelation( 86
68 RelationDefinition referred, 87 dispatch def CharSequence referRelation(RelationDefinition referred, String sourceVariable, String targetVariable,
69 String sourceVariable, 88 Modality modality, Map<String, PQuery> fqn2PQuery) {
70 String targetVariable, 89 val pattern = referred.annotations.filter(TransfomedViatraQuery).head.patternFullyQualifiedName.lookup(
71 Modality modality, 90 fqn2PQuery)
72 Map<String,PQuery> fqn2PQuery) 91 return this.relationDefinitionIndexer.referPattern(pattern, #[sourceVariable, targetVariable], modality, true,
73 { 92 false)
74 val pattern = referred.annotations.filter(TransfomedViatraQuery).head.patternFullyQualifiedName.lookup(fqn2PQuery)
75 return this.relationDefinitionIndexer.referPattern(pattern,#[sourceVariable,targetVariable],modality,true,false)
76 } 93 }
77 94
78 def public referRelationByName(EReference reference, 95 def referRelationByName(EReference reference, String sourceVariable, String targetVariable, Modality modality) {
79 String sourceVariable, 96 '''find «modality.name.toLowerCase»InRelation«canonizeName('''«reference.name» reference «reference.EContainingClass.name»''')»(problem,interpretation,«sourceVariable»,«targetVariable»);'''
80 String targetVariable,
81 Modality modality)
82 {
83 '''find «modality.name.toLowerCase»InRelation«canonizeName('''«reference.name» reference «reference.EContainingClass.name»''')
84 »(problem,interpretation,«sourceVariable»,«targetVariable»);'''
85 } 97 }
86 98
87 def public CharSequence referAttributeByName(EAttribute attribute, 99 def CharSequence referAttributeByName(EAttribute attribute, String sourceVariable, String targetVariable,
88 String sourceVariable, 100 Modality modality) {
89 String targetVariable, 101 '''find «modality.name.toLowerCase»InRelation«canonizeName('''«attribute.name» attribute «attribute.EContainingClass.name»''')»(problem,interpretation,«sourceVariable»,«targetVariable»);'''
90 Modality modality)
91 {
92 '''find «modality.name.toLowerCase»InRelation«canonizeName('''«attribute.name» attribute «attribute.EContainingClass.name»''')
93 »(problem,interpretation,«sourceVariable»,«targetVariable»);'''
94 } 102 }
95 103
96 public def canonizeName(String name) { 104 def canonizeName(String name) {
97 name.split(' ').join('_') 105 name.split(' ').join('_')
98 } 106 }
99 107
100 public def lowerMultiplicities(LogicProblem problem) { 108 def wfQueries(LogicProblem problem) {
101 problem.assertions.map[annotations].flatten.filter(LowerMultiplicityAssertion).filter[!it.relation.isDerived] 109 problem.assertions.map[it.annotations].flatten.filter(TransformedViatraWellformednessConstraint).map[it.query]
102 }
103 public def wfQueries(LogicProblem problem) {
104 problem.assertions.map[it.annotations]
105 .flatten
106 .filter(TransformedViatraWellformednessConstraint)
107 .map[it.query]
108 } 110 }
109 public def getContainments(LogicProblem p) { 111
112 def getContainments(LogicProblem p) {
110 return p.containmentHierarchies.head.containmentRelations 113 return p.containmentHierarchies.head.containmentRelations
111 } 114 }
112 public def getInverseRelations(LogicProblem p) { 115
116 def getInverseRelations(LogicProblem p) {
113 val inverseRelations = new HashMap 117 val inverseRelations = new HashMap
114 p.annotations.filter(InverseRelationAssertion).forEach[ 118 p.annotations.filter(InverseRelationAssertion).forEach [
115 inverseRelations.put(it.inverseA,it.inverseB) 119 inverseRelations.put(it.inverseA, it.inverseB)
116 inverseRelations.put(it.inverseB,it.inverseA) 120 inverseRelations.put(it.inverseB, it.inverseA)
117 ] 121 ]
118 return inverseRelations 122 return inverseRelations
119 } 123 }
120 public def isRepresentative(Relation relation, Relation inverse) { 124
121 if(inverse == null) { 125 def isRepresentative(Relation relation, Relation inverse) {
126 if (relation === null) {
127 return false
128 } else if (inverse === null) {
122 return true 129 return true
123 } else { 130 } else {
124 relation.name.compareTo(inverse.name)<1 131 relation.name.compareTo(inverse.name) < 1
125 } 132 }
126 } 133 }
127 134
128 public def isDerived(Relation relation) { 135 def isDerived(Relation relation) {
129 relation.annotations.exists[it instanceof DefinedByDerivedFeature] 136 relation.annotations.exists[it instanceof DefinedByDerivedFeature]
130 } 137 }
131 public def getDerivedDefinition(RelationDeclaration relation) { 138
139 def getDerivedDefinition(RelationDeclaration relation) {
132 relation.annotations.filter(DefinedByDerivedFeature).head.query 140 relation.annotations.filter(DefinedByDerivedFeature).head.query
133 } 141 }
134 142
135 private def allTypeReferences(LogicProblem problem) { 143 private def allTypeReferences(LogicProblem problem) {
136 problem.eAllContents.filter(TypeReference).toIterable 144 problem.eAllContents.filter(TypeReference).toIterable
137 } 145 }
146
138 protected def hasBoolean(LogicProblem problem) { 147 protected def hasBoolean(LogicProblem problem) {
139 problem.allTypeReferences.exists[it instanceof BoolTypeReference] 148 problem.allTypeReferences.exists[it instanceof BoolTypeReference]
140 } 149 }
150
141 protected def hasInteger(LogicProblem problem) { 151 protected def hasInteger(LogicProblem problem) {
142 problem.allTypeReferences.exists[it instanceof IntTypeReference] 152 problem.allTypeReferences.exists[it instanceof IntTypeReference]
143 } 153 }
154
144 protected def hasReal(LogicProblem problem) { 155 protected def hasReal(LogicProblem problem) {
145 problem.allTypeReferences.exists[it instanceof RealTypeReference] 156 problem.allTypeReferences.exists[it instanceof RealTypeReference]
146 } 157 }
158
147 protected def hasString(LogicProblem problem) { 159 protected def hasString(LogicProblem problem) {
148 problem.allTypeReferences.exists[it instanceof StringTypeReference] 160 problem.allTypeReferences.exists[it instanceof StringTypeReference]
149 } 161 }
150 162
151 public def transformBaseProperties( 163 def transformBaseProperties(
152 LogicProblem problem, 164 LogicProblem problem,
153 PartialInterpretation emptySolution, 165 PartialInterpretation emptySolution,
154 Map<String,PQuery> fqn2PQuery, 166 Map<String, PQuery> fqn2PQuery,
155 TypeAnalysisResult typeAnalysisResult 167 TypeAnalysisResult typeAnalysisResult,
168 RelationConstraints constraints,
169 Collection<LinearTypeConstraintHint> hints,
170 Collection<UnitPropagationPatternGenerator> unitPropagationPatternGenerators
156 ) { 171 ) {
157 172 val first =
158 return ''' 173 '''
159 import epackage "http://www.bme.hu/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage" 174 import epackage "http://www.bme.hu/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage"
160 import epackage "http://www.bme.hu/mit/inf/dslreasoner/logic/model/problem" 175 import epackage "http://www.bme.hu/mit/inf/dslreasoner/logic/model/problem"
161 import epackage "http://www.bme.hu/mit/inf/dslreasoner/logic/model/language" 176 import epackage "http://www.bme.hu/mit/inf/dslreasoner/logic/model/language"
@@ -170,6 +185,7 @@ class PatternGenerator {
170 ///////////////////////// 185 /////////////////////////
171 // 0.1 Existence 186 // 0.1 Existence
172 ///////////////////////// 187 /////////////////////////
188 /** [[exist(element)]]=1 */
173 private pattern mustExist(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement) { 189 private pattern mustExist(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement) {
174 find interpretation(problem,interpretation); 190 find interpretation(problem,interpretation);
175 LogicProblem.elements(problem,element); 191 LogicProblem.elements(problem,element);
@@ -178,6 +194,7 @@ class PatternGenerator {
178 PartialInterpretation.newElements(interpretation,element); 194 PartialInterpretation.newElements(interpretation,element);
179 } 195 }
180 196
197 /** [[exist(element)]]>=1/2 */
181 private pattern mayExist(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement) { 198 private pattern mayExist(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement) {
182 find mustExist(problem,interpretation,element); 199 find mustExist(problem,interpretation,element);
183 } or { 200 } or {
@@ -188,7 +205,7 @@ class PatternGenerator {
188 205
189 private pattern elementCloseWorld(element:DefinedElement) { 206 private pattern elementCloseWorld(element:DefinedElement) {
190 PartialInterpretation.openWorldElements(i,element); 207 PartialInterpretation.openWorldElements(i,element);
191 PartialInterpretation.maxNewElements(i,0); 208 PartialInterpretation.maxNewElements(i,0);
192 } or { 209 } or {
193 Scope.targetTypeInterpretation(scope,interpretation); 210 Scope.targetTypeInterpretation(scope,interpretation);
194 PartialTypeInterpratation.elements(interpretation,element); 211 PartialTypeInterpratation.elements(interpretation,element);
@@ -198,64 +215,115 @@ class PatternGenerator {
198 //////////////////////// 215 ////////////////////////
199 // 0.2 Equivalence 216 // 0.2 Equivalence
200 //////////////////////// 217 ////////////////////////
201 pattern mayEquivalent(problem:LogicProblem, interpretation:PartialInterpretation, a: DefinedElement, b: DefinedElement) { 218 pattern mayEquivalent(problem:LogicProblem, interpretation:PartialInterpretation, a: DefinedElement, b: DefinedElement)
219 // For non-primitive type. Boolean types always must equivalent or cannot equivalent
220 {
202 find mayExist(problem,interpretation,a); 221 find mayExist(problem,interpretation,a);
203 find mayExist(problem,interpretation,b); 222 find mayExist(problem,interpretation,b);
204 a == b; 223 a == b;
224««« } or {
225««« find mayExist(problem,interpretation,a);
226««« find mayExist(problem,interpretation,b);
227««« IntegerElement(a);
228««« IntegerElement(b);
229««« PrimitiveElement.valueSet(a,false);
230««« } or {
231««« find mayExist(problem,interpretation,a);
232««« find mayExist(problem,interpretation,b);
233««« IntegerElement(a);
234««« IntegerElement(b);
235««« PrimitiveElement.valueSet(b,false);
236««« } or {
237««« find mayExist(problem,interpretation,a);
238««« find mayExist(problem,interpretation,b);
239««« RealElement(a);
240««« RealElement(b);
241««« PrimitiveElement.valueSet(a,false);
242««« } or {
243««« find mayExist(problem,interpretation,a);
244««« find mayExist(problem,interpretation,b);
245««« RealElement(a);
246««« RealElement(b);
247««« PrimitiveElement.valueSet(b,false);
248««« } or {
249««« find mayExist(problem,interpretation,a);
250««« find mayExist(problem,interpretation,b);
251««« StringElement(a);
252««« StringElement(b);
253««« PrimitiveElement.valueSet(a,false);
254««« } or {
255««« find mayExist(problem,interpretation,a);
256««« find mayExist(problem,interpretation,b);
257««« StringElement(a);
258««« StringElement(b);
259««« PrimitiveElement.valueSet(b,false);
205 } 260 }
261
206 pattern mustEquivalent(problem:LogicProblem, interpretation:PartialInterpretation, a: DefinedElement, b: DefinedElement) { 262 pattern mustEquivalent(problem:LogicProblem, interpretation:PartialInterpretation, a: DefinedElement, b: DefinedElement) {
263 // For non-primitive and Boolean primitive type
207 find mustExist(problem,interpretation,a); 264 find mustExist(problem,interpretation,a);
208 find mustExist(problem,interpretation,b); 265 find mustExist(problem,interpretation,b);
209 a == b; 266 a == b;
267««« } or {
268««« find mustExist(problem,interpretation,a);
269««« find mustExist(problem,interpretation,b);
270««« PrimitiveElement.valueSet(a,true);
271««« PrimitiveElement.valueSet(b,true);
272««« IntegerElement.value(a,value);
273««« IntegerElement.value(b,value);
274««« } or {
275««« find mustExist(problem,interpretation,a);
276««« find mustExist(problem,interpretation,b);
277««« PrimitiveElement.valueSet(a,true);
278««« PrimitiveElement.valueSet(b,true);
279««« RealElement.value(a,value);
280««« RealElement.value(b,value);
281««« } or {
282««« find mustExist(problem,interpretation,a);
283««« find mustExist(problem,interpretation,b);
284««« PrimitiveElement.valueSet(a,true);
285««« PrimitiveElement.valueSet(b,true);
286««« StringElement.value(a,value);
287««« StringElement.value(b,value);
210 } 288 }
211 289
212 ////////////////////////
213 // 0.3 Required Patterns by TypeIndexer
214 ////////////////////////
215 «typeIndexer.requiredQueries»
216
217 ////////// 290 //////////
218 // 1. Problem-Specific Base Indexers 291 // 1. Problem-Specific Base Indexers
219 ////////// 292 //////////
220 // 1.1 Type Indexers 293 // 1.1 Type Indexers
221 ////////// 294 //////////
222 // 1.1.1 primitive Type Indexers 295 // 1.1.1 Required Patterns by TypeIndexer
223 ////////// 296 //////////
224««« pattern instanceofBoolean(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement) { 297
225««« find interpretation(problem,interpretation); 298 «typeIndexer.requiredQueries»
226««« PartialInterpretation.booleanelements(interpretation,element);
227««« }
228««« pattern instanceofInteger(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement) {
229««« find interpretation(problem,interpretation);
230««« PartialInterpretation.integerelements(interpretation,element);
231««« } or {
232««« find interpretation(problem,interpretation);
233««« PartialInterpretation.newIntegers(interpetation,element);
234««« }
235««« pattern instanceofReal(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement) {
236««« find interpretation(problem,interpretation);
237««« PartialInterpretation.realelements(interpretation,element);
238««« } or {
239««« find interpretation(problem,interpretation);
240««« PartialInterpretation.newReals(interpetation,element);
241««« }
242««« pattern instanceofString(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement) {
243««« find interpretation(problem,interpretation);
244««« PartialInterpretation.stringelements(interpretation,element);
245««« } or {
246««« find interpretation(problem,interpretation);
247««« PartialInterpretation.newStrings(interpetation,element);
248««« }
249 299
250 ////////// 300 //////////
251 // 1.1.2 domain-specific Type Indexers 301 // 1.1.2 primitive Type Indexers
302 //////////
303 // Currently unused. Refer primitive types as:
304 // > PrimitiveElement(element)
305 // specific types are referred as:
306 // > BooleanElement(variableName)
307 // > IntegerElement(variableName)
308 // > RealElement(variableName)
309 // > StringElement(variableName)
310 // And their value as
311 // > BooleanElement.value(variableName,value)
312 // > IntegerElement.value(variableName,value)
313 // > RealElement.value(variableName,value)
314 // > StringElement.value(variableName,value)
315 // Whether a value is set is defined by:
316 // > PrimitiveElement.valueSet(variableName,isFilled);
317
318 //////////
319 // 1.1.3 domain-specific Type Indexers
252 ////////// 320 //////////
253 «typeIndexer.generateInstanceOfQueries(problem,emptySolution,typeAnalysisResult)» 321 «typeIndexer.generateInstanceOfQueries(problem,emptySolution,typeAnalysisResult)»
254 322
255 ////////// 323 //////////
256 // 1.2 Relation Declaration Indexers 324 // 1.2 Relation Declaration Indexers
257 ////////// 325 //////////
258 «relationDeclarationIndexer.generateRelationIndexers(problem,problem.relations.filter(RelationDeclaration),fqn2PQuery)» 326 «relationDeclarationIndexer.generateRelationIndexers(problem,problem.relations.filter(RelationDeclaration),unitPropagationPatternGenerators,fqn2PQuery)»
259 327
260 ////////// 328 //////////
261 // 1.3 Relation Definition Indexers 329 // 1.3 Relation Definition Indexers
@@ -279,7 +347,7 @@ class PatternGenerator {
279 ////////// 347 //////////
280 // 3.1 Unfinishedness Measured by Multiplicity 348 // 3.1 Unfinishedness Measured by Multiplicity
281 ////////// 349 //////////
282 «unfinishedIndexer.generateUnfinishedMultiplicityQueries(problem,fqn2PQuery)» 350 «unfinishedIndexer.generateUnfinishedMultiplicityQueries(constraints.multiplicityConstraints,fqn2PQuery)»
283 351
284 ////////// 352 //////////
285 // 3.2 Unfinishedness Measured by WF Queries 353 // 3.2 Unfinishedness Measured by WF Queries
@@ -301,7 +369,24 @@ class PatternGenerator {
301 ////////// 369 //////////
302 // 4.3 Relation refinement 370 // 4.3 Relation refinement
303 ////////// 371 //////////
304 «relationRefinementGenerator.generateRefineReference(problem)» 372 «relationRefinementGenerator.generateRefineReference(problem, unitPropagationPatternGenerators)»
373
374 //////////
375 // 5 Hints
376 //////////
377 «FOR hint : hints»
378 «hint.getAdditionalPatterns(this, fqn2PQuery)»
379 «ENDFOR»
380 «FOR generator : unitPropagationPatternGenerators»
381 «generator.getAdditionalPatterns(this, fqn2PQuery)»
382 «ENDFOR»
383
384 //////////
385 // 6 Unit Propagations
386 //////////
305 ''' 387 '''
388 val up = unitPropagationPreconditionGenerator.generateUnitPropagationRules(problem,problem.relations.filter(RelationDefinition),fqn2PQuery)
389 val second = up.definitions
390 return new PatternGeneratorResult(first+second,up.constraint2MustPreconditionName,up.constraint2CurrentPreconditionName)
306 } 391 }
307} 392}
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 0e13a5e1..2e786286 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
@@ -1,97 +1,171 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns 1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns
2 2
3import com.google.common.collect.ImmutableSet
3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation 4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration 5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDefinition
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type 7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
6import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem 8import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
9import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality
7import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics 10import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeAnalysis 11import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeAnalysis
9import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeAnalysisResult 12import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeAnalysisResult
10import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeInferenceMethod 13import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeInferenceMethod
14import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeConstraintHint
15import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.RelationConstraints
16import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.RelationMultiplicityConstraint
17import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy
11import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.util.ParseUtil 18import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.util.ParseUtil
12import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 19import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
13import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace 20import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace
21import java.util.Collection
22import java.util.HashMap
14import java.util.Map 23import java.util.Map
24import java.util.Set
15import org.eclipse.viatra.query.runtime.api.IPatternMatch 25import org.eclipse.viatra.query.runtime.api.IPatternMatch
16import org.eclipse.viatra.query.runtime.api.IQuerySpecification 26import org.eclipse.viatra.query.runtime.api.IQuerySpecification
17import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher 27import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
28import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint
18import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery 29import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
19import org.eclipse.xtend.lib.annotations.Data 30import org.eclipse.xtend.lib.annotations.Data
20 31
21import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* 32import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
22import java.util.Collection
23import java.util.Set
24 33
25@Data class GeneratedPatterns { 34@Data class GeneratedPatterns {
26 public Map<Relation, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidWFQueries 35 public Map<Relation, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidWFQueries
27 public Map<Relation, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFQueries 36 public Map<Relation, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFQueries
28 public Map<Relation, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedMulticiplicityQueries 37 public Map<RelationMultiplicityConstraint, UnifinishedMultiplicityQueries> multiplicityConstraintQueries
29 public Map<ObjectCreationPrecondition, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> refineObjectQueries 38 public IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hasElementInContainmentQuery
30 public Map<? extends Type, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> refineTypeQueries 39 public Map<ObjectCreationPrecondition, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> refineObjectQueries
31 public Map<Pair<RelationDeclaration, Relation>, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> refinerelationQueries 40 public Map<? extends Type, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> refineTypeQueries
41 public Map<Pair<RelationDeclaration, Relation>, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> refineRelationQueries
42 public Map<Pair<RelationDeclaration, Relation>, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> mustRelationPropagationQueries
43 public Map<PConstraint, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> mustUnitPropagationPreconditionPatterns
44 public Map<PConstraint, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> currentUnitPropagationPreconditionPatterns
45 public Map<RelationDefinition, ModalPatternQueries> modalRelationQueries
32 public Collection<IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> allQueries 46 public Collection<IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> allQueries
33} 47}
34 48
49@Data
50class ModalPatternQueries {
51 val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> mayQuery
52 val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> mustQuery
53 val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> currentQuery
54}
55
56@Data
57class UnifinishedMultiplicityQueries {
58 val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> existingMultiplicityQuery
59 val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> existingInverseMultiplicityQuery
60
61 def Set<IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> getAllQueries() {
62 val builder = ImmutableSet.builder
63 if (existingMultiplicityQuery !== null) {
64 builder.add(existingMultiplicityQuery)
65 }
66 if (existingInverseMultiplicityQuery !== null) {
67 builder.add(existingInverseMultiplicityQuery)
68 }
69 builder.build
70 }
71}
72
35class PatternProvider { 73class PatternProvider {
36
37 val TypeAnalysis typeAnalysis = new TypeAnalysis 74 val TypeAnalysis typeAnalysis = new TypeAnalysis
38 75
39 public def generateQueries( 76 def generateQueries(LogicProblem problem, PartialInterpretation emptySolution, ModelGenerationStatistics statistics,
40 LogicProblem problem, 77 Set<PQuery> existingQueries, ReasonerWorkspace workspace, TypeInferenceMethod typeInferenceMethod,
41 PartialInterpretation emptySolution, 78 ScopePropagatorStrategy scopePropagatorStrategy, RelationConstraints relationConstraints,
42 ModelGenerationStatistics statistics, 79 Collection<LinearTypeConstraintHint> hints,
43 Set<PQuery> existingQueries, 80 Collection<UnitPropagationPatternGenerator> unitPropagationPatternGenerators, boolean writeToFile) {
44 ReasonerWorkspace workspace,
45 TypeInferenceMethod typeInferenceMethod,
46 boolean writeToFile)
47 {
48 val fqn2Query = existingQueries.toMap[it.fullyQualifiedName] 81 val fqn2Query = existingQueries.toMap[it.fullyQualifiedName]
49 val PatternGenerator patternGenerator = new PatternGenerator(typeInferenceMethod) 82 val PatternGenerator patternGenerator = new PatternGenerator(typeInferenceMethod, scopePropagatorStrategy)
50 val typeAnalysisResult = if(patternGenerator.requiresTypeAnalysis) { 83 val typeAnalysisResult = if (patternGenerator.requiresTypeAnalysis) {
51 val startTime = System.nanoTime 84 val startTime = System.nanoTime
52 val result = typeAnalysis.performTypeAnalysis(problem,emptySolution) 85 val result = typeAnalysis.performTypeAnalysis(problem, emptySolution)
53 val typeAnalysisTime = System.nanoTime - startTime 86 val typeAnalysisTime = System.nanoTime - startTime
54 statistics.PreliminaryTypeAnalisisTime = typeAnalysisTime 87 statistics.preliminaryTypeAnalisisTime = typeAnalysisTime
55 result 88 result
56 } else { 89 } else {
57 null 90 null
58 } 91 }
59 val baseIndexerFile = patternGenerator.transformBaseProperties(problem,emptySolution,fqn2Query,typeAnalysisResult) 92 val patternGeneratorResult = patternGenerator.transformBaseProperties(problem, emptySolution, fqn2Query,
60 if(writeToFile) { 93 typeAnalysisResult, relationConstraints, hints, unitPropagationPatternGenerators)
61 workspace.writeText('''generated3valued.vql_deactivated''',baseIndexerFile) 94 if (writeToFile) {
95 workspace.writeText('''generated3valued.vql_deactivated''', patternGeneratorResult.patternText)
62 } 96 }
63 val ParseUtil parseUtil = new ParseUtil 97 val ParseUtil parseUtil = new ParseUtil
64 val generatedQueries = parseUtil.parse(baseIndexerFile) 98 val generatedQueries = parseUtil.parse(patternGeneratorResult.patternText)
65 val runtimeQueries = calclulateRuntimeQueries(patternGenerator,problem,emptySolution,typeAnalysisResult,generatedQueries); 99 val runtimeQueries = calclulateRuntimeQueries(patternGenerator, problem, emptySolution, typeAnalysisResult,
100 patternGeneratorResult.constraint2MustPreconditionName,
101 patternGeneratorResult.constraint2CurrentPreconditionName, relationConstraints,
102 unitPropagationPatternGenerators, generatedQueries)
66 return runtimeQueries 103 return runtimeQueries
67 } 104 }
68 105
69 private def GeneratedPatterns calclulateRuntimeQueries( 106 private def GeneratedPatterns calclulateRuntimeQueries(
70 PatternGenerator patternGenerator, 107 PatternGenerator patternGenerator,
71 LogicProblem problem, 108 LogicProblem problem,
72 PartialInterpretation emptySolution, 109 PartialInterpretation emptySolution,
73 TypeAnalysisResult typeAnalysisResult, 110 TypeAnalysisResult typeAnalysisResult,
74 Map<String, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> queries 111 HashMap<PConstraint, String> mustUnitPropagationTrace,
112 HashMap<PConstraint, String> currentUnitPropagationTrace,
113 RelationConstraints relationConstraints,
114 Collection<UnitPropagationPatternGenerator> unitPropagationPatternGenerators,
115 Map<String, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> queries
75 ) { 116 ) {
76 val Map<Relation, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> 117 val Map<Relation, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidWFQueries = patternGenerator.
77 invalidWFQueries = patternGenerator.invalidIndexer.getInvalidateByWfQueryNames(problem).mapValues[it.lookup(queries)] 118 invalidIndexer.getInvalidateByWfQueryNames(problem).mapValues[it.lookup(queries)]
78 val Map<Relation, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> 119 val Map<Relation, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFQueries = patternGenerator.
79 unfinishedWFQueries = patternGenerator.unfinishedIndexer.getUnfinishedWFQueryNames(problem).mapValues[it.lookup(queries)] 120 unfinishedIndexer.getUnfinishedWFQueryNames(problem).mapValues[it.lookup(queries)]
80 val Map<Relation, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> 121
81 unfinishedMultiplicityQueries = patternGenerator.unfinishedIndexer.getUnfinishedMultiplicityQueries(problem).mapValues[it.lookup(queries)] 122 val unfinishedMultiplicities = patternGenerator.unfinishedIndexer.getUnfinishedMultiplicityQueries(
82 val Map<ObjectCreationPrecondition, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> 123 relationConstraints.multiplicityConstraints)
83 refineObjectsQueries = patternGenerator.typeRefinementGenerator.getRefineObjectQueryNames(problem,emptySolution,typeAnalysisResult).mapValues[it.lookup(queries)] 124 val multiplicityConstraintQueries = unfinishedMultiplicities.mapValues [
84 val Map<? extends Type, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> 125 new UnifinishedMultiplicityQueries(existingMultiplicityQueryName?.lookup(queries),
85 refineTypeQueries = patternGenerator.typeRefinementGenerator.getRefineTypeQueryNames(problem,emptySolution,typeAnalysisResult).mapValues[it.lookup(queries)] 126 existingInverseMultiplicityQueryName?.lookup(queries))
86 val Map<Pair<RelationDeclaration, Relation>, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> 127 ]
87 refineRelationQueries = patternGenerator.relationRefinementGenerator.getRefineRelationQueries(problem).mapValues[it.lookup(queries)] 128 val hasElementInContainmentQuery = patternGenerator.typeRefinementGenerator.hasElementInContainmentName.lookup(
129 queries)
130
131 val Map<ObjectCreationPrecondition, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> refineObjectsQueries = patternGenerator.
132 typeRefinementGenerator.getRefineObjectQueryNames(problem, emptySolution, typeAnalysisResult).mapValues [
133 it.lookup(queries)
134 ]
135 val Map<? extends Type, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> refineTypeQueries = patternGenerator.
136 typeRefinementGenerator.getRefineTypeQueryNames(problem, emptySolution, typeAnalysisResult).mapValues [
137 it.lookup(queries)
138 ]
139 val Map<Pair<RelationDeclaration, Relation>, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> refineRelationQueries = patternGenerator.
140 relationRefinementGenerator.getRefineRelationQueries(problem).mapValues[it.lookup(queries)]
141 val Map<Pair<RelationDeclaration, Relation>, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> mustRelationPropagationQueries = patternGenerator.
142 relationRefinementGenerator.getMustPropagationQueries(problem, unitPropagationPatternGenerators).mapValues[it.lookup(queries)]
143 val Map<PConstraint, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> mustUnitPropagationPreconditionPatterns = mustUnitPropagationTrace.
144 mapValues[it.lookup(queries)]
145 val Map<PConstraint, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> currentUnitPropagationPreconditionPatterns = currentUnitPropagationTrace.
146 mapValues[it.lookup(queries)]
147
148 val modalRelationQueries = problem.relations.filter(RelationDefinition).toMap([it], [ relationDefinition |
149 val indexer = patternGenerator.relationDefinitionIndexer
150 new ModalPatternQueries(
151 indexer.relationDefinitionName(relationDefinition, Modality.MAY).lookup(queries),
152 indexer.relationDefinitionName(relationDefinition, Modality.MUST).lookup(queries),
153 indexer.relationDefinitionName(relationDefinition, Modality.CURRENT).lookup(queries)
154 )
155 ])
156
88 return new GeneratedPatterns( 157 return new GeneratedPatterns(
89 invalidWFQueries, 158 invalidWFQueries,
90 unfinishedWFQueries, 159 unfinishedWFQueries,
91 unfinishedMultiplicityQueries, 160 multiplicityConstraintQueries,
161 hasElementInContainmentQuery,
92 refineObjectsQueries, 162 refineObjectsQueries,
93 refineTypeQueries, 163 refineTypeQueries,
94 refineRelationQueries, 164 refineRelationQueries,
165 mustRelationPropagationQueries,
166 mustUnitPropagationPreconditionPatterns,
167 currentUnitPropagationPreconditionPatterns,
168 modalRelationQueries,
95 queries.values 169 queries.values
96 ) 170 )
97 } 171 }
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDeclarationIndexer.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDeclarationIndexer.xtend
index f384cd50..23ba3cad 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDeclarationIndexer.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDeclarationIndexer.xtend
@@ -1,10 +1,13 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns 1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns
2 2
3import com.google.common.collect.ImmutableMap
4import com.google.common.collect.ImmutableSet
3import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.UpperMultiplicityAssertion 5import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.UpperMultiplicityAssertion
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation 6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration 7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
6import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem 8import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
7import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality 9import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality
10import java.util.Collection
8import java.util.HashMap 11import java.util.HashMap
9import java.util.List 12import java.util.List
10import java.util.Map 13import java.util.Map
@@ -14,41 +17,40 @@ import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
14 17
15class RelationDeclarationIndexer { 18class RelationDeclarationIndexer {
16 val PatternGenerator base; 19 val PatternGenerator base;
17 20
18 new(PatternGenerator base) { 21 new(PatternGenerator base) {
19 this.base = base 22 this.base = base
20 } 23 }
21 24
22 public def generateRelationIndexers(LogicProblem problem, Iterable<RelationDeclaration> relations, Map<String,PQuery> fqn2PQuery) { 25 def generateRelationIndexers(LogicProblem problem, Iterable<RelationDeclaration> relations,
26 Iterable<UnitPropagationPatternGenerator> unitPropagationPatternGenerators, Map<String, PQuery> fqn2PQuery) {
23 val upperMultiplicities = new HashMap 27 val upperMultiplicities = new HashMap
24 problem.annotations.filter(UpperMultiplicityAssertion).forEach[ 28 problem.annotations.filter(UpperMultiplicityAssertion).forEach [
25 upperMultiplicities.put(it.relation,it.upper) 29 upperMultiplicities.put(it.relation, it.upper)
26 ] 30 ]
27 31 val mustNotRelations = ImmutableMap.copyOf(unitPropagationPatternGenerators.flatMap[mustNotPatterns.entrySet].
32 groupBy[key].mapValues[ImmutableSet.copyOf(map[value])])
33
28 return ''' 34 return '''
29 «FOR relation : relations» 35 «FOR relation : relations»
30 «IF base.isDerived(relation)» 36 «IF base.isDerived(relation)»
31 «generateDerivedMustRelation(problem,relation,base.getDerivedDefinition(relation).patternFullyQualifiedName.lookup(fqn2PQuery))» 37 «generateDerivedMustRelation(problem,relation,base.getDerivedDefinition(relation).patternFullyQualifiedName.lookup(fqn2PQuery))»
32 «generateDerivedMayRelation(problem,relation,base.getDerivedDefinition(relation).patternFullyQualifiedName.lookup(fqn2PQuery))» 38 «generateDerivedMayRelation(problem,relation,base.getDerivedDefinition(relation).patternFullyQualifiedName.lookup(fqn2PQuery))»
33 «ELSE» 39 «ELSE»
34 «generateMustRelation(problem,relation)» 40 «generateMustRelation(problem, relation)»
35 «generateMayRelation(problem,relation,upperMultiplicities,base.getContainments(problem),base.getInverseRelations(problem),fqn2PQuery)» 41 «generateMayRelation(problem, relation, upperMultiplicities, base.getContainments(problem), base.getInverseRelations(problem), mustNotRelations.get(relation) ?: emptySet, fqn2PQuery)»
36 «ENDIF» 42 «ENDIF»
37 «ENDFOR» 43 «ENDFOR»
38 ''' 44 '''
39 } 45 }
40 46
41 def private patternName(RelationDeclaration r, Modality modality) { 47 def private patternName(RelationDeclaration r, Modality modality) {
42 '''«modality.name.toLowerCase»InRelation«base.canonizeName(r.name)»''' 48 '''«modality.name.toLowerCase»InRelation«base.canonizeName(r.name)»'''
43 } 49 }
44 50
45 public def referRelation( 51 def referRelation(RelationDeclaration referred, String sourceVariable, String targetVariable,
46 RelationDeclaration referred, 52 Modality modality) '''find «referred.patternName(modality)»(problem,interpretation,«sourceVariable»,«targetVariable»);'''
47 String sourceVariable, 53
48 String targetVariable,
49 Modality modality)
50 '''find «referred.patternName(modality)»(problem,interpretation,«sourceVariable»,«targetVariable»);'''
51
52 def generateMustRelation(LogicProblem problem, RelationDeclaration relation) ''' 54 def generateMustRelation(LogicProblem problem, RelationDeclaration relation) '''
53 /** 55 /**
54 * Matcher for detecting tuples t where []«relation.name»(source,target) 56 * Matcher for detecting tuples t where []«relation.name»(source,target)
@@ -65,59 +67,64 @@ class RelationDeclarationIndexer {
65 BinaryElementRelationLink.param2(link,target); 67 BinaryElementRelationLink.param2(link,target);
66 } 68 }
67 ''' 69 '''
70
68 def generateMayRelation(LogicProblem problem, RelationDeclaration relation, 71 def generateMayRelation(LogicProblem problem, RelationDeclaration relation,
69 Map<Relation, Integer> upperMultiplicities, 72 Map<Relation, Integer> upperMultiplicities, List<Relation> containments,
70 List<Relation> containments, 73 HashMap<Relation, Relation> inverseRelations, Collection<String> mustNotRelations,
71 HashMap<Relation, Relation> inverseRelations, 74 Map<String, PQuery> fqn2PQuery) {
72 Map<String,PQuery> fqn2PQuery)
73 {
74 return ''' 75 return '''
75 /** 76 /**
76 * Matcher for detecting tuples t where <>«relation.name»(source,target) 77 * Matcher for detecting tuples t where <>«relation.name»(source,target)
77 */ 78 */
78 private pattern «relation.patternName(Modality.MAY)»( 79 private pattern «relation.patternName(Modality.MAY)»(
79 problem:LogicProblem, interpretation:PartialInterpretation, 80 problem:LogicProblem, interpretation:PartialInterpretation,
80 source: DefinedElement, target:DefinedElement) 81 source: DefinedElement, target:DefinedElement)
81 { 82 {
82 find interpretation(problem,interpretation); 83 find interpretation(problem,interpretation);
83 // The two endpoint of the link have to exist 84 // The two endpoint of the link have to exist
84 find mayExist(problem, interpretation, source); 85 find mayExist(problem, interpretation, source);
85 find mayExist(problem, interpretation, target); 86 find mayExist(problem, interpretation, target);
86 // Type consistency 87 // Type consistency
87 «base.typeIndexer.referInstanceOfByReference(relation.parameters.get(0),Modality.MAY,"source")» 88 «base.typeIndexer.referInstanceOfByReference(relation.parameters.get(0),Modality.MAY,"source")»
88 «base.typeIndexer.referInstanceOfByReference(relation.parameters.get(1),Modality.MAY,"target")» 89 «base.typeIndexer.referInstanceOfByReference(relation.parameters.get(1),Modality.MAY,"target")»
89 «IF upperMultiplicities.containsKey(relation)» 90 «IF upperMultiplicities.containsKey(relation)»
90 // There are "numberOfExistingReferences" currently existing instances of the reference from the source, 91 // There are "numberOfExistingReferences" currently existing instances of the reference from the source,
91 // the upper bound of the multiplicity should be considered. 92 // the upper bound of the multiplicity should be considered.
92 numberOfExistingReferences == count «referRelation(relation,"source","_",Modality.MUST)» 93 numberOfExistingReferences == count «referRelation(relation,"source","_",Modality.MUST)»
93 check(numberOfExistingReferences < «upperMultiplicities.get(relation)»); 94 numberOfExistingReferences != «upperMultiplicities.get(relation)»;
94 «ENDIF» 95 «ENDIF»
95 «IF inverseRelations.containsKey(relation) && upperMultiplicities.containsKey(inverseRelations.get(relation))» 96 «IF inverseRelations.containsKey(relation) && upperMultiplicities.containsKey(inverseRelations.get(relation))»
96 // There are "numberOfExistingReferences" currently existing instances of the reference to the target, 97 // There are "numberOfExistingReferences" currently existing instances of the reference to the target,
97 // the upper bound of the opposite reference multiplicity should be considered. 98 // the upper bound of the opposite reference multiplicity should be considered.
98 numberOfExistingOppositeReferences == count «base.referRelation(inverseRelations.get(relation),"target","_",Modality.MUST,fqn2PQuery)» 99 numberOfExistingOppositeReferences == count «base.referRelation(inverseRelations.get(relation),"target","_",Modality.MUST,fqn2PQuery)»
99 check(numberOfExistingOppositeReferences < «upperMultiplicities.get(inverseRelations.get(relation))»); 100 numberOfExistingOppositeReferences != «upperMultiplicities.get(inverseRelations.get(relation))»;
100 «ENDIF» 101 «ENDIF»
101 «IF containments.contains(relation)» 102 «IF containments.contains(relation)»
102 // The reference is containment, then a new reference cannot be create if: 103 // The reference is containment, then a new reference cannot be create if:
103 // 1. Multiple parents 104 // 1. Multiple parents
104 neg «base.containmentIndexer.referMustContaint("_","target")» 105 neg «base.containmentIndexer.referMustContaint("_","target")»
105 // 2. Circle in the containment hierarchy 106 // 2. Circle in the containment hierarchy
106 neg «base.containmentIndexer.referTransitiveMustContains("target","source")» 107 neg «base.containmentIndexer.referTransitiveMustContains("target","source")»
107 «ENDIF» 108 «ENDIF»
108 «IF inverseRelations.containsKey(relation) && containments.contains(inverseRelations.get(relation))» 109 «IF inverseRelations.containsKey(relation) && containments.contains(inverseRelations.get(relation))»
109 // The eOpposite of the reference is containment, then a referene cannot be created if 110 // The eOpposite of the reference is containment, then a referene cannot be created if
110 // 1. Multiple parents 111 // 1. Multiple parents
111 neg «base.containmentIndexer.referMustContaint("source","_")» 112 neg «base.containmentIndexer.referMustContaint("source","_")»
112 // 2. Circle in the containment hierarchy 113 // 2. Circle in the containment hierarchy
113 neg «base.containmentIndexer.referTransitiveMustContains("source","target")» 114 neg «base.containmentIndexer.referTransitiveMustContains("source","target")»
114 «ENDIF» 115 «ENDIF»
115 } or { 116 «IF !mustNotRelations.empty»
116 «relation.referRelation("source","target",Modality.MUST)» 117 // ![] unit propagation relations
117 } 118 «FOR mustNotRelation : mustNotRelations»
118 ''' 119 neg find «mustNotRelation»(problem, interpretation, source, target);
120 «ENDFOR»
121 «ENDIF»
122 } or {
123 «relation.referRelation("source","target",Modality.MUST)»
124 }
125 '''
119 } 126 }
120 127
121 def generateDerivedMustRelation(LogicProblem problem, RelationDeclaration relation, PQuery definition) ''' 128 def generateDerivedMustRelation(LogicProblem problem, RelationDeclaration relation, PQuery definition) '''
122 /** 129 /**
123 * Matcher for detecting tuples t where []«relation.name»(source,target) 130 * Matcher for detecting tuples t where []«relation.name»(source,target)
@@ -129,6 +136,7 @@ class RelationDeclarationIndexer {
129 «base.relationDefinitionIndexer.referPattern(definition,#["source","target"],Modality::MUST,true,false)» 136 «base.relationDefinitionIndexer.referPattern(definition,#["source","target"],Modality::MUST,true,false)»
130 } 137 }
131 ''' 138 '''
139
132 def generateDerivedMayRelation(LogicProblem problem, RelationDeclaration relation, PQuery definition) ''' 140 def generateDerivedMayRelation(LogicProblem problem, RelationDeclaration relation, PQuery definition) '''
133 /** 141 /**
134 * Matcher for detecting tuples t where []«relation.name»(source,target) 142 * Matcher for detecting tuples t where []«relation.name»(source,target)
@@ -140,4 +148,4 @@ class RelationDeclarationIndexer {
140 «base.relationDefinitionIndexer.referPattern(definition,#["source","target"],Modality::MAY,true,false)» 148 «base.relationDefinitionIndexer.referPattern(definition,#["source","target"],Modality::MAY,true,false)»
141 } 149 }
142 ''' 150 '''
143} \ No newline at end of file 151}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDefinitionIndexer.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDefinitionIndexer.xtend
index 9723373f..338a9af2 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDefinitionIndexer.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDefinitionIndexer.xtend
@@ -5,38 +5,27 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
5import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.TransfomedViatraQuery 5import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.TransfomedViatraQuery
6import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality 6import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality
7import java.util.Map 7import java.util.Map
8import org.eclipse.emf.ecore.EAttribute
9import org.eclipse.emf.ecore.EEnumLiteral
10import org.eclipse.emf.ecore.EReference
11import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey
12import org.eclipse.viatra.query.runtime.emf.types.EDataTypeInSlotsKey
13import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey
14import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint
15import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable 8import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable
16import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality
17import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter
18import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality
19import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall
20import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure 9import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure
21import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.ConstantValue 10import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PDisjunction
22import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall
23import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint
24import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery 11import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
25 12
26import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* 13import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
27import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.TypeFilterConstraint
28 14
29class RelationDefinitionIndexer { 15class RelationDefinitionIndexer {
30 val PatternGenerator base; 16 public val PatternGenerator base;
17 val PConstraintTransformer constraintTransformer;
31 18
32 new(PatternGenerator base) { 19 new(PatternGenerator base) {
33 this.base = base 20 this.base = base
21 this.constraintTransformer = new PConstraintTransformer(this);
34 } 22 }
35 23
36 public def generateRelationDefinitions( 24 def generateRelationDefinitions(
37 LogicProblem problem, 25 LogicProblem problem,
38 Iterable<RelationDefinition> relations, 26 Iterable<RelationDefinition> relations,
39 Map<String,PQuery> fqn2PQuery) { 27 Map<String,PQuery> fqn2PQuery)
28 {
40 val relation2PQuery = relations.toInvertedMap[ 29 val relation2PQuery = relations.toInvertedMap[
41 annotations.filter(TransfomedViatraQuery).head.patternFullyQualifiedName.lookup(fqn2PQuery) 30 annotations.filter(TransfomedViatraQuery).head.patternFullyQualifiedName.lookup(fqn2PQuery)
42 ] 31 ]
@@ -71,23 +60,24 @@ class RelationDefinitionIndexer {
71 ] 60 ]
72 } 61 }
73 62
74 private def relationDefinitionName(RelationDefinition relation, Modality modality) 63 def String relationDefinitionName(RelationDefinition relation, Modality modality)
75 '''«modality.name.toLowerCase»InRelation_«base.canonizeName(relation.name)»''' 64 '''«modality.name.toLowerCase»InRelation_«base.canonizeName(relation.name)»'''
76 65
77 private def canonizeName(PVariable v) { 66 def canonizeName(PVariable v) {
78 return '''«IF v.referringConstraints.size == 1»_«ENDIF»var_«v.name.replaceAll("\\W","")»''' 67 return '''«IF v.referringConstraints.size == 1»_«ENDIF»var_«v.name.replaceAll("\\W","")»'''
79 } 68 }
80 69
81 private def transformPattern(RelationDefinition relation, PQuery p, Modality modality) { 70 private def transformPattern(RelationDefinition relation, PQuery p, Modality modality) {
82 try { 71 try {
72 val bodies = (relation.annotations.filter(TransfomedViatraQuery).head.optimizedDisjunction as PDisjunction).bodies
83 return ''' 73 return '''
84 private pattern «relationDefinitionName(relation,modality)»( 74 private pattern «relationDefinitionName(relation,modality)»(
85 problem:LogicProblem, interpretation:PartialInterpretation, 75 problem:LogicProblem, interpretation:PartialInterpretation,
86 «FOR param : p.parameters SEPARATOR ', '»var_«param.name»«ENDFOR») 76 «FOR param : p.parameters SEPARATOR ', '»var_«param.name»«ENDFOR»)
87 «FOR body : p.disjunctBodies.bodies SEPARATOR "or"»{ 77 «FOR body : bodies SEPARATOR "or"»{
88 find interpretation(problem,interpretation); 78 find interpretation(problem,interpretation);
89 «FOR constraint : body.constraints» 79 «FOR constraint : body.constraints»
90 «constraint.transformConstraint(modality)» 80 «this.constraintTransformer.transformConstraint(constraint,modality,relation.annotations.filter(TransfomedViatraQuery).head.variableTrace)»
91 «ENDFOR» 81 «ENDFOR»
92 }«ENDFOR» 82 }«ENDFOR»
93 ''' 83 '''
@@ -104,158 +94,12 @@ class RelationDefinitionIndexer {
104 ''' 94 '''
105 } 95 }
106 96
107 private def toMustMay(Modality modality) { 97 def toMustMay(Modality modality) {
108 if(modality == Modality::MAY) return Modality::MAY 98 if(modality == Modality::MAY) return Modality::MAY
109 else return Modality::MUST 99 else return Modality::MUST
110 } 100 }
111 101
112 def public referPattern(PQuery p, String[] variables, Modality modality, boolean positive, boolean transitive) ''' 102 def referPattern(PQuery p, String[] variables, Modality modality, boolean positive, boolean transitive) '''
113 «IF !positive»neg «ENDIF»find «IF transitive»twoParam_«ENDIF»«modality.name.toLowerCase»InRelation_pattern_«p.fullyQualifiedName.replace('.','_')»«IF transitive»+«ENDIF»(«IF !transitive»problem,interpretation,«ENDIF»«variables.join(',')»); 103 «IF !positive»neg «ENDIF»find «IF transitive»twoParam_«ENDIF»«modality.name.toLowerCase»InRelation_pattern_«p.fullyQualifiedName.replace('.','_')»«IF transitive»+«ENDIF»(«IF !transitive»problem,interpretation,«ENDIF»«variables.join(',')»);
114 ''' 104 '''
115
116 private dispatch def transformConstraint(TypeConstraint constraint, Modality modality) {
117 val touple = constraint.variablesTuple
118 if(touple.size == 1) {
119 val inputKey = constraint.equivalentJudgement.inputKey
120 if(inputKey instanceof EClassTransitiveInstancesKey) {
121 return base.typeIndexer.referInstanceOf(inputKey.emfKey,modality.toMustMay,
122 constraint.getVariableInTuple(0).canonizeName)
123 } else if(inputKey instanceof EDataTypeInSlotsKey){
124 return '''// type constraint is enforced by construction'''
125 }
126
127 } else if(touple.size == 2){
128 val key = (constraint.equivalentJudgement.inputKey as EStructuralFeatureInstancesKey).emfKey
129 if(key instanceof EReference) {
130 return base.referRelationByName(
131 key,
132 constraint.getVariableInTuple(0).canonizeName,
133 constraint.getVariableInTuple(1).canonizeName,
134 modality.toMustMay)
135 } else if (key instanceof EAttribute) {
136 return base.referAttributeByName(key,
137 constraint.getVariableInTuple(0).canonizeName,
138 constraint.getVariableInTuple(1).canonizeName,
139 modality.toMustMay)
140 } else throw new UnsupportedOperationException('''unknown key: «key.class»''')
141 } else {
142 throw new UnsupportedOperationException('''Unsupported touple size: «touple.size»''')
143 }
144 }
145 private dispatch def transformConstraint(TypeFilterConstraint constraint, Modality modality) {
146 val touple = constraint.variablesTuple
147 if(touple.size == 1) {
148 val inputKey = constraint.equivalentJudgement.inputKey
149 if(inputKey instanceof EClassTransitiveInstancesKey) {
150 return base.typeIndexer.referInstanceOf(inputKey.emfKey,modality.toMustMay,
151 (constraint.getVariablesTuple.get(0) as PVariable).canonizeName)
152 } else if(inputKey instanceof EDataTypeInSlotsKey){
153 return '''// type constraint is enforced by construction'''
154 }
155
156 } else if(touple.size == 2){
157 val key = (constraint.equivalentJudgement.inputKey as EStructuralFeatureInstancesKey).emfKey
158 if(key instanceof EReference) {
159 return base.referRelationByName(
160 key,
161 (constraint.getVariablesTuple.get(0) as PVariable).canonizeName,
162 (constraint.getVariablesTuple.get(1) as PVariable).canonizeName,
163 modality.toMustMay)
164 } else if (key instanceof EAttribute) {
165 return base.referAttributeByName(key,
166 (constraint.getVariablesTuple.get(0) as PVariable).canonizeName,
167 (constraint.getVariablesTuple.get(1) as PVariable).canonizeName,
168 modality.toMustMay)
169 } else throw new UnsupportedOperationException('''unknown key: «key.class»''')
170 } else {
171 throw new UnsupportedOperationException('''Unsupported touple size: «touple.size»''')
172 }
173 }
174
175 private dispatch def transformConstraint(Equality equality, Modality modality) {
176 val a = equality.who
177 val b = equality.withWhom
178 transformEquality(modality.toMustMay, a, b)
179 }
180
181 private def CharSequence transformEquality(Modality modality, PVariable a, PVariable b) {
182 if(modality.isMustOrCurrent) '''find mustEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);'''
183 else '''find mayEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);'''
184 }
185
186 private dispatch def transformConstraint(Inequality inequality, Modality modality) {
187 val a = inequality.who
188 val b = inequality.withWhom
189 if(modality.isCurrent) {
190 return '''neg find mustEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);'''
191 } else if(modality.isMust) {
192 return '''neg find mayEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);'''
193 } else { // modality.isMay
194 return '''neg find mustEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);'''
195 }
196 }
197
198 private dispatch def transformConstraint(NegativePatternCall pcall, Modality modality) {
199 val params = (0..<pcall.actualParametersTuple.size).map[index |
200 val variable = pcall.actualParametersTuple.get(index) as PVariable
201 return variable.canonizeName
202 ]
203 return referPattern(pcall.referredQuery,params,modality.dual,false,false)
204 }
205
206 private dispatch def transformConstraint(PositivePatternCall pcall, Modality modality) {
207 val params = (0..<pcall.variablesTuple.size).map[index |
208 val variable = pcall.variablesTuple.get(index) as PVariable
209 return variable.canonizeName
210 ]
211 return referPattern(pcall.referredQuery,params,modality,true,false)
212 }
213 private dispatch def transformConstraint(BinaryTransitiveClosure pcall, Modality modality) {
214 val params = (0..1).map[index |
215 val variable = pcall.getVariableInTuple(index) as PVariable
216 return variable.canonizeName
217 ]
218 return referPattern(pcall.referredQuery,params,modality,true,true)
219 }
220 private dispatch def transformConstraint(ExportedParameter e, Modality modality) {
221 return '''// «e.parameterName» is exported'''
222 }
223 private dispatch def transformConstraint(ConstantValue c, Modality modality) {
224 val target = c.supplierKey
225
226 var String targetString;
227 var String additionalDefinition;
228 if(target instanceof EEnumLiteral) {
229 targetString = '''const_«target.name»_«target.EEnum.name»'''
230 additionalDefinition = '''DefinedElement.name(«targetString»,"«target.name» «target.EEnum.name»"); //LogicProblem.elements(problem,«targetString»);'''
231 } else if(target instanceof Integer) {
232 targetString = '''const_«target»_Integer'''
233 additionalDefinition = '''IntegerElement.value(«targetString»,«target»);'''
234 } else if(target instanceof Boolean) {
235 targetString = '''const_«target»_Boolean'''
236 additionalDefinition = '''BooleanElement.value(«targetString»,«target»);'''
237 } else if(target instanceof String) {
238 targetString = '''const_«target»_String'''
239 additionalDefinition = '''StringElement.value(«targetString»,"«target»");'''
240 } else if(target instanceof Double) {
241 targetString = '''const_«target»_Number'''
242 additionalDefinition = '''RealElement.value(«targetString»,"«target»");'''
243 } else if(target instanceof Float) {
244 targetString = '''const_«target»_Number'''
245 additionalDefinition = '''RealElement.value(«targetString»,"«target»");'''
246 } else {
247 throw new UnsupportedOperationException('''Unknown constant type: «target.class»''')
248 }
249
250 val source = c.variablesTuple
251 var String sourceName
252 if(source.size == 1)
253 sourceName = (source.get(0) as PVariable).canonizeName
254 else throw new UnsupportedOperationException("unknown source")
255 return '''«sourceName» == «targetString»;«additionalDefinition»''';
256 }
257
258 private dispatch def transformConstraint(PConstraint c, Modality modality) {
259 throw new UnsupportedOperationException('''Unknown constraint type: "«c.class.name»"!''')
260 }
261} \ No newline at end of file 105} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationRefinementGenerator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationRefinementGenerator.xtend
index f9e9baea..6f5f2402 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationRefinementGenerator.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationRefinementGenerator.xtend
@@ -1,85 +1,93 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns 1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns
2 2
3import com.google.common.collect.ImmutableList
4import com.google.common.collect.ImmutableMap
5import com.google.common.collect.ImmutableSet
3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation 6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration 7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
5import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem 8import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
6import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality 9import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality
10import java.util.Collection
7import java.util.LinkedList 11import java.util.LinkedList
8import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference 12import java.util.Map
13import java.util.Set
14import org.eclipse.xtend2.lib.StringConcatenationClient
9 15
10class RelationRefinementGenerator { 16class RelationRefinementGenerator {
11 PatternGenerator base; 17 PatternGenerator base;
12 public new(PatternGenerator base) { 18
19 new(PatternGenerator base) {
13 this.base = base 20 this.base = base
14 } 21 }
15 22
16 def CharSequence generateRefineReference(LogicProblem p) { 23 def CharSequence generateRefineReference(LogicProblem p,
17 return ''' 24 Collection<UnitPropagationPatternGenerator> unitPropagationPatternGenerators) {
18 «FOR relationRefinement: this.getRelationRefinements(p)» 25 val mustRelations = getMustRelations(unitPropagationPatternGenerators)
19 pattern «relationRefinementQueryName(relationRefinement.key,relationRefinement.value)»( 26
20 problem:LogicProblem, interpretation:PartialInterpretation, 27 '''
21 relationIterpretation:PartialRelationInterpretation«IF relationRefinement.value != null», oppositeInterpretation:PartialRelationInterpretation«ENDIF», 28 «FOR relationRefinement : this.getRelationRefinements(p)»
22 from: DefinedElement, to: DefinedElement) 29 pattern «relationRefinementQueryName(relationRefinement.key,relationRefinement.value)»(
23 { 30 problem:LogicProblem, interpretation:PartialInterpretation,
24 find interpretation(problem,interpretation); 31 relationIterpretation:PartialRelationInterpretation«IF relationRefinement.value !== null», oppositeInterpretation:PartialRelationInterpretation«ENDIF»,
25 PartialInterpretation.partialrelationinterpretation(interpretation,relationIterpretation); 32 from: DefinedElement, to: DefinedElement)
26 PartialRelationInterpretation.interpretationOf.name(relationIterpretation,"«relationRefinement.key.name»"); 33 {
27 «IF relationRefinement.value != null» 34 find interpretation(problem,interpretation);
28 PartialInterpretation.partialrelationinterpretation(interpretation,oppositeInterpretation); 35 PartialInterpretation.partialrelationinterpretation(interpretation,relationIterpretation);
29 PartialRelationInterpretation.interpretationOf.name(oppositeInterpretation,"«relationRefinement.value.name»"); 36 PartialRelationInterpretation.interpretationOf.name(relationIterpretation,"«relationRefinement.key.name»");
30 «ENDIF» 37 «IF relationRefinement.value !== null»
31 find mustExist(problem, interpretation, from); 38 PartialInterpretation.partialrelationinterpretation(interpretation,oppositeInterpretation);
32 find mustExist(problem, interpretation, to); 39 PartialRelationInterpretation.interpretationOf.name(oppositeInterpretation,"«relationRefinement.value.name»");
33 «base.typeIndexer.referInstanceOfByReference(relationRefinement.key.parameters.get(0), Modality::MUST,"from")» 40 «ENDIF»
34 «base.typeIndexer.referInstanceOfByReference(relationRefinement.key.parameters.get(1), Modality::MUST,"to")» 41 find mustExist(problem, interpretation, from);
35 «base.relationDeclarationIndexer.referRelation(relationRefinement.key,"from","to",Modality.MAY)» 42 find mustExist(problem, interpretation, to);
36 neg «base.relationDeclarationIndexer.referRelation(relationRefinement.key,"from","to",Modality.MUST)» 43 «base.typeIndexer.referInstanceOfByReference(relationRefinement.key.parameters.get(0), Modality::MUST,"from")»
37 } 44 «base.typeIndexer.referInstanceOfByReference(relationRefinement.key.parameters.get(1), Modality::MUST,"to")»
38 «ENDFOR» 45 «base.relationDeclarationIndexer.referRelation(relationRefinement.key,"from","to",Modality.MAY)»
46 neg «base.relationDeclarationIndexer.referRelation(relationRefinement.key,"from","to",Modality.MUST)»
47 }
48
49 «IF isMustPropagationQueryNeeded(relationRefinement.key, relationRefinement.value, mustRelations)»
50 pattern «mustPropagationQueryName(relationRefinement.key)»(
51 problem:LogicProblem, interpretation:PartialInterpretation,
52 relationIterpretation:PartialRelationInterpretation«IF relationRefinement.value !== null», oppositeInterpretation:PartialRelationInterpretation«ENDIF»,
53 from: DefinedElement, to: DefinedElement)
54 «FOR body : getMustPropagationBodies(relationRefinement.key, relationRefinement.value, mustRelations) SEPARATOR " or "»
55 {
56 «referRefinementQuery(relationRefinement.key, relationRefinement.value, "relationIterpretation", "oppositeInterpretation", "from", "to")»
57 «body»
58 }
59 «ENDFOR»
60 «ENDIF»
61 «ENDFOR»
39 ''' 62 '''
40 } 63 }
41 64
42 def String relationRefinementQueryName(RelationDeclaration relation, Relation inverseRelation) { 65 def String relationRefinementQueryName(RelationDeclaration relation, Relation inverseRelation) {
43 '''«IF inverseRelation != null 66 '''«IF inverseRelation !== null»refineRelation_«base.canonizeName(relation.name)»_and_«base.canonizeName(inverseRelation.name)»«ELSE»refineRelation_«base.canonizeName(relation.name)»«ENDIF»'''
44 »refineRelation_«base.canonizeName(relation.name)»_and_«base.canonizeName(inverseRelation.name)»«
45 ELSE
46 »refineRelation_«base.canonizeName(relation.name)»«ENDIF»'''
47 } 67 }
48 68
69 def String mustPropagationQueryName(RelationDeclaration relation) {
70 '''mustPropagation_«base.canonizeName(relation.name)»'''
71 }
72
49 def referRefinementQuery(RelationDeclaration relation, Relation inverseRelation, String relInterpretationName, 73 def referRefinementQuery(RelationDeclaration relation, Relation inverseRelation, String relInterpretationName,
50 String inverseInterpretationName, String sourceName, String targetName) 74 String inverseInterpretationName, String sourceName,
51 '''find «this.relationRefinementQueryName(relation,inverseRelation)»(problem, interpretation, «relInterpretationName», «IF inverseRelation != null»inverseInterpretationName, «ENDIF»«sourceName», «targetName»);''' 75 String targetName) '''find «this.relationRefinementQueryName(relation,inverseRelation)»(problem, interpretation, «relInterpretationName», «IF inverseRelation !== null»«inverseInterpretationName», «ENDIF»«sourceName», «targetName»);'''
52 76
53 def getRefineRelationQueries(LogicProblem p) { 77 def getRefineRelationQueries(LogicProblem p) {
54// val containmentRelations = p.containmentHierarchies.map[containmentRelations].flatten.toSet 78 getRelationRefinements(p).toInvertedMap[relationRefinementQueryName(it.key, it.value)]
55// p.relations.filter(RelationDeclaration).filter[!containmentRelations.contains(it)].toInvertedMap['''refineRelation_«base.canonizeName(it.name)»''']
56 /*
57 val res = new LinkedHashMap
58 for(relation: getRelationRefinements(p)) {
59 if(inverseRelations.containsKey(relation)) {
60 val name = '''refineRelation_«base.canonizeName(relation.name)»_and_«base.canonizeName(inverseRelations.get(relation).name)»'''
61 res.put(relation -> inverseRelations.get(relation),name)
62 } else {
63 val name = '''refineRelation_«base.canonizeName(relation.name)»'''
64 res.put(relation -> null,name)
65 }
66 }
67 return res*/
68
69 getRelationRefinements(p).toInvertedMap[relationRefinementQueryName(it.key,it.value)]
70 } 79 }
71
72 80
73 def getRelationRefinements(LogicProblem p) { 81 def getRelationRefinements(LogicProblem p) {
74 val inverses = base.getInverseRelations(p) 82 val inverses = base.getInverseRelations(p)
75 val containments = base.getContainments(p) 83 val containments = base.getContainments(p)
76 val list = new LinkedList 84 val list = new LinkedList
77 for(relation : p.relations.filter(RelationDeclaration)) { 85 for (relation : p.relations.filter(RelationDeclaration)) {
78 if(!containments.contains(relation)) { 86 if (!containments.contains(relation)) {
79 if(inverses.containsKey(relation)) { 87 if (inverses.containsKey(relation)) {
80 val inverse = inverses.get(relation) 88 val inverse = inverses.get(relation)
81 if(!containments.contains(inverse)) { 89 if (!containments.contains(inverse)) {
82 if(base.isRepresentative(relation,inverse)) { 90 if (base.isRepresentative(relation, inverse)) {
83 list += (relation -> inverse) 91 list += (relation -> inverse)
84 } 92 }
85 } 93 }
@@ -90,4 +98,54 @@ class RelationRefinementGenerator {
90 } 98 }
91 return list 99 return list
92 } 100 }
93} \ No newline at end of file 101
102 def getMustPropagationQueries(LogicProblem p,
103 Collection<UnitPropagationPatternGenerator> unitPropagationPatternGenerators) {
104 val refinements = getRelationRefinements(p)
105 val mustRelations = getMustRelations(unitPropagationPatternGenerators)
106 refinements.filter[isMustPropagationQueryNeeded(key, value, mustRelations)].toInvertedMap [
107 mustPropagationQueryName(key)
108 ]
109 }
110
111 private def getMustRelations(Collection<UnitPropagationPatternGenerator> unitPropagationPatternGenerators) {
112 ImmutableMap.copyOf(unitPropagationPatternGenerators.flatMap[mustPatterns.entrySet].groupBy[key].mapValues [
113 ImmutableSet.copyOf(map[value])
114 ])
115 }
116
117 private def isMustPropagationQueryNeeded(Relation relation, Relation inverseRelation,
118 Map<Relation, ? extends Set<String>> mustRelations) {
119 val mustSet = mustRelations.get(relation)
120 if (mustSet !== null && !mustSet.empty) {
121 return true
122 }
123 if (inverseRelation !== null) {
124 val inverseMustSet = mustRelations.get(inverseRelation)
125 if (inverseMustSet !== null && !inverseMustSet.empty) {
126 return true
127 }
128 }
129 false
130 }
131
132 private def getMustPropagationBodies(Relation relation, Relation inverseRelation,
133 Map<Relation, ? extends Set<String>> mustRelations) {
134 val builder = ImmutableList.<StringConcatenationClient>builder()
135 val mustSet = mustRelations.get(relation)
136 if (mustSet !== null) {
137 for (refinementQuery : mustSet) {
138 builder.add('''find «refinementQuery»(problem, interpretation, from, to);''')
139 }
140 }
141 if (inverseRelation !== null && inverseRelation != relation) {
142 val inverseMustSet = mustRelations.get(inverseRelation)
143 if (inverseMustSet !== null) {
144 for (refinementQuery : inverseMustSet) {
145 builder.add('''find «refinementQuery»(problem, interpretation, to, from);''')
146 }
147 }
148 }
149 builder.build
150 }
151}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeIndexer.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeIndexer.xtend
index d1d57189..e4e2aa30 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeIndexer.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeIndexer.xtend
@@ -1,52 +1,126 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns 1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns
2 2
3import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
5import org.eclipse.emf.ecore.EClass
6import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeAnalysisResult
9import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference
10import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference 3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference
11import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntTypeReference 5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntTypeReference
12import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference 6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference
13import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.StringTypeReference 7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.StringTypeReference
8import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
9import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
10import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality
11import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeAnalysisResult
12import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
14import java.math.BigDecimal 13import java.math.BigDecimal
14import org.eclipse.emf.ecore.EClass
15import org.eclipse.xtend.lib.annotations.Accessors
16import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
15 17
18@FinalFieldsConstructor
16abstract class TypeIndexer { 19abstract class TypeIndexer {
17 public def CharSequence getRequiredQueries() 20 @Accessors(PROTECTED_GETTER) val PatternGenerator base
18 public def boolean requiresTypeAnalysis() 21
19 public def CharSequence generateInstanceOfQueries(LogicProblem problem,PartialInterpretation emptySolution,TypeAnalysisResult typeAnalysisResult) 22 def CharSequence getRequiredQueries() '''
20 public def CharSequence referInstanceOf(Type type, Modality modality, String variableName) 23 private pattern typeInterpretation(problem:LogicProblem, interpretation:PartialInterpretation, type:TypeDeclaration, typeInterpretation:PartialComplexTypeInterpretation) {
21 public def CharSequence referInstanceOf(EClass type, Modality modality, String variableName) 24 find interpretation(problem,interpretation);
22 25 LogicProblem.types(problem,type);
23 public def dispatch CharSequence referInstanceOfByReference(ComplexTypeReference reference, Modality modality, String variableName) { 26 PartialInterpretation.partialtypeinterpratation(interpretation,typeInterpretation);
24 reference.referred.referInstanceOf(modality,variableName) 27 PartialComplexTypeInterpretation.interpretationOf(typeInterpretation,type);
25 } 28 }
26 public def dispatch CharSequence referInstanceOfByReference(BoolTypeReference reference, Modality modality, String variableName) { 29
30 private pattern directInstanceOf(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement, type:Type) {
31 find interpretation(problem,interpretation);
32 LogicProblem.types(problem,type);
33 TypeDefinition.elements(type,element);
34 } or {
35 find interpretation(problem,interpretation);
36 find typeInterpretation(problem,interpretation,type,typeInterpretation);
37 PartialComplexTypeInterpretation.elements(typeInterpretation,element);
38 }
39
40 private pattern isPrimitive(element: PrimitiveElement) {
41 PrimitiveElement(element);
42 }
43 '''
44
45 def boolean requiresTypeAnalysis()
46
47 def CharSequence generateInstanceOfQueries(LogicProblem problem, PartialInterpretation emptySolution,
48 TypeAnalysisResult typeAnalysisResult) '''
49 «FOR type : problem.types»
50 «problem.generateMustInstenceOf(type, typeAnalysisResult)»
51 «problem.generateMayInstanceOf(type, typeAnalysisResult)»
52 «ENDFOR»
53 '''
54
55 protected def CharSequence generateMustInstenceOf(LogicProblem problem, Type type,
56 TypeAnalysisResult typeAnalysisResult) '''
57 /**
58 * An element must be an instance of type "«type.name»".
59 */
60 private pattern «patternName(type,Modality.MUST)»(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement) {
61 Type.name(type,"«type.name»");
62 find directInstanceOf(problem,interpretation,element,type);
63 }
64 '''
65
66 protected def CharSequence generateMayInstanceOf(LogicProblem problem, Type type,
67 TypeAnalysisResult typeAnalysisResult)
68
69 protected def patternName(Type type,
70 Modality modality) '''«modality.toBase»InstanceOf«base.canonizeName(type.name)»'''
71
72 def referInstanceOf(Type type, Modality modality, String variableName) {
73 '''find «patternName(type,modality)»(problem,interpretation,«variableName»);'''
74 }
75
76 def referInstanceOf(EClass type, Modality modality, String variableName) {
77 '''find «modality.toBase»InstanceOf«base.canonizeName('''«type.name» class''')»(problem,interpretation,«variableName»);'''
78 }
79
80 def dispatch CharSequence referInstanceOfByReference(ComplexTypeReference reference, Modality modality,
81 String variableName) {
82 reference.referred.referInstanceOf(modality, variableName)
83 }
84
85 def dispatch CharSequence referInstanceOfByReference(BoolTypeReference reference, Modality modality,
86 String variableName) {
27 '''BooleanElement(«variableName»);''' 87 '''BooleanElement(«variableName»);'''
28 } 88 }
29 public def dispatch CharSequence referInstanceOfByReference(IntTypeReference reference, Modality modality, String variableName) { 89
90 def dispatch CharSequence referInstanceOfByReference(IntTypeReference reference, Modality modality,
91 String variableName) {
30 '''IntegerElement(«variableName»);''' 92 '''IntegerElement(«variableName»);'''
31 } 93 }
32 public def dispatch CharSequence referInstanceOfByReference(RealTypeReference reference, Modality modality, String variableName) { 94
95 def dispatch CharSequence referInstanceOfByReference(RealTypeReference reference, Modality modality,
96 String variableName) {
33 '''RealElement(«variableName»);''' 97 '''RealElement(«variableName»);'''
34 } 98 }
35 public def dispatch CharSequence referInstanceOfByReference(StringTypeReference reference, Modality modality, String variableName) { 99
100 def dispatch CharSequence referInstanceOfByReference(StringTypeReference reference, Modality modality,
101 String variableName) {
36 '''StringElement(«variableName»);''' 102 '''StringElement(«variableName»);'''
37 } 103 }
38 public def dispatch CharSequence referPrimitiveValue(String variableName, Boolean value) { 104
105 def dispatch CharSequence referPrimitiveValue(String variableName, Boolean value) {
39 '''BooleanElement.value(«variableName»,«value»);''' 106 '''BooleanElement.value(«variableName»,«value»);'''
40 } 107 }
41 public def dispatch CharSequence referPrimitiveValue(String variableName, Integer value) { 108
109 def dispatch CharSequence referPrimitiveValue(String variableName, Integer value) {
42 '''IntegerElement.value(«variableName»,«value»);''' 110 '''IntegerElement.value(«variableName»,«value»);'''
43 } 111 }
44 public def dispatch CharSequence referPrimitiveValue(String variableName, BigDecimal value) { 112
113 def dispatch CharSequence referPrimitiveValue(String variableName, BigDecimal value) {
45 '''RealElement.value(«variableName»,«value»);''' 114 '''RealElement.value(«variableName»,«value»);'''
46 } 115 }
47 ///TODO: de-escaping string literals 116
48 public def dispatch CharSequence referPrimitiveValue(String variableName, String value) { 117 def dispatch CharSequence referPrimitiveValue(String variableName, String value) {
118 // /TODO: de-escaping string literals
49 '''StringElement.value(«variableName»,"«value»");''' 119 '''StringElement.value(«variableName»,"«value»");'''
50 } 120 }
51 121
52} \ No newline at end of file 122 def CharSequence referPrimitiveFilled(String variableName, boolean isFilled) {
123 '''PrimitiveElement.valueSet(«variableName»,«isFilled»);'''
124 }
125}
126
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeIndexerWithPreliminaryTypeAnalysis.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeIndexerWithPreliminaryTypeAnalysis.xtend
index d3af0426..0393b803 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeIndexerWithPreliminaryTypeAnalysis.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeIndexerWithPreliminaryTypeAnalysis.xtend
@@ -4,113 +4,51 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
4import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem 4import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
5import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality 5import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality
6import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeAnalysisResult 6import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeAnalysisResult
7import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeRefinementPrecondition
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
9import org.eclipse.emf.ecore.EClass
10 7
11class TypeIndexerWithPreliminaryTypeAnalysis extends TypeIndexer{ 8class TypeIndexerWithPreliminaryTypeAnalysis extends TypeIndexer {
12 val PatternGenerator base;
13
14 new(PatternGenerator base) { 9 new(PatternGenerator base) {
15 this.base = base 10 super(base)
16 } 11 }
12
17 override requiresTypeAnalysis() { true } 13 override requiresTypeAnalysis() { true }
18 14
19 override getRequiredQueries() ''' 15 protected override generateMayInstanceOf(LogicProblem problem, Type type, TypeAnalysisResult typeAnalysisResult) {
20 private pattern typeInterpretation(problem:LogicProblem, interpretation:PartialInterpretation, type:TypeDeclaration, typeInterpretation:PartialComplexTypeInterpretation) { 16 val precondition = typeAnalysisResult?.mayNewTypePreconditions?.get(type)
21 find interpretation(problem,interpretation); 17 val inhibitorTypes = precondition?.inhibitorTypes
22 LogicProblem.types(problem,type);
23 PartialInterpretation.partialtypeinterpratation(interpretation,typeInterpretation);
24 PartialComplexTypeInterpretation.interpretationOf(typeInterpretation,type);
25 }
26
27 private pattern directInstanceOf(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement, type:Type) {
28 find interpretation(problem,interpretation);
29 LogicProblem.types(problem,type);
30 TypeDefinition.elements(type,element);
31 } or {
32 find interpretation(problem,interpretation);
33 find typeInterpretation(problem,interpretation,type,typeInterpretation);
34 PartialComplexTypeInterpretation.elements(typeInterpretation,element);
35 }
36
37 private pattern isPrimitive(element: PrimitiveElement) {
38 PrimitiveElement(element);
39 }
40 '''
41
42 override generateInstanceOfQueries(LogicProblem problem, PartialInterpretation emptySolution, TypeAnalysisResult typeAnalysisResult) {
43 val mayNewTypePreconditions = typeAnalysisResult.mayNewTypePreconditions
44
45 return '''
46 «FOR type:problem.types»
47 «problem.generateMustInstenceOf(type)»
48 «problem.generateMayInstanceOf(type,mayNewTypePreconditions.get(type))»
49 «ENDFOR»
50 '''
51 }
52
53 private def patternName(Type type, Modality modality)
54 '''«modality.toString.toLowerCase»InstanceOf«base.canonizeName(type.name)»'''
55
56 private def generateMustInstenceOf(LogicProblem problem, Type type) {
57 '''
58 /**
59 * An element must be an instance of type "«type.name»".
60 */
61 private pattern «patternName(type,Modality.MUST)»(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement) {
62 Type.name(type,"«type.name»");
63 find directInstanceOf(problem,interpretation,element,type);
64 }
65 '''
66 }
67
68 private def generateMayInstanceOf(LogicProblem problem, Type type, TypeRefinementPrecondition precondition) {
69 val inhibitorTypes = if(precondition!=null) {
70 precondition.inhibitorTypes
71 } else {
72 null
73 }
74 ''' 18 '''
75 private pattern scopeDisallowsNew«base.canonizeName(type.name)»(problem:LogicProblem, interpretation:PartialInterpretation) { 19 private pattern scopeDisallowsNew«base.canonizeName(type.name)»(problem:LogicProblem, interpretation:PartialInterpretation) {
76 find interpretation(problem,interpretation); 20 find interpretation(problem,interpretation);
77 PartialInterpretation.scopes(interpretation,scope); 21 PartialInterpretation.scopes(interpretation,scope);
78 Scope.targetTypeInterpretation(scope,typeInterpretation); 22 Scope.targetTypeInterpretation(scope,typeInterpretation);
79 Scope.maxNewElements(scope,0); 23 Scope.maxNewElements(scope,0);
80 PartialComplexTypeInterpretation.interpretationOf(typeInterpretation,type); 24 PartialComplexTypeInterpretation.interpretationOf(typeInterpretation,type);
81 Type.name(type,"«type.name»"); 25 Type.name(type,"«type.name»");
82 } 26 }
83 27
84 /** 28 /**
85 * An element may be an instance of type "«type.name»". 29 * An element may be an instance of type "«type.name»".
86 */ 30 */
87 private pattern «patternName(type,Modality.MAY)»(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement) 31 private pattern «patternName(type,Modality.MAY)»(problem:LogicProblem, interpretation:PartialInterpretation, element:DefinedElement)
88 «IF inhibitorTypes !== null»{ 32 «IF inhibitorTypes !== null»
89 find interpretation(problem,interpretation); 33 {
90 PartialInterpretation.newElements(interpretation,element); 34 find interpretation(problem,interpretation);
91 «FOR inhibitorType : inhibitorTypes» 35 PartialInterpretation.newElements(interpretation,element);
92 neg «referInstanceOf(inhibitorType,Modality.MUST,"element")» 36 «FOR inhibitorType : inhibitorTypes»
93 «ENDFOR» 37 neg «referInstanceOf(inhibitorType,Modality.MUST,"element")»
94 neg find scopeDisallowsNew«base.canonizeName(type.name)»(problem, interpretation); 38 «ENDFOR»
95 neg find isPrimitive(element); 39 neg find scopeDisallowsNew«base.canonizeName(type.name)»(problem, interpretation);
96 } or { 40 neg find isPrimitive(element);
97 find interpretation(problem,interpretation); 41 } or {
98 PartialInterpretation.openWorldElements(interpretation,element); 42 find interpretation(problem,interpretation);
99 «FOR inhibitorType : inhibitorTypes» 43 PartialInterpretation.openWorldElements(interpretation,element);
100 neg «referInstanceOf(inhibitorType,Modality.MUST,"element")» 44 «FOR inhibitorType : inhibitorTypes»
101 «ENDFOR» 45 neg «referInstanceOf(inhibitorType,Modality.MUST,"element")»
102 neg find scopeDisallowsNew«base.canonizeName(type.name)»(problem, interpretation); 46 «ENDFOR»
103 neg find isPrimitive(element); 47 neg find scopeDisallowsNew«base.canonizeName(type.name)»(problem, interpretation);
104 } or 48 neg find isPrimitive(element);
105 «ENDIF» 49 } or
106 { «referInstanceOf(type,Modality.MUST,"element")» } 50 «ENDIF»
51 { «referInstanceOf(type,Modality.MUST,"element")» }
107 ''' 52 '''
108 } 53 }
109 54}
110 public override referInstanceOf(Type type, Modality modality, String variableName) {
111 '''find «patternName(type,modality)»(problem,interpretation,«variableName»);'''
112 }
113 public override referInstanceOf(EClass type, Modality modality, String variableName) {
114 '''find «modality.toString.toLowerCase»InstanceOf«base.canonizeName('''«type.name» class''')»(problem,interpretation,«variableName»);'''
115 }
116} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeRefinementGenerator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeRefinementGenerator.xtend
index 7e3fad91..4ef336ae 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeRefinementGenerator.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeRefinementGenerator.xtend
@@ -25,69 +25,76 @@ class ObjectCreationPrecondition {
25 25
26abstract class TypeRefinementGenerator { 26abstract class TypeRefinementGenerator {
27 val protected PatternGenerator base; 27 val protected PatternGenerator base;
28 public new(PatternGenerator base) { 28
29 new(PatternGenerator base) {
29 this.base = base 30 this.base = base
30 } 31 }
31 32
32 public def boolean requiresTypeAnalysis() 33 def boolean requiresTypeAnalysis()
33 public def CharSequence generateRefineObjectQueries(LogicProblem p, PartialInterpretation emptySolution, TypeAnalysisResult typeAnalysisResult) 34
34 public def CharSequence generateRefineTypeQueries(LogicProblem p, PartialInterpretation emptySolution, TypeAnalysisResult typeAnalysisResult) 35 def CharSequence generateRefineObjectQueries(LogicProblem p, PartialInterpretation emptySolution,
35 public def Map<? extends Type, String> getRefineTypeQueryNames(LogicProblem p, PartialInterpretation emptySolution, TypeAnalysisResult typeAnalysisResult) 36 TypeAnalysisResult typeAnalysisResult)
36 37
37 public def getRefineObjectQueryNames(LogicProblem p, PartialInterpretation emptySolution, TypeAnalysisResult typeAnalysisResult) { 38 def CharSequence generateRefineTypeQueries(LogicProblem p, PartialInterpretation emptySolution,
38 val Map<ObjectCreationPrecondition,String> objectCreationQueries = new LinkedHashMap 39 TypeAnalysisResult typeAnalysisResult)
40
41 def Map<? extends Type, String> getRefineTypeQueryNames(LogicProblem p, PartialInterpretation emptySolution,
42 TypeAnalysisResult typeAnalysisResult)
43
44 def getRefineObjectQueryNames(LogicProblem p, PartialInterpretation emptySolution,
45 TypeAnalysisResult typeAnalysisResult) {
46 val Map<ObjectCreationPrecondition, String> objectCreationQueries = new LinkedHashMap
39 val containment = p.containmentHierarchies.head 47 val containment = p.containmentHierarchies.head
40 val inverseRelations = new HashMap 48 val inverseRelations = new HashMap
41 p.annotations.filter(InverseRelationAssertion).forEach[ 49 p.annotations.filter(InverseRelationAssertion).forEach [
42 inverseRelations.put(it.inverseA,it.inverseB) 50 inverseRelations.put(it.inverseA, it.inverseB)
43 inverseRelations.put(it.inverseB,it.inverseA) 51 inverseRelations.put(it.inverseB, it.inverseA)
44 ] 52 ]
45 for(type: p.types.filter(TypeDeclaration).filter[!it.isAbstract]) { 53 for (type : p.types.filter(TypeDeclaration).filter[!it.isAbstract]) {
46 if(containment.typeInContainment(type)) { 54 if (containment.typeInContainment(type)) {
47 for(containmentRelation : containment.containmentRelations.filter[canBeContainedByRelation(it,type)]) { 55 for (containmentRelation : containment.containmentRelations.
48 if(inverseRelations.containsKey(containmentRelation)) { 56 filter[canBeContainedByRelation(it, type)]) {
57 if (inverseRelations.containsKey(containmentRelation)) {
49 objectCreationQueries.put( 58 objectCreationQueries.put(
50 new ObjectCreationPrecondition(containmentRelation,inverseRelations.get(containmentRelation),type), 59 new ObjectCreationPrecondition(containmentRelation,
51 this.patternName(containmentRelation,inverseRelations.get(containmentRelation),type)) 60 inverseRelations.get(containmentRelation), type),
61 this.patternName(containmentRelation, inverseRelations.get(containmentRelation), type))
52 } else { 62 } else {
53 objectCreationQueries.put( 63 objectCreationQueries.put(new ObjectCreationPrecondition(containmentRelation, null, type),
54 new ObjectCreationPrecondition(containmentRelation,null,type), 64 patternName(containmentRelation, null, type))
55 patternName(containmentRelation,null,type))
56 } 65 }
57 } 66 }
58 objectCreationQueries.put( 67 objectCreationQueries.put(new ObjectCreationPrecondition(null, null, type),
59 new ObjectCreationPrecondition(null,null,type), 68 patternName(null, null, type))
60 patternName(null,null,type))
61 } else { 69 } else {
62 objectCreationQueries.put( 70 objectCreationQueries.put(new ObjectCreationPrecondition(null, null, type),
63 new ObjectCreationPrecondition(null,null,type), 71 this.patternName(null, null, type))
64 this.patternName(null,null,type))
65 } 72 }
66 } 73 }
67 return objectCreationQueries 74 return objectCreationQueries
68 } 75 }
69 76
70 protected def canBeContainedByRelation(Relation r, Type t) { 77 protected def canBeContainedByRelation(Relation r, Type t) {
71 if(r.parameters.size==2) { 78 if (r.parameters.size == 2) {
72 val param = r.parameters.get(1) 79 val param = r.parameters.get(1)
73 if(param instanceof ComplexTypeReference) { 80 if (param instanceof ComplexTypeReference) {
74 val allSuperTypes = t.transitiveClosureStar[it.supertypes] 81 val allSuperTypes = t.transitiveClosureStar[it.supertypes]
75 for(superType : allSuperTypes) { 82 for (superType : allSuperTypes) {
76 if(param.referred == superType) return true 83 if(param.referred == superType) return true
77 } 84 }
78 } 85 }
79 } 86 }
80 return false 87 return false
81 } 88 }
82 89
83 private def typeInContainment(ContainmentHierarchy hierarchy, Type type) { 90 private def typeInContainment(ContainmentHierarchy hierarchy, Type type) {
84 val allSuperTypes = type.transitiveClosureStar[it.supertypes] 91 val allSuperTypes = type.transitiveClosureStar[it.supertypes]
85 return allSuperTypes.exists[hierarchy.typesOrderedInHierarchy.contains(it)] 92 return allSuperTypes.exists[hierarchy.typesOrderedInHierarchy.contains(it)]
86 } 93 }
87 94
88 protected def String patternName(Relation containmentRelation, Relation inverseContainment, Type newType) { 95 protected def String patternName(Relation containmentRelation, Relation inverseContainment, Type newType) {
89 if(containmentRelation != null) { 96 if (containmentRelation !== null) {
90 if(inverseContainment != null) { 97 if (inverseContainment !== null) {
91 '''createObject_«base.canonizeName(newType.name)»_by_«base.canonizeName(containmentRelation.name)»_with_«base.canonizeName(inverseContainment.name)»''' 98 '''createObject_«base.canonizeName(newType.name)»_by_«base.canonizeName(containmentRelation.name)»_with_«base.canonizeName(inverseContainment.name)»'''
92 } else { 99 } else {
93 '''createObject_«base.canonizeName(newType.name)»_by_«base.canonizeName(containmentRelation.name)»''' 100 '''createObject_«base.canonizeName(newType.name)»_by_«base.canonizeName(containmentRelation.name)»'''
@@ -96,4 +103,8 @@ abstract class TypeRefinementGenerator {
96 '''createObject_«base.canonizeName(newType.name)»''' 103 '''createObject_«base.canonizeName(newType.name)»'''
97 } 104 }
98 } 105 }
99} \ No newline at end of file 106
107 def hasElementInContainmentName() {
108 "hasElementInContainment"
109 }
110}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeRefinementWithPreliminaryTypeAnalysis.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeRefinementWithPreliminaryTypeAnalysis.xtend
index cbbbcb08..1a81695e 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeRefinementWithPreliminaryTypeAnalysis.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/TypeRefinementWithPreliminaryTypeAnalysis.xtend
@@ -10,7 +10,7 @@ import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.par
10import java.util.HashMap 10import java.util.HashMap
11 11
12class TypeRefinementWithPreliminaryTypeAnalysis extends TypeRefinementGenerator{ 12class TypeRefinementWithPreliminaryTypeAnalysis extends TypeRefinementGenerator{
13 public new(PatternGenerator base) { 13 new(PatternGenerator base) {
14 super(base) 14 super(base)
15 } 15 }
16 override requiresTypeAnalysis() { true } 16 override requiresTypeAnalysis() { true }
@@ -24,7 +24,7 @@ class TypeRefinementWithPreliminaryTypeAnalysis extends TypeRefinementGenerator{
24 inverseRelations.put(it.inverseB,it.inverseA) 24 inverseRelations.put(it.inverseB,it.inverseA)
25 ] 25 ]
26 return ''' 26 return '''
27 private pattern hasElementInContainment(problem:LogicProblem, interpretation:PartialInterpretation) 27 pattern «hasElementInContainmentName»(problem:LogicProblem, interpretation:PartialInterpretation)
28 «FOR type :containment.typesOrderedInHierarchy SEPARATOR "or"»{ 28 «FOR type :containment.typesOrderedInHierarchy SEPARATOR "or"»{
29 find interpretation(problem,interpretation); 29 find interpretation(problem,interpretation);
30 «base.typeIndexer.referInstanceOf(type,Modality.MUST,"root")» 30 «base.typeIndexer.referInstanceOf(type,Modality.MUST,"root")»
@@ -76,7 +76,7 @@ class TypeRefinementWithPreliminaryTypeAnalysis extends TypeRefinementGenerator{
76 typeInterpretation:PartialComplexTypeInterpretation) 76 typeInterpretation:PartialComplexTypeInterpretation)
77 { 77 {
78 find interpretation(problem,interpretation); 78 find interpretation(problem,interpretation);
79 neg find hasElementInContainment(problem,interpretation); 79 neg find «hasElementInContainmentName»(problem,interpretation);
80 PartialInterpretation.partialtypeinterpratation(interpretation,typeInterpretation); 80 PartialInterpretation.partialtypeinterpratation(interpretation,typeInterpretation);
81 PartialComplexTypeInterpretation.interpretationOf.name(typeInterpretation,"«type.name»"); 81 PartialComplexTypeInterpretation.interpretationOf.name(typeInterpretation,"«type.name»");
82 «base.typeIndexer.referInstanceOf(type,Modality.MAY,"newObject")» 82 «base.typeIndexer.referInstanceOf(type,Modality.MAY,"newObject")»
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 ad1c9033..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
@@ -1,85 +1,149 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns 1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns
2 2
3import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.LowerMultiplicityAssertion 3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
4import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem 4import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
5import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.TransformedViatraWellformednessConstraint 5import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality
6import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.RelationMultiplicityConstraint
7import java.util.LinkedHashMap
8import java.util.List
6import java.util.Map 9import java.util.Map
7import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery 10import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
11import org.eclipse.xtend.lib.annotations.Data
8 12
9import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* 13import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
10import java.util.LinkedHashMap 14
11import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality 15@Data
12import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference 16class UnifinishedMultiplicityQueryNames {
17 val String existingMultiplicityQueryName
18 val String existingInverseMultiplicityQueryName
19}
13 20
14class UnfinishedIndexer { 21class UnfinishedIndexer {
15 val PatternGenerator base 22 val PatternGenerator base
16 23 val boolean indexUpperMultiplicities
17 new(PatternGenerator patternGenerator) { 24
25 new(PatternGenerator patternGenerator, boolean indexUpperMultiplicities) {
18 this.base = patternGenerator 26 this.base = patternGenerator
27 this.indexUpperMultiplicities = indexUpperMultiplicities
19 } 28 }
20 29
21 def generateUnfinishedWfQueries(LogicProblem problem, Map<String,PQuery> fqn2PQuery) { 30 def generateUnfinishedWfQueries(LogicProblem problem, Map<String, PQuery> fqn2PQuery) {
22 val wfQueries = base.wfQueries(problem) 31 val wfQueries = base.wfQueries(problem)
23 ''' 32 '''
24 «FOR wfQuery: wfQueries» 33 «FOR wfQuery : wfQueries»
25 pattern unfinishedBy_«base.canonizeName(wfQuery.target.name)»(problem:LogicProblem, interpretation:PartialInterpretation, 34 pattern unfinishedBy_«base.canonizeName(wfQuery.target.name)»(problem:LogicProblem, interpretation:PartialInterpretation,
26 «FOR param : wfQuery.patternFullyQualifiedName.lookup(fqn2PQuery).parameters SEPARATOR ', '»var_«param.name»«ENDFOR») 35 «FOR param : wfQuery.patternFullyQualifiedName.lookup(fqn2PQuery).parameters SEPARATOR ', '»var_«param.name»«ENDFOR»)
27 { 36 {
28 «base.relationDefinitionIndexer.referPattern( 37 «base.relationDefinitionIndexer.referPattern(
29 wfQuery.patternFullyQualifiedName.lookup(fqn2PQuery), 38 wfQuery.patternFullyQualifiedName.lookup(fqn2PQuery),
30 wfQuery.patternFullyQualifiedName.lookup(fqn2PQuery).parameters.map['''var_«it.name»'''], 39 wfQuery.patternFullyQualifiedName.lookup(fqn2PQuery).parameters.map['''var_«it.name»'''],
31 Modality.CURRENT, 40 Modality.CURRENT,
32 true,false)» 41 true,false)»
33 } 42 }
34 «ENDFOR» 43 «ENDFOR»
35 ''' 44 '''
36 } 45 }
46
37 def getUnfinishedWFQueryNames(LogicProblem problem) { 47 def getUnfinishedWFQueryNames(LogicProblem problem) {
38 val wfQueries = base.wfQueries(problem) 48 val wfQueries = base.wfQueries(problem)
39 val map = new LinkedHashMap 49 val map = new LinkedHashMap
40 for(wfQuery : wfQueries) { 50 for (wfQuery : wfQueries) {
41 map.put(wfQuery.target,'''unfinishedBy_«base.canonizeName(wfQuery.target.name)»''') 51 map.put(wfQuery.target, '''unfinishedBy_«base.canonizeName(wfQuery.target.name)»''')
42 } 52 }
43 return map 53 return map
44 } 54 }
45 def generateUnfinishedMultiplicityQueries(LogicProblem problem, Map<String,PQuery> fqn2PQuery) { 55
46 val lowerMultiplicities = base.lowerMultiplicities(problem) 56 def generateUnfinishedMultiplicityQueries(List<RelationMultiplicityConstraint> constraints,
47 return ''' 57 Map<String, PQuery> fqn2PQuery) '''
48 «FOR lowerMultiplicity : lowerMultiplicities» 58 «FOR constraint : constraints»
49 pattern «unfinishedMultiplicityName(lowerMultiplicity)»(problem:LogicProblem, interpretation:PartialInterpretation, relationIterpretation:PartialRelationInterpretation, object:DefinedElement,missingMultiplicity) { 59 «IF constraint.shouldIndexExistingMultiplicites(indexUpperMultiplicities)»
50 find interpretation(problem,interpretation); 60 private pattern «existingMultiplicityName(constraint)»(problem:LogicProblem, interpretation:PartialInterpretation, object:DefinedElement, numberOfExistingReferences:java Integer«IF constraint.shouldIndexRepairMultiplcities(indexUpperMultiplicities)», numberOfRepairMatches: java Integer«ENDIF») {
51 PartialInterpretation.partialrelationinterpretation(interpretation,relationIterpretation); 61 find interpretation(problem,interpretation);
52 PartialRelationInterpretation.interpretationOf.name(relationIterpretation,"«lowerMultiplicity.relation.name»"); 62 find mustExist(problem,interpretation,object);
53 «base.typeIndexer.referInstanceOf(lowerMultiplicity.firstParamTypeOfRelation,Modality::MUST,"object")» 63 «base.typeIndexer.referInstanceOf(constraint.sourceType,Modality::MUST,"object")»
54 numberOfExistingReferences == count «base.referRelation(lowerMultiplicity.relation,"object","_",Modality.MUST,fqn2PQuery)» 64 numberOfExistingReferences == count «base.referRelation(constraint.relation,"object","_",Modality.MUST,fqn2PQuery)»
55 check(numberOfExistingReferences < «lowerMultiplicity.lower»); 65 «IF constraint.shouldIndexRepairMultiplcities(indexUpperMultiplicities)»
56 missingMultiplicity == eval(«lowerMultiplicity.lower»-numberOfExistingReferences); 66 numberOfRepairMatches == count find «repairMatchName(constraint)»(problem, interpretation, object, _);
57 } 67 «ENDIF»
68 }
69 «ENDIF»
70
71 «IF constraint.shouldIndexRepairMatches(indexUpperMultiplicities)»
72 private pattern «repairMatchName(constraint)»(problem:LogicProblem, interpretation:PartialInterpretation, source:DefinedElement, target:DefinedElement) {
73 «IF constraint.containment || constraint.container»
74 «repairMatchFallback(constraint, fqn2PQuery)»
75 «ELSEIF base.isRepresentative(constraint.relation, constraint.inverseRelation) && constraint.relation instanceof RelationDeclaration»
76 «base.relationRefinementGenerator.referRefinementQuery(constraint.relation as RelationDeclaration, constraint.inverseRelation, "_", "_", "source", "target")»
77 «ELSEIF base.isRepresentative(constraint.inverseRelation, constraint.relation) && constraint.inverseRelation instanceof RelationDeclaration»
78 «base.relationRefinementGenerator.referRefinementQuery(constraint.inverseRelation as RelationDeclaration, constraint.relation, "_", "_", "target", "source")»
79 «ELSE»
80 «repairMatchFallback(constraint, fqn2PQuery)»
81 «ENDIF»
82 }
83 «ENDIF»
84
85 «IF constraint.shouldIndexInverseMultiplicites(indexUpperMultiplicities)»
86 private pattern «existingInverseMultiplicityName(constraint)»(problem:LogicProblem, interpretation:PartialInterpretation, object:DefinedElement, numberOfExistingReferences:java Integer, numberOfRepairMatches: java Integer) {
87 find interpretation(problem,interpretation);
88 find mustExist(problem,interpretation,object);
89 «base.typeIndexer.referInstanceOf(constraint.targetType,Modality::MUST,"object")»
90 numberOfExistingReferences == count «base.referRelation(constraint.relation,"_","object",Modality.MUST,fqn2PQuery)»
91 numberOfRepairMatches == count find «repairMatchName(constraint)»(problem, interpretation, _, object);
92 }
93 «ENDIF»
58 «ENDFOR» 94 «ENDFOR»
59 ''' 95 '''
96
97 private def repairMatchFallback(RelationMultiplicityConstraint constraint, Map<String, PQuery> fqn2PQuery) '''
98 find interpretation(problem,interpretation);
99 find mustExist(problem,interpretation,source);
100 «base.typeIndexer.referInstanceOf(constraint.sourceType,Modality::MUST,"source")»
101 find mustExist(problem,interpretation,target);
102 «base.typeIndexer.referInstanceOf(constraint.targetType,Modality::MUST,"target")»
103 neg «base.referRelation(constraint.relation,"source","target",Modality.MUST,fqn2PQuery)»
104 «base.referRelation(constraint.relation,"source","target",Modality.MAY,fqn2PQuery)»
105 '''
106
107 def String existingMultiplicityName(
108 RelationMultiplicityConstraint constraint) '''existingMultiplicity_«base.canonizeName(constraint.relation.name)»'''
109
110 def String existingInverseMultiplicityName(
111 RelationMultiplicityConstraint constraint) '''existingInverseMultiplicity_«base.canonizeName(constraint.relation.name)»'''
112
113 private def String repairMatchName(
114 RelationMultiplicityConstraint constraint) '''repair_«base.canonizeName(constraint.relation.name)»'''
115
116 def getUnfinishedMultiplicityQueries(List<RelationMultiplicityConstraint> constraints) {
117 constraints.toInvertedMap [ constraint |
118 new UnifinishedMultiplicityQueryNames(
119 if (constraint.shouldIndexExistingMultiplicites(indexUpperMultiplicities)) {
120 existingMultiplicityName(constraint)
121 } else {
122 null
123 },
124 if (constraint.shouldIndexInverseMultiplicites(indexUpperMultiplicities)) {
125 existingInverseMultiplicityName(constraint)
126 } else {
127 null
128 }
129 )
130 ]
60 } 131 }
61 def String unfinishedMultiplicityName(LowerMultiplicityAssertion lowerMultiplicityAssertion) 132
62 '''unfinishedLowerMultiplicity_«base.canonizeName(lowerMultiplicityAssertion.relation.name)»''' 133 static def shouldIndexExistingMultiplicites(RelationMultiplicityConstraint it, boolean indexUpperMultiplicities) {
63 134 constrainsUnfinished || (indexUpperMultiplicities && constrainsRemainingContents)
64 def public referUnfinishedMultiplicityQuery(LowerMultiplicityAssertion lowerMultiplicityAssertion)
65 '''find «unfinishedMultiplicityName(lowerMultiplicityAssertion)»(problem, interpretation ,object, missingMultiplicity);'''
66
67 def getFirstParamTypeOfRelation(LowerMultiplicityAssertion lowerMultiplicityAssertion) {
68 val parameters = lowerMultiplicityAssertion.relation.parameters
69 if(parameters.size == 2) {
70 val firstParam = parameters.get(0)
71 if(firstParam instanceof ComplexTypeReference) {
72 return firstParam.referred
73 }
74 }
75 } 135 }
76 136
77 def getUnfinishedMultiplicityQueries(LogicProblem problem) { 137 static def shouldIndexRepairMultiplcities(RelationMultiplicityConstraint it, boolean indexUpperMultiplicities) {
78 val lowerMultiplicities = base.lowerMultiplicities(problem) 138 shouldIndexExistingMultiplicites(indexUpperMultiplicities) && constrainsUnrepairable
79 val map = new LinkedHashMap 139 }
80 for(lowerMultiplicity : lowerMultiplicities) { 140
81 map.put(lowerMultiplicity.relation,unfinishedMultiplicityName(lowerMultiplicity)) 141 static def shouldIndexInverseMultiplicites(RelationMultiplicityConstraint it, boolean indexUpperMultiplicities) {
82 } 142 indexUpperMultiplicities && constrainsRemainingInverse
83 return map 143 }
144
145 static def shouldIndexRepairMatches(RelationMultiplicityConstraint it, boolean indexUpperMultiplicities) {
146 shouldIndexRepairMultiplcities(indexUpperMultiplicities) ||
147 shouldIndexInverseMultiplicites(indexUpperMultiplicities)
84 } 148 }
85} 149}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/UnitPropagationPreconditionGenerator.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/UnitPropagationPreconditionGenerator.xtend
new file mode 100644
index 00000000..400f47bc
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/UnitPropagationPreconditionGenerator.xtend
@@ -0,0 +1,302 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns
2
3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDefinition
5import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
6import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.TransfomedViatraQuery
7import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.PropagationModality
9import java.util.Map
10import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint
11import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable
12import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExpressionEvaluation
13import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
14
15import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
16import java.util.LinkedList
17import java.util.List
18import org.eclipse.xtend.lib.annotations.Data
19import java.util.HashMap
20import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall
21import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall
22import java.util.Comparator
23import java.util.ArrayList
24import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PDisjunction
25import java.util.LinkedHashSet
26
27@Data class UnitPropagation {
28 val PQuery q
29 val PConstraint c
30 val PropagationModality pm
31 val Modality m3
32}
33@Data
34class UnitPropagationPreconditionGenerationResult {
35 List<CharSequence> definitions= new LinkedList
36 Map<UnitPropagation,String> unitPropagation2PatternName = new HashMap
37 Map<PConstraint,String> constraintOccurence2Name = new HashMap
38
39 def registerQuery(PQuery q, PConstraint c, PropagationModality pm, Modality m3, String patternName, CharSequence definition) {
40 val key = new UnitPropagation(q,c,pm,m3)
41 definitions += definition
42 unitPropagation2PatternName.put(key,patternName)
43 }
44 def registerUnsatQuery(PQuery q, PConstraint c, PropagationModality pm, Modality m3) {
45 val key = new UnitPropagation(q,c,pm,m3)
46 unitPropagation2PatternName.put(key,null)
47 }
48 def contains(PQuery q, PConstraint c, PropagationModality pm, Modality m3) {
49 val key = new UnitPropagation(q,c,pm,m3)
50 return unitPropagation2PatternName.containsKey(key)
51 }
52 def getName(PQuery q, PConstraint c, PropagationModality pm, Modality m3) {
53 val key = new UnitPropagation(q,c,pm,m3)
54 return key.lookup(unitPropagation2PatternName)
55 }
56 def isDefined(PQuery q, PConstraint c, PropagationModality pm, Modality m3) {
57 val key = new UnitPropagation(q,c,pm,m3)
58 return unitPropagation2PatternName.get(key) !== null
59 }
60}
61@Data
62class UnitPropagationPreconditionFinalResult {
63 CharSequence definitions
64 HashMap<PConstraint,String> constraint2MustPreconditionName
65 HashMap<PConstraint,String> constraint2CurrentPreconditionName
66}
67
68class UnitPropagationPreconditionGenerator {
69 val PatternGenerator base
70 val PConstraintTransformer constraintTransformer;
71
72 new(PatternGenerator patternGenerator) {
73 this.base = patternGenerator
74 this.constraintTransformer = new PConstraintTransformer(base.relationDefinitionIndexer)
75 }
76
77 def generateUnitPropagationRules(
78 LogicProblem problem,
79 Iterable<RelationDefinition> relations,
80 Map<String,PQuery> fqn2PQuery)
81 {
82 // Create an empty result
83 val res = new UnitPropagationPreconditionGenerationResult
84 val wfs = base.wfQueries(problem)//.map[it.patternPQuery]
85 val Map<PConstraint,List<Pair<String,Integer>>> mainMustPropagationNames = new HashMap
86 val Map<PConstraint,List<Pair<String,Integer>>> mainCurrentPropagationNames = new HashMap
87 for(wf : wfs) {
88 val query = wf.patternPQuery as PQuery
89 val relation = wf.target
90 val allReferredChecks = allReferredConstraints(relation,query).filter(ExpressionEvaluation)
91
92 for(referredCheck : allReferredChecks) {
93 val mustPropagationPrecondition = getOrGeneratePropagationRule(res,relation,query,referredCheck,PropagationModality::UP, Modality::MUST)
94 val currentPropagationPrecondition = getOrGeneratePropagationRule(res,relation,query,referredCheck,PropagationModality::UP, Modality::CURRENT)
95 if(!mainMustPropagationNames.containsKey(referredCheck)) {
96 mainMustPropagationNames.put(referredCheck,new LinkedList)
97 }
98 if(!mainCurrentPropagationNames.containsKey(referredCheck)) {
99 mainCurrentPropagationNames.put(referredCheck,new LinkedList)
100 }
101 if(mustPropagationPrecondition !== null) {
102 mainMustPropagationNames.get(referredCheck).add(mustPropagationPrecondition->query.parameterNames.size)
103 }
104 if(currentPropagationPrecondition !== null) {
105 mainCurrentPropagationNames.get(referredCheck).add(currentPropagationPrecondition->query.parameterNames.size)
106 }
107 }
108 }
109 val preconditions = new LinkedList
110 val constraint2MustPrecondition = new HashMap
111 val constraint2CurrentPrecondition = new HashMap
112 for(entry : mainMustPropagationNames.entrySet) {
113 val name = '''UPMUSTPropagate_«res.getOrGenerateConstraintName(entry.key)»''';
114 val def = '''
115 pattern «name»(«FOR index : 1..entry.key.arity SEPARATOR ", "»«canonizeName(index,PropagationModality::UP)»«ENDFOR»)
116 «FOR propagation : entry.value SEPARATOR " or "»
117 { find «propagation.key»(problem,interpretation,«FOR index : 0..<propagation.value SEPARATOR ','»_«ENDFOR»,«FOR index : 1..entry.key.arity SEPARATOR ", "»«canonizeName(index,PropagationModality::UP)»«ENDFOR»); }
118 «ENDFOR»'''
119 preconditions+=def
120 constraint2MustPrecondition.put(entry.key,name)
121 }
122 for(entry : mainCurrentPropagationNames.entrySet) {
123 val name = '''UPCurrentPropagate_«res.getOrGenerateConstraintName(entry.key)»''';
124 val def = '''
125 pattern «name»(«FOR index : 1..entry.key.arity SEPARATOR ", "»«canonizeName(index,PropagationModality::UP)»«ENDFOR»)
126 «FOR propagation : entry.value SEPARATOR " or "»
127 { find «propagation.key»(problem,interpretation,«FOR index : 0..<propagation.value SEPARATOR ','»_«ENDFOR»,«FOR index : 1..entry.key.arity SEPARATOR ", "»«canonizeName(index,PropagationModality::UP)»«ENDFOR»); }
128 «ENDFOR»'''
129 preconditions+=def
130 constraint2CurrentPrecondition.put(entry.key,name)
131 }
132
133 val definitions = '''
134 «FOR def : res.definitions»
135 «def»
136 «ENDFOR»
137
138 // Collected propagation preconditions:
139
140 «FOR predondition : preconditions»
141 «predondition»
142 «ENDFOR»
143 '''
144 return new UnitPropagationPreconditionFinalResult(definitions,constraint2MustPrecondition,constraint2CurrentPrecondition)
145 }
146 def allReferredConstraints(Relation relation, PQuery query) {
147 val allReferredQueries = query.allReferredQueries
148 val problem = relation.eContainer as LogicProblem
149 val constraints = new LinkedHashSet
150 for(referredQuery: #[query]+allReferredQueries) {
151 val referredRelation = problem.annotations.filter(TransfomedViatraQuery).filter[it.patternPQuery === referredQuery].head.target
152 val bodies = (referredRelation.annotations.filter(TransfomedViatraQuery).head.optimizedDisjunction as PDisjunction).bodies
153 constraints.addAll(bodies.map[getConstraints].flatten)
154 }
155
156 return constraints
157 }
158
159 def getOrGeneratePropagationRule(UnitPropagationPreconditionGenerationResult res, Relation relation, PQuery q, PConstraint c, PropagationModality pm, Modality m3) {
160 if(res.contains(q,c,pm,m3)) {
161 return res.getName(q,c,pm,m3)
162 } else {
163 res.generatePropagationRule(relation,q,c,pm,m3)
164 return res.getName(q,c,pm,m3)
165 }
166 }
167 def getOrGenerateConstraintName(UnitPropagationPreconditionGenerationResult res, PConstraint c){
168 if(res.constraintOccurence2Name.containsKey(c)) {
169 return res.constraintOccurence2Name.get(c)
170 } else {
171 val constraintName = '''Constraint«res.constraintOccurence2Name.size»'''
172 res.constraintOccurence2Name.put(c,constraintName)
173 return constraintName
174 }
175 }
176
177 def void generatePropagationRule(UnitPropagationPreconditionGenerationResult res, Relation relation, PQuery q, PConstraint c, PropagationModality pm, Modality m3) {
178 val name = relationDefinitionName(res,relation,q,c,pm,m3)
179 val constraintArity = c.arity
180 val bodies = (relation.annotations.filter(TransfomedViatraQuery).head.optimizedDisjunction as PDisjunction).bodies
181 val generatedBodies = new LinkedList
182 for(body : bodies) {
183 if(body.constraints.contains(c)) {
184 if(pm === PropagationModality::UP) {
185 generatedBodies += '''
186 // Original Constraints
187 «FOR constraint : body.constraints.filter[it !== c]»
188 «this.constraintTransformer.transformConstraint(constraint,m3,relation.annotations.filter(TransfomedViatraQuery).head.variableTrace)»
189 «ENDFOR»
190 // Propagation for constraint
191 «this.constraintTransformer.transformConstraintUnset(c as ExpressionEvaluation,relation.annotations.filter(TransfomedViatraQuery).head.variableTrace)»
192 // Matching variables
193 «this.propagateVariables(c,pm)»
194 '''
195 }
196 // Otherwise, for PropagationModality::DOWN, the body cannot be satisfied
197 } else {
198 val positives = body.constraints.filter(PositivePatternCall)
199 for(positive: positives) {
200 val referredPQuery = positive.referredQuery
201 val referredRelation = (relation.eContainer as LogicProblem)
202 .annotations.filter(TransfomedViatraQuery).filter[it.patternPQuery === referredPQuery].head.target
203 if(allReferredConstraints(referredRelation,referredPQuery).toSet.contains(c)) {
204 val referredName = getOrGeneratePropagationRule(res,referredRelation,referredPQuery,c,pm,m3)
205 if(referredName !== null) {
206 generatedBodies += '''
207 // Original Constraints
208 «FOR constraint : body.constraints.filter[it !== positive]»
209 «this.constraintTransformer.transformConstraint(constraint,m3,relation.annotations.filter(TransfomedViatraQuery).head.variableTrace)»
210 «ENDFOR»
211 // Propagation for constraint referred indirectly from this pattern through «referredName»
212 find «referredName»(problem, interpretation,
213 «FOR index : 0..<referredPQuery.parameters.size SEPARATOR ", "»«positive.getVariableInTuple(index).canonizeName»«ENDFOR»,
214 «FOR index : 1..c.arity SEPARATOR ", "»«canonizeName(index,pm)»«ENDFOR»);
215 '''
216 }
217 // Otherwise, if the referred pattern is not satisfiable, this pattern is not satisfiable either
218 }
219 }
220
221 val negatives = body.constraints.filter(NegativePatternCall)
222 for(negative : negatives) {
223 val referredPQuery = negative.referredQuery
224 val referredRelation = (relation.eContainer as LogicProblem)
225 .annotations.filter(TransfomedViatraQuery).filter[it.patternPQuery === referredPQuery].head.target
226 if(allReferredConstraints(referredRelation,referredPQuery).toSet.contains(c)) {
227 val referredName = getOrGeneratePropagationRule(res,referredRelation,referredPQuery,c,pm,m3.dual)
228 if(referredName !== null) {
229 generatedBodies += '''
230 // Original Constraints
231 «FOR constraint : body.constraints.filter[it !== negative]»
232 «this.constraintTransformer.transformConstraint(constraint,m3,relation.annotations.filter(TransfomedViatraQuery).head.variableTrace)»
233 «ENDFOR»
234 // Propagation for constraint referred indirectly from this pattern through «referredName»
235 find «referredName»(problem, interpretation,
236 «FOR index : 0..<referredPQuery.parameters.size SEPARATOR ", "»«(negative.actualParametersTuple.get(index) as PVariable).canonizeName»«ENDFOR»,
237 «FOR index : 1..c.arity SEPARATOR ", "»«canonizeName(index,pm)»«ENDFOR»);
238 '''
239 } else {
240 generatedBodies += '''
241 // Original Constraints
242 «FOR constraint : body.constraints.filter[it !== negative]»
243 «this.constraintTransformer.transformConstraint(constraint,m3,relation.annotations.filter(TransfomedViatraQuery).head.variableTrace)»
244 «ENDFOR»
245 // Propagation for constraint referred indirectly from this pattern through «referredName»,
246 // which was unsatisfiable
247 '''
248 }
249 }
250 }
251 }
252 }
253
254 // Register the result
255 if(generatedBodies.empty) {
256 res.registerUnsatQuery(q,c,pm,m3)
257 } else {
258 val definition = '''
259 private pattern «name»(
260 problem:LogicProblem, interpretation:PartialInterpretation,
261 «FOR param : q.parameters SEPARATOR ', '»var_«param.name»«ENDFOR»,
262 «FOR arity : 1..constraintArity SEPARATOR ', '»«canonizeName(arity,pm)»«ENDFOR»)
263 «FOR generatedBody: generatedBodies SEPARATOR " or "»{
264 «generatedBody»
265 }«ENDFOR»
266 '''
267 res.registerQuery(q,c,pm,m3,name,definition)
268 }
269 }
270
271 private def String relationDefinitionName(UnitPropagationPreconditionGenerationResult res, Relation relation, PQuery q, PConstraint c, PropagationModality pm, Modality m3)
272 '''«pm.name»«m3.name»Propagate«res.getOrGenerateConstraintName(c)»_«base.canonizeName(relation.name)»'''
273
274 def canonizeName(PVariable v) {
275 return '''«IF v.referringConstraints.size == 1»_«ENDIF»var_«v.name.replaceAll("\\W","")»'''
276 }
277
278 def canonizeName(int index, PropagationModality m) {
279 return '''«m.name.toLowerCase»_«index»'''
280 }
281
282 def dispatch propagateVariables(ExpressionEvaluation c, PropagationModality m) {
283 val comparator = new Comparator<PVariable>(){
284 override compare(PVariable o1, PVariable o2) {
285 o1.name.compareTo(o2.name)
286 }
287 }
288 val variablesInOrder = new ArrayList(c.affectedVariables)
289 variablesInOrder.toList.sort(comparator)
290 return '''«FOR variableIndex : 1..variablesInOrder.size»«variablesInOrder.get(variableIndex-1).canonizeName»==«canonizeName(variableIndex,m)»;«ENDFOR»'''
291 }
292 def dispatch propagateVariables(PConstraint c, PropagationModality m) {
293 throw new UnsupportedOperationException('''Constraint not supported: «c.class.simpleName»''')
294 }
295
296 def dispatch arity(ExpressionEvaluation c) {
297 c.affectedVariables.size
298 }
299 def dispatch arity(PConstraint c) {
300 throw new UnsupportedOperationException('''Constraint not supported: «c.class.simpleName»''')
301 }
302} \ No newline at end of file
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 e1be2742..732c135d 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
@@ -1,18 +1,89 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules 1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules
2 2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.MultiplicityGoalConstraintCalculator 3import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.LowerMultiplicityAssertion
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
6import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
7import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.MultiplicityGoalConstraintCalculator
4import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns 8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns
5import java.util.ArrayList 9import java.util.ArrayList
10import java.util.HashMap
11import java.util.LinkedList
12import java.util.List
13import java.util.Map
6 14
7class GoalConstraintProvider { 15class GoalConstraintProvider {
8 def public getUnfinishedMultiplicityQueries(GeneratedPatterns patterns) { 16
9 val multiplicityQueries = patterns.unfinishedMulticiplicityQueries 17 def getUnfinishedMultiplicityQueries(LogicProblem p, GeneratedPatterns patterns, boolean calculateObjectCost) {
10 val res = new ArrayList(multiplicityQueries.size) 18 val objectCosts = if (calculateObjectCost) {
11 for(multiplicityQuery : multiplicityQueries.entrySet) { 19 calculateMissingObjectCost(p)
12 val targetRelationName = multiplicityQuery.key.name 20 } else {
13 val query = multiplicityQuery.value 21 emptyMap
14 res += new MultiplicityGoalConstraintCalculator(targetRelationName,query); 22 }
23 val res = new ArrayList()
24 for (entry : patterns.multiplicityConstraintQueries.entrySet) {
25 val constraint = entry.key
26 if (constraint.constrainsUnfinished) {
27 val queries = entry.value
28 val targetRelationName = constraint.relation.name
29 val query = queries.existingMultiplicityQuery
30 val containment = constraint.containment
31 val lowerBound = constraint.lowerBound
32 val cost = objectCosts.getOrDefault(constraint.relation, 1)
33 res += new MultiplicityGoalConstraintCalculator(
34 targetRelationName,
35 query,
36 containment,
37 lowerBound,
38 cost
39 )
40 }
15 } 41 }
16 return res 42 return res
17 } 43 }
18} \ No newline at end of file 44
45 private def calculateMissingObjectCost(LogicProblem p) {
46 val containments = p.containmentHierarchies.head.containmentRelations
47 val containment2Lower = containments.toInvertedMap [ containment |
48 val lower = p.annotations.filter(LowerMultiplicityAssertion).filter[it.relation === containment].head
49 if (lower !== null) {
50 lower.lower
51 } else {
52 0
53 }
54 ]
55 val types = p.types
56 val Map<Type, List<? extends Pair<Type, Integer>>> type2NewCost = new HashMap
57 for (type : types) {
58 val allSupertypes = (#[type] + type.supertypes).toSet
59 val allOutgoingContainments = containments.filter [
60 allSupertypes.contains((it.parameters.get(0) as ComplexTypeReference).referred)
61 ]
62 val list = new LinkedList
63 for (outgoingContainment : allOutgoingContainments) {
64 val value = containment2Lower.get(outgoingContainment)
65 if (value > 0) {
66 list.add((outgoingContainment.parameters.get(1) as ComplexTypeReference).referred -> value)
67 }
68 }
69 type2NewCost.put(type, list)
70 }
71 val res = new HashMap
72 for (containment : containments) {
73 val key = containment
74 val value = (containment.parameters.get(1) as ComplexTypeReference).referred.count(type2NewCost)
75// println('''«key.name» --> «value» new''')
76 res.put(key, value)
77 }
78 return res
79 }
80
81 private def int count(Type t, Map<Type, List<? extends Pair<Type, Integer>>> containments) {
82 val list = containments.get(t)
83 var r = 1
84 for (element : list) {
85 r += element.value * element.key.count(containments)
86 }
87 return r
88 }
89}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend
index 20d24b77..dca10baf 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend
@@ -1,226 +1,743 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules 1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules
2 2
3import com.google.common.collect.ImmutableList
4import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.InverseRelationAssertion
5import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.LowerMultiplicityAssertion
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference
7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference
3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement 8import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement
9import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntTypeReference
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.LogiclanguageFactory 10import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.LogiclanguageFactory
11import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.PrimitiveTypeReference
12import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation 13import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration 14import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
15import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.StringTypeReference
7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type 16import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
17import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics 18import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics
9import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator 19import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagator
10import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns 20import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns
11import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.ObjectCreationPrecondition 21import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.ObjectCreationPrecondition
22import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialBooleanInterpretation
12import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation 23import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
24import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialIntegerInterpretation
13import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 25import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
26import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRealInterpretation
14import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation 27import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation
28import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialStringInterpretation
29import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation
15import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory 30import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory
31import java.lang.reflect.Field
32import java.util.HashMap
33import java.util.Iterator
16import java.util.LinkedHashMap 34import java.util.LinkedHashMap
35import java.util.LinkedList
36import java.util.List
37import java.util.Map
38import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine
17import org.eclipse.viatra.query.runtime.api.GenericPatternMatch 39import org.eclipse.viatra.query.runtime.api.GenericPatternMatch
40import org.eclipse.viatra.query.runtime.api.IPatternMatch
18import org.eclipse.viatra.query.runtime.api.IQuerySpecification 41import org.eclipse.viatra.query.runtime.api.IQuerySpecification
42import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
19import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher 43import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
44import org.eclipse.viatra.query.runtime.emf.EMFScope
45import org.eclipse.viatra.query.runtime.rete.matcher.ReteBackendFactory
20import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule 46import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule
21import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRuleFactory 47import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRuleFactory
48import org.eclipse.xtend.lib.annotations.Data
49import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
50import org.eclipse.xtext.xbase.lib.Functions.Function0
22 51
23class RefinementRuleProvider { 52class RefinementRuleProvider {
24 private extension BatchTransformationRuleFactory factory = new BatchTransformationRuleFactory 53 val extension BatchTransformationRuleFactory factory = new BatchTransformationRuleFactory
25 private extension PartialinterpretationFactory factory2 = PartialinterpretationFactory.eINSTANCE 54 val extension PartialinterpretationFactory factory2 = PartialinterpretationFactory.eINSTANCE
26 private extension LogiclanguageFactory factory3 = LogiclanguageFactory.eINSTANCE 55 val extension LogiclanguageFactory factory3 = LogiclanguageFactory.eINSTANCE
27 56
28 def canonizeName(String name) { 57 def canonizeName(String name) {
29 return name.replace(' ','_') 58 return name.replace(' ', '_')
30 } 59 }
31 60
32 def LinkedHashMap<ObjectCreationPrecondition, BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>>> 61 def createUnitPrulePropagator(LogicProblem p, PartialInterpretation i, GeneratedPatterns patterns,
33 createObjectRefinementRules( 62 ScopePropagator scopePropagator, ModelGenerationStatistics statistics) {
34 GeneratedPatterns patterns, 63 new UnitRulePropagator(p, i, this, scopePropagator, patterns.mustRelationPropagationQueries, statistics)
35 ScopePropagator scopePropagator, 64 }
36 boolean nameNewElement, 65
37 ModelGenerationStatistics statistics 66 def LinkedHashMap<ObjectCreationPrecondition, BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>>> createObjectRefinementRules(
38 ) 67 LogicProblem p,
39 { 68 PartialInterpretation i,
69 GeneratedPatterns patterns,
70 UnitRulePropagator unitRulePropagator,
71 boolean nameNewElement,
72 ModelGenerationStatistics statistics
73 ) {
40 val res = new LinkedHashMap 74 val res = new LinkedHashMap
41 for(LHSEntry: patterns.refineObjectQueries.entrySet) { 75 val recursiveObjectCreation = recursiveObjectCreation(p, i)
76 for (LHSEntry : patterns.refineObjectQueries.entrySet) {
42 val containmentRelation = LHSEntry.key.containmentRelation 77 val containmentRelation = LHSEntry.key.containmentRelation
43 val inverseRelation = LHSEntry.key.inverseContainment 78 val inverseRelation = LHSEntry.key.inverseContainment
44 val type = LHSEntry.key.newType 79 val type = LHSEntry.key.newType
45 val lhs = LHSEntry.value as IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> 80 val lhs = LHSEntry.value as IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>>
46 val rule = createObjectCreationRule(containmentRelation,inverseRelation,type,lhs,nameNewElement,scopePropagator,statistics) 81 val rule = createObjectCreationRule(p, containmentRelation, inverseRelation, type,
47 res.put(LHSEntry.key,rule) 82 recursiveObjectCreation.get(type), lhs, nameNewElement, unitRulePropagator, statistics)
83 res.put(LHSEntry.key, rule)
48 } 84 }
49 return res 85 return res
50 } 86 }
51 87
52 def private createObjectCreationRule( 88 def private createObjectCreationRule(LogicProblem p, Relation containmentRelation, Relation inverseRelation,
53 Relation containmentRelation, 89 Type type, List<ObjectCreationInterpretationData> recursiveObjectCreations,
54 Relation inverseRelation, 90 IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, boolean nameNewElement,
55 Type type, 91 UnitRulePropagator unitRulePropagator, ModelGenerationStatistics statistics) {
56 IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, 92 val name = '''addObject_«type.name.canonizeName»«IF containmentRelation!==null»_by_«containmentRelation.name.canonizeName»«ENDIF»'''
57 boolean nameNewElement, 93 val ruleBuilder = factory.createRule(lhs).name(name)
58 ScopePropagator scopePropagator, 94 if (containmentRelation !== null) {
59 ModelGenerationStatistics statistics) 95 if (inverseRelation !== null) {
60 { 96 ruleBuilder.action [ match |
61 val name = '''addObject_«type.name.canonizeName»« 97 statistics.incrementTransformationCount
62 IF containmentRelation!=null»_by_«containmentRelation.name.canonizeName»«ENDIF»''' 98// println(name)
63 //println("Rule created: " + name + "> " + lhs.fullyQualifiedName)
64 val ruleBuilder = factory.createRule
65 .name(name)
66 .precondition(lhs)
67 if(containmentRelation != null) {
68 if(inverseRelation!= null) {
69 ruleBuilder.action[match |
70 //println(name)
71 val startTime = System.nanoTime 99 val startTime = System.nanoTime
72 //val problem = match.get(0) as LogicProblem 100 // val problem = match.get(0) as LogicProblem
73 val interpretation = match.get(1) as PartialInterpretation 101 val interpretation = match.get(1) as PartialInterpretation
74 val relationInterpretation = match.get(2) as PartialRelationInterpretation 102 val relationInterpretation = match.get(2) as PartialRelationInterpretation
75 val inverseRelationInterpretation = match.get(3) as PartialRelationInterpretation 103 val inverseRelationInterpretation = match.get(3) as PartialRelationInterpretation
76 val typeInterpretation = match.get(4) as PartialComplexTypeInterpretation 104 val typeInterpretation = match.get(4) as PartialComplexTypeInterpretation
77 val container = match.get(5) as DefinedElement 105 val container = match.get(5) as DefinedElement
78 106 createObjectActionWithContainmentAndInverse(
79 val newElement = createDefinedElement 107 nameNewElement,
80 if(nameNewElement) { 108 interpretation,
81 newElement.name = '''new «interpretation.newElements.size»''' 109 typeInterpretation,
82 } 110 container,
83 111 relationInterpretation,
84 // Existence 112 inverseRelationInterpretation,
85 interpretation.newElements+=newElement 113 [createDefinedElement],
86 /*interpretation.maxNewElements=interpretation.maxNewElements-1 114 recursiveObjectCreations,
87 if(interpretation.minNewElements > 0) { 115 unitRulePropagator
88 interpretation.minNewElements=interpretation.minNewElements-1 116 )
89 }*/ 117 statistics.addExecutionTime(System.nanoTime - startTime)
90 118
91 // Types 119 unitRulePropagator.propagate
92 typeInterpretation.elements += newElement
93 typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement]
94 // ContainmentRelation
95 val newLink1 = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement]
96 relationInterpretation.relationlinks+=newLink1
97 // Inverse Containment
98 val newLink2 = factory2.createBinaryElementRelationLink => [it.param1 = newElement it.param2 = container]
99 inverseRelationInterpretation.relationlinks+=newLink2
100
101 // Scope propagation
102 scopePropagator.propagateAdditionToType(typeInterpretation)
103
104 statistics.addExecutionTime(System.nanoTime-startTime)
105 ] 120 ]
106 } else { 121 } else {
107 ruleBuilder.action[match | 122 ruleBuilder.action [ match |
108 //println(name) 123 statistics.incrementTransformationCount
124// println(name)
109 val startTime = System.nanoTime 125 val startTime = System.nanoTime
110 //val problem = match.get(0) as LogicProblem 126 // val problem = match.get(0) as LogicProblem
111 val interpretation = match.get(1) as PartialInterpretation 127 val interpretation = match.get(1) as PartialInterpretation
112 val relationInterpretation = match.get(2) as PartialRelationInterpretation 128 val relationInterpretation = match.get(2) as PartialRelationInterpretation
113 val typeInterpretation = match.get(3) as PartialComplexTypeInterpretation 129 val typeInterpretation = match.get(3) as PartialComplexTypeInterpretation
114 val container = match.get(4) as DefinedElement 130 val container = match.get(4) as DefinedElement
115 131
116 val newElement = createDefinedElement 132 createObjectActionWithContainment(
117 if(nameNewElement) { 133 nameNewElement,
118 newElement.name = '''new «interpretation.newElements.size»''' 134 interpretation,
119 } 135 typeInterpretation,
120 136 container,
121 // Existence 137 relationInterpretation,
122 interpretation.newElements+=newElement 138 [createDefinedElement],
123 /*interpretation.maxNewElements=interpretation.maxNewElements-1 139 recursiveObjectCreations,
124 if(interpretation.minNewElements > 0) { 140 unitRulePropagator
125 interpretation.minNewElements=interpretation.minNewElements-1 141 )
126 }*/ 142 statistics.addExecutionTime(System.nanoTime - startTime)
127 143
128 // Types 144 unitRulePropagator.propagate
129 typeInterpretation.elements += newElement
130 typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement]
131 // ContainmentRelation
132 val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement]
133 relationInterpretation.relationlinks+=newLink
134
135 // Scope propagation
136 scopePropagator.propagateAdditionToType(typeInterpretation)
137
138 statistics.addExecutionTime(System.nanoTime-startTime)
139 ] 145 ]
140 } 146 }
141 } else { 147 } else {
142 ruleBuilder.action[match | 148 ruleBuilder.action [ match |
149 statistics.incrementTransformationCount
150// println(name)
143 val startTime = System.nanoTime 151 val startTime = System.nanoTime
144 //val problem = match.get(0) as LogicProblem 152 // val problem = match.get(0) as LogicProblem
145 val interpretation = match.get(1) as PartialInterpretation 153 val interpretation = match.get(1) as PartialInterpretation
146 val typeInterpretation = match.get(2) as PartialComplexTypeInterpretation 154 val typeInterpretation = match.get(2) as PartialComplexTypeInterpretation
147 155
148 val newElement = createDefinedElement 156 createObjectAction(
149 if(nameNewElement) { 157 nameNewElement,
150 newElement.name = '''new «interpretation.newElements.size»''' 158 interpretation,
151 } 159 typeInterpretation,
152 160 [createDefinedElement],
153 // Existence 161 recursiveObjectCreations,
154 interpretation.newElements+=newElement 162 unitRulePropagator
155 /* 163 )
156 interpretation.maxNewElements=interpretation.maxNewElements-1 164 statistics.addExecutionTime(System.nanoTime - startTime)
157 if(interpretation.minNewElements > 0) { 165
158 interpretation.minNewElements=interpretation.minNewElements-1 166 unitRulePropagator.propagate
159 }*/
160
161 // Types
162 typeInterpretation.elements += newElement
163 typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement]
164
165 // Scope propagation
166 scopePropagator.propagateAdditionToType(typeInterpretation)
167
168 statistics.addExecutionTime(System.nanoTime-startTime)
169 ] 167 ]
170 } 168 }
171 return ruleBuilder.build 169 return ruleBuilder.build
172 } 170 }
173 171
174 def createRelationRefinementRules(GeneratedPatterns patterns, ModelGenerationStatistics statistics) { 172 def private recursiveObjectCreation(LogicProblem p, PartialInterpretation i) {
173 val Map<Type, List<ObjectCreationInterpretationData>> recursiveObjectCreation = new HashMap
174 for (type : p.types) {
175 recursiveObjectCreation.put(type, new LinkedList)
176 }
177
178 val containmentReferences = p.containmentHierarchies.head.containmentRelations
179
180 for (relationInterpretation : i.partialrelationinterpretation) {
181 val relation = relationInterpretation.interpretationOf
182 val lowermultiplicities = p.annotations.filter(LowerMultiplicityAssertion).filter[it.relation === relation]
183 if ((!lowermultiplicities.empty)) {
184 val number = lowermultiplicities.head.lower
185 if (number > 0) {
186 val sourceTypeInterpretation = getTypeInterpretation(i, relation,
187 0) as PartialComplexTypeInterpretation
188 val subtypeInterpretations = i.partialtypeinterpratation.filter(PartialComplexTypeInterpretation).
189 filter [
190 it === sourceTypeInterpretation ||
191 it.supertypeInterpretation.contains(sourceTypeInterpretation)
192 ]
193
194 if (containmentReferences.contains(relation)) {
195 val targetTypeInterpretation = getTypeInterpretation(i, relation, 1)
196 val targetType = (targetTypeInterpretation as PartialComplexTypeInterpretation).interpretationOf
197 if ((!targetType.isIsAbstract) && (targetType.supertypes.empty)) {
198 val inverseAnnotation = p.annotations.filter(InverseRelationAssertion).filter [
199 it.inverseA === relation || it.inverseB === relation
200 ]
201 if (!inverseAnnotation.empty) {
202 val onlyInverseAnnotation = if (inverseAnnotation.head.inverseA === relation) {
203 inverseAnnotation.head.inverseB
204 } else {
205 inverseAnnotation.head.inverseA
206 }
207 val inverseRelationInterpretation = i.partialrelationinterpretation.filter [
208 it.interpretationOf === onlyInverseAnnotation
209 ].head
210 for (subTypeInterpretation : subtypeInterpretations) {
211 for (var times = 0; times < number; times++) {
212 recursiveObjectCreation.get(subTypeInterpretation.interpretationOf) +=
213 new ObjectCreationInterpretationData(
214 i,
215 targetTypeInterpretation,
216 relationInterpretation,
217 inverseRelationInterpretation,
218 targetTypeInterpretation.getTypeConstructor
219 )
220 }
221 }
222 } else {
223 for (subTypeInterpretation : subtypeInterpretations) {
224 for (var times = 0; times < number; times++) {
225 recursiveObjectCreation.get(subTypeInterpretation.interpretationOf) +=
226 new ObjectCreationInterpretationData(
227 i,
228 targetTypeInterpretation,
229 relationInterpretation,
230 null,
231 targetTypeInterpretation.getTypeConstructor
232 )
233 }
234 }
235 }
236 }
237 } else if (relation.parameters.get(1) instanceof PrimitiveTypeReference) {
238 val targetTypeInterpretation = getTypeInterpretation(i, relation, 1)
239 for (subTypeInterpretation : subtypeInterpretations) {
240 for (var times = 0; times < number; times++) {
241 recursiveObjectCreation.get(subTypeInterpretation.interpretationOf) +=
242 new ObjectCreationInterpretationData(
243 i,
244 targetTypeInterpretation,
245 relationInterpretation,
246 null,
247 targetTypeInterpretation.getTypeConstructor
248 )
249 }
250 }
251 }
252 }
253 }
254 }
255
256 // Doing the recursion
257 var objectCreations = new LinkedList(recursiveObjectCreation.values.flatten.toList)
258 for (objectCreation : objectCreations) {
259 val newInterpretation = objectCreation.typeInterpretation
260 if (newInterpretation instanceof PartialComplexTypeInterpretation) {
261 val newlyCreatedType = newInterpretation.interpretationOf
262 if (recursiveObjectCreation.containsKey(newlyCreatedType)) {
263 val actionsWhenTypeCreated = recursiveObjectCreation.get(newlyCreatedType)
264 objectCreation.recursiveConstructors += actionsWhenTypeCreated
265 }
266 }
267 }
268
269 // checking acyclicity
270 for (objectCreation : objectCreations) {
271 var reachable = objectCreation.recursiveConstructors
272 do {
273 if (reachable.contains(objectCreation)) {
274 throw new IllegalArgumentException('''Cicrle in the containment!''')
275 } else {
276 reachable = reachable.map[it.recursiveConstructors].flatten.toList
277 }
278 } while (!reachable.empty)
279 }
280
281 return recursiveObjectCreation
282 }
283
284 private def getTypeInterpretation(PartialInterpretation i, RelationDeclaration relation, int index) {
285 val typeReference = relation.parameters.get(index)
286 return getTypeInterpretation(i, typeReference)
287
288 }
289
290 private dispatch def getTypeInterpretation(PartialInterpretation i, ComplexTypeReference reference) {
291 return i.partialtypeinterpratation.filter(PartialComplexTypeInterpretation).filter [
292 it.getInterpretationOf == reference.referred
293 ].head
294 }
295
296 private dispatch def getTypeInterpretation(PartialInterpretation i, BoolTypeReference reference) {
297 return i.partialtypeinterpratation.filter(PartialBooleanInterpretation).head
298 }
299
300 private dispatch def getTypeInterpretation(PartialInterpretation i, IntTypeReference reference) {
301 return i.partialtypeinterpratation.filter(PartialIntegerInterpretation).head
302 }
303
304 private dispatch def getTypeInterpretation(PartialInterpretation i, RealTypeReference reference) {
305 return i.partialtypeinterpratation.filter(PartialRealInterpretation).head
306 }
307
308 private dispatch def getTypeInterpretation(PartialInterpretation i, StringTypeReference reference) {
309 return i.partialtypeinterpratation.filter(PartialStringInterpretation).head
310 }
311
312 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialComplexTypeInterpretation reference) {
313 [createDefinedElement]
314 }
315
316 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialBooleanInterpretation reference) {
317 [createBooleanElement]
318 }
319
320 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialIntegerInterpretation reference) {
321 [createIntegerElement]
322 }
323
324 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialRealInterpretation reference) {
325 [createRealElement]
326 }
327
328 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialStringInterpretation reference) {
329 [createStringElement]
330 }
331
332 def createRelationRefinementRules(GeneratedPatterns patterns, UnitRulePropagator unitRulePropagator,
333 ModelGenerationStatistics statistics) {
175 val res = new LinkedHashMap 334 val res = new LinkedHashMap
176 for(LHSEntry: patterns.refinerelationQueries.entrySet) { 335 for (LHSEntry : patterns.refineRelationQueries.entrySet) {
177 val declaration = LHSEntry.key.key 336 val declaration = LHSEntry.key.key
178 val inverseReference = LHSEntry.key.value 337 val inverseReference = LHSEntry.key.value
179 val lhs = LHSEntry.value as IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> 338 val lhs = LHSEntry.value as IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>>
180 val rule = createRelationRefinementRule(declaration,inverseReference,lhs,statistics) 339 val rule = createRelationRefinementRule(declaration, inverseReference, lhs, unitRulePropagator, statistics)
181 res.put(LHSEntry.key,rule) 340 res.put(LHSEntry.key, rule)
182 } 341 }
183 return res 342 return res
184 } 343 }
185 344
186 def private BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>> 345 def private BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>> createRelationRefinementRule(
187 createRelationRefinementRule(RelationDeclaration declaration, Relation inverseRelation, IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, ModelGenerationStatistics statistics) 346 RelationDeclaration declaration, Relation inverseRelation,
188 { 347 IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, UnitRulePropagator unitRulePropagator,
189 val name = '''addRelation_«declaration.name.canonizeName»«IF inverseRelation != null»_and_«inverseRelation.name.canonizeName»«ENDIF»''' 348 ModelGenerationStatistics statistics) {
190 val ruleBuilder = factory.createRule 349 val name = '''addRelation_«declaration.name.canonizeName»«IF inverseRelation !== null»_and_«inverseRelation.name.canonizeName»«ENDIF»'''
191 .name(name) 350 val ruleBuilder = factory.createRule(lhs).name(name)
192 .precondition(lhs) 351 if (inverseRelation === null) {
193 if (inverseRelation == null) {
194 ruleBuilder.action [ match | 352 ruleBuilder.action [ match |
195 val startTime = System.nanoTime 353 statistics.incrementTransformationCount
196 //println(name) 354// println(name)
197 // val problem = match.get(0) as LogicProblem 355 val startTime = System.nanoTime
198 // val interpretation = match.get(1) as PartialInterpretation 356 createRelationLinkAction(match, unitRulePropagator)
199 val relationInterpretation = match.get(2) as PartialRelationInterpretation 357 statistics.addExecutionTime(System.nanoTime - startTime)
200 val src = match.get(3) as DefinedElement 358
201 val trg = match.get(4) as DefinedElement 359 unitRulePropagator.propagate
202 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg]
203 relationInterpretation.relationlinks += link
204 statistics.addExecutionTime(System.nanoTime-startTime)
205 ] 360 ]
206 } else { 361 } else {
207 ruleBuilder.action [ match | 362 ruleBuilder.action [ match |
208 val startTime = System.nanoTime 363 statistics.incrementTransformationCount
209 //println(name) 364// println(name)
210 // val problem = match.get(0) as LogicProblem 365 val startTime = System.nanoTime
211 // val interpretation = match.get(1) as PartialInterpretation 366 createRelationLinkWithInverse(match, unitRulePropagator)
212 val relationInterpretation = match.get(2) as PartialRelationInterpretation 367 statistics.addExecutionTime(System.nanoTime - startTime)
213 val inverseInterpretation = match.get(3) as PartialRelationInterpretation 368
214 val src = match.get(4) as DefinedElement 369 unitRulePropagator.propagate
215 val trg = match.get(5) as DefinedElement
216 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg]
217 relationInterpretation.relationlinks += link
218 val inverseLink = createBinaryElementRelationLink => [it.param1 = trg it.param2 = src]
219 inverseInterpretation.relationlinks += inverseLink
220 statistics.addExecutionTime(System.nanoTime-startTime)
221 ] 370 ]
222 } 371 }
223 372
224 return ruleBuilder.build 373 return ruleBuilder.build
225 } 374 }
375
376 // ///////////////////////
377 // Actions
378 // ///////////////////////
379 protected def void createObjectAction(boolean nameNewElement, ObjectCreationInterpretationData data,
380 DefinedElement container, UnitRulePropagator unitRulePropagator) {
381 if (data.containerInterpretation !== null) {
382 if (data.containerInverseInterpretation !== null) {
383 createObjectActionWithContainmentAndInverse(
384 nameNewElement,
385 data.interpretation,
386 data.typeInterpretation,
387 container,
388 data.containerInterpretation,
389 data.containerInverseInterpretation,
390 data.constructor,
391 data.recursiveConstructors,
392 unitRulePropagator
393 )
394 } else {
395 createObjectActionWithContainment(
396 nameNewElement,
397 data.interpretation,
398 data.typeInterpretation,
399 container,
400 data.containerInterpretation,
401 data.constructor,
402 data.recursiveConstructors,
403 unitRulePropagator
404 )
405 }
406 } else {
407 createObjectAction(
408 nameNewElement,
409 data.interpretation,
410 data.typeInterpretation,
411 data.constructor,
412 data.recursiveConstructors,
413 unitRulePropagator
414 )
415 }
416
417 }
418
419 protected def createObjectActionWithContainmentAndInverse(
420 boolean nameNewElement,
421 PartialInterpretation interpretation,
422 PartialTypeInterpratation typeInterpretation,
423 DefinedElement container,
424 PartialRelationInterpretation relationInterpretation,
425 PartialRelationInterpretation inverseRelationInterpretation,
426 Function0<DefinedElement> constructor,
427 List<ObjectCreationInterpretationData> recursiceObjectCreations,
428 UnitRulePropagator unitRulePropagator
429 ) {
430 val newElement = constructor.apply
431 if (nameNewElement) {
432 newElement.name = '''new «interpretation.newElements.size»'''
433 }
434
435 // Types
436 typeInterpretation.elements += newElement
437 if (typeInterpretation instanceof PartialComplexTypeInterpretation) {
438 typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement]
439 }
440 // ContainmentRelation
441 val newLink1 = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement]
442 relationInterpretation.relationlinks += newLink1
443 // Inverse Containment
444 val newLink2 = factory2.createBinaryElementRelationLink => [it.param1 = newElement it.param2 = container]
445 inverseRelationInterpretation.relationlinks += newLink2
446
447 // Scope propagation
448 unitRulePropagator.decrementTypeScope(typeInterpretation)
449 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
450 unitRulePropagator.addedToRelation(inverseRelationInterpretation.interpretationOf)
451
452 // Existence
453 interpretation.newElements += newElement
454
455 // Do recursive object creation
456 for (newConstructor : recursiceObjectCreations) {
457 createObjectAction(nameNewElement, newConstructor, newElement, unitRulePropagator)
458 }
459
460 return newElement
461 }
462
463 protected def createObjectActionWithContainment(
464 boolean nameNewElement,
465 PartialInterpretation interpretation,
466 PartialTypeInterpratation typeInterpretation,
467 DefinedElement container,
468 PartialRelationInterpretation relationInterpretation,
469 Function0<DefinedElement> constructor,
470 List<ObjectCreationInterpretationData> recursiceObjectCreations,
471 UnitRulePropagator unitRulePropagator
472 ) {
473 val newElement = constructor.apply
474 if (nameNewElement) {
475 newElement.name = '''new «interpretation.newElements.size»'''
476 }
477
478 // Types
479 typeInterpretation.elements += newElement
480 if (typeInterpretation instanceof PartialComplexTypeInterpretation) {
481 typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement]
482 }
483 // ContainmentRelation
484 val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement]
485 relationInterpretation.relationlinks += newLink
486 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
487
488 // Scope propagation
489 unitRulePropagator.decrementTypeScope(typeInterpretation)
490
491 // Existence
492 interpretation.newElements += newElement
493
494 // Do recursive object creation
495 for (newConstructor : recursiceObjectCreations) {
496 createObjectAction(nameNewElement, newConstructor, newElement, unitRulePropagator)
497 }
498
499 return newElement
500 }
501
502 protected def createObjectAction(boolean nameNewElement, PartialInterpretation interpretation,
503 PartialTypeInterpratation typeInterpretation, Function0<DefinedElement> constructor,
504 List<ObjectCreationInterpretationData> recursiceObjectCreations, UnitRulePropagator unitRulePropagator) {
505 val newElement = constructor.apply
506 if (nameNewElement) {
507 newElement.name = '''new «interpretation.newElements.size»'''
508 }
509
510 // Types
511 typeInterpretation.elements += newElement
512 if (typeInterpretation instanceof PartialComplexTypeInterpretation) {
513 typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement]
514 }
515
516 // Scope propagation
517 unitRulePropagator.decrementTypeScope(typeInterpretation)
518
519 // Existence
520 interpretation.newElements += newElement
521
522 // Do recursive object creation
523 for (newConstructor : recursiceObjectCreations) {
524 createObjectAction(nameNewElement, newConstructor, newElement, unitRulePropagator)
525 }
526
527 return newElement
528 }
529
530 protected def createRelationLinkAction(IPatternMatch match, UnitRulePropagator unitRulePropagator) {
531 // val problem = match.get(0) as LogicProblem
532 // val interpretation = match.get(1) as PartialInterpretation
533 val relationInterpretation = match.get(2) as PartialRelationInterpretation
534 val src = match.get(3) as DefinedElement
535 val trg = match.get(4) as DefinedElement
536 createRelationLinkAction(src, trg, relationInterpretation, unitRulePropagator)
537 }
538
539 protected def void createRelationLinkAction(DefinedElement src, DefinedElement trg,
540 PartialRelationInterpretation relationInterpretation, UnitRulePropagator unitRulePropagator) {
541 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg]
542 relationInterpretation.relationlinks += link
543 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
544 }
545
546 protected def void createRelationLinkWithInverse(IPatternMatch match, UnitRulePropagator unitRulePropagator) {
547 // val problem = match.get(0) as LogicProblem
548 // val interpretation = match.get(1) as PartialInterpretation
549 val relationInterpretation = match.get(2) as PartialRelationInterpretation
550 val inverseInterpretation = match.get(3) as PartialRelationInterpretation
551 val src = match.get(4) as DefinedElement
552 val trg = match.get(5) as DefinedElement
553 createRelationLinkWithInverse(src, trg, relationInterpretation, inverseInterpretation, unitRulePropagator)
554 }
555
556 protected def void createRelationLinkWithInverse(DefinedElement src, DefinedElement trg,
557 PartialRelationInterpretation relationInterpretation, PartialRelationInterpretation inverseInterpretation,
558 UnitRulePropagator unitRulePropagator) {
559 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg]
560 relationInterpretation.relationlinks += link
561 val inverseLink = createBinaryElementRelationLink => [it.param1 = trg it.param2 = src]
562 inverseInterpretation.relationlinks += inverseLink
563 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
564 unitRulePropagator.addedToRelation(inverseInterpretation.interpretationOf)
565 }
566
567 static class UnitRulePropagator {
568 val LogicProblem p
569 val PartialInterpretation i
570 val RefinementRuleProvider refinementRuleProvider
571 var AdvancedViatraQueryEngine queryEngine
572 var Field delayMessageDelivery
573 val ScopePropagator scopePropagator
574 val List<AbstractMustRelationPropagator<? extends IPatternMatch>> propagators
575 val ModelGenerationStatistics statistics
576
577 new(LogicProblem p, PartialInterpretation i, RefinementRuleProvider refinementRuleProvider,
578 ScopePropagator scopePropagator,
579 Map<Pair<RelationDeclaration, Relation>, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> mustRelationPropagationQueries,
580 ModelGenerationStatistics statistics) {
581 this.p = p
582 this.i = i
583 this.refinementRuleProvider = refinementRuleProvider
584 queryEngine = ViatraQueryEngine.on(new EMFScope(i)) as AdvancedViatraQueryEngine
585 delayMessageDelivery = queryEngine.class.getDeclaredField("delayMessageDelivery")
586 delayMessageDelivery.accessible = true
587 this.scopePropagator = scopePropagator
588 propagators = ImmutableList.copyOf(mustRelationPropagationQueries.entrySet.map [ entry |
589 val matcher = queryEngine.getMatcher(entry.value)
590 getPropagator(entry.key.key, entry.key.value, matcher)
591 ])
592 this.statistics = statistics
593 }
594
595 def decrementTypeScope(PartialTypeInterpratation partialTypeInterpratation) {
596 scopePropagator.decrementTypeScope(partialTypeInterpratation)
597 }
598
599 def addedToRelation(Relation r) {
600 scopePropagator.addedToRelation(r)
601 }
602
603 def propagate() {
604 var boolean changed
605 do {
606 val scopeChanged = propagateScope()
607 val mustChanged = propagateMustRelations()
608 changed = scopeChanged || mustChanged
609 } while (changed)
610 }
611
612 protected def flushQueryEngine() {
613 if (queryEngine.updatePropagationDelayed) {
614 delayMessageDelivery.setBoolean(queryEngine, false)
615 queryEngine.getQueryBackend(ReteBackendFactory.INSTANCE).flushUpdates
616 delayMessageDelivery.setBoolean(queryEngine, true)
617 }
618 }
619
620 protected def propagateScope() {
621 if (scopePropagator.scopePropagationNeeded) {
622 if (scopePropagator.queryEngineFlushRequiredBeforePropagation) {
623 flushQueryEngine()
624 }
625 val propagatorStartTime = System.nanoTime
626 scopePropagator.propagateAllScopeConstraints()
627 statistics.addScopePropagationTime(System.nanoTime - propagatorStartTime)
628 true
629 } else {
630 false
631 }
632 }
633
634 protected def propagateMustRelations() {
635 if (propagators.empty) {
636 return false
637 }
638 flushQueryEngine()
639 val propagatorStartTime = System.nanoTime
640 var changed = false
641 for (propagator : propagators) {
642 changed = propagator.propagate(p, i, refinementRuleProvider, this) || changed
643 }
644 statistics.addMustRelationPropagationTime(System.nanoTime - propagatorStartTime)
645 changed
646 }
647
648 private static def <T extends IPatternMatch> getPropagator(Relation relation, Relation inverseRelation,
649 ViatraQueryMatcher<T> matcher) {
650 if (inverseRelation === null) {
651 new MustRelationPropagator(matcher)
652 } else if (relation == inverseRelation) {
653 new MustRelationPropagatorWithSelfInverse(matcher)
654 } else {
655 new MustRelationPropagatorWithInverse(matcher)
656 }
657 }
658
659 @FinalFieldsConstructor
660 private static abstract class AbstractMustRelationPropagator<T extends IPatternMatch> {
661 val ViatraQueryMatcher<T> matcher
662
663 def propagate(LogicProblem p, PartialInterpretation i, RefinementRuleProvider refinementRuleProvider,
664 UnitRulePropagator unitRulePropagator) {
665 val iterator = getIterator(p, i)
666 if (!iterator.hasNext) {
667 return false
668 }
669 iterate(iterator, refinementRuleProvider, unitRulePropagator)
670 true
671 }
672
673 def iterate(Iterator<T> iterator, RefinementRuleProvider refinementRuleProvider,
674 UnitRulePropagator unitRulePropagator) {
675 while (iterator.hasNext) {
676 doPropagate(iterator.next, refinementRuleProvider, unitRulePropagator)
677 }
678 }
679
680 protected def getIterator(LogicProblem p, PartialInterpretation i) {
681 val partialMatch = matcher.newEmptyMatch
682 partialMatch.set(0, p)
683 partialMatch.set(1, i)
684 matcher.streamAllMatches(partialMatch).iterator
685 }
686
687 protected def void doPropagate(T match, RefinementRuleProvider refinementRuleProvider,
688 UnitRulePropagator unitRulePropagator)
689 }
690
691 private static class MustRelationPropagator<T extends IPatternMatch> extends AbstractMustRelationPropagator<T> {
692 new(ViatraQueryMatcher<T> matcher) {
693 super(matcher)
694 }
695
696 override protected doPropagate(T match, RefinementRuleProvider refinementRuleProvider,
697 UnitRulePropagator unitRulePropagator) {
698 refinementRuleProvider.createRelationLinkAction(match, unitRulePropagator)
699 }
700 }
701
702 private static class MustRelationPropagatorWithInverse<T extends IPatternMatch> extends AbstractMustRelationPropagator<T> {
703 new(ViatraQueryMatcher<T> matcher) {
704 super(matcher)
705 }
706
707 override protected doPropagate(T match, RefinementRuleProvider refinementRuleProvider,
708 UnitRulePropagator unitRulePropagator) {
709 refinementRuleProvider.createRelationLinkWithInverse(match, unitRulePropagator)
710 }
711 }
712
713 private static class MustRelationPropagatorWithSelfInverse<T extends IPatternMatch> extends MustRelationPropagatorWithInverse<T> {
714 new(ViatraQueryMatcher<T> matcher) {
715 super(matcher)
716 }
717
718 override iterate(Iterator<T> iterator, RefinementRuleProvider refinementRuleProvider,
719 UnitRulePropagator unitRulePropagator) {
720 val pairs = newHashSet
721 while (iterator.hasNext) {
722 val match = iterator.next
723 val src = match.get(4) as DefinedElement
724 val trg = match.get(5) as DefinedElement
725 if (!pairs.contains(trg -> src)) {
726 pairs.add(src -> trg)
727 doPropagate(match, refinementRuleProvider, unitRulePropagator)
728 }
729 }
730 }
731 }
732 }
733}
734
735@Data
736class ObjectCreationInterpretationData {
737 PartialInterpretation interpretation
738 PartialTypeInterpratation typeInterpretation
739 PartialRelationInterpretation containerInterpretation
740 PartialRelationInterpretation containerInverseInterpretation
741 Function0<DefinedElement> constructor
742 List<ObjectCreationInterpretationData> recursiveConstructors = new LinkedList
226} 743}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/util/ParseUtil.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/util/ParseUtil.xtend
index 8e264488..26ec7091 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/util/ParseUtil.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/util/ParseUtil.xtend
@@ -196,8 +196,20 @@ class ParseUtil {
196} 196}
197 197
198class FixedMetamodelProvider implements IMetamodelProvider { 198class FixedMetamodelProvider implements IMetamodelProvider {
199
200 static val EPACKAGE_TO_PLUGIN_MAP = #{
201 PartialinterpretationPackage.eINSTANCE -> "hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage",
202 LogicproblemPackage.eINSTANCE -> "hu.bme.mit.inf.dslreasoner.logic.model",
203 LogiclanguagePackage.eINSTANCE -> "hu.bme.mit.inf.dslreasoner.logic.model"
204 }
205
206 static val EPACKAGE_TO_JAVA_PACKAGE_MAP = #{
207 PartialinterpretationPackage.eINSTANCE -> "hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation",
208 LogicproblemPackage.eINSTANCE -> "hu.bme.mit.inf.dslreasoner.logic.model.logicproblem",
209 LogiclanguagePackage.eINSTANCE -> "hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage"
210 }
199 211
200 protected val List<EPackage> packages = new LinkedList 212 val List<EPackage> packages = new LinkedList
201 213
202 new() { 214 new() {
203 packages += PartialinterpretationPackage.eINSTANCE 215 packages += PartialinterpretationPackage.eINSTANCE
@@ -213,15 +225,24 @@ class FixedMetamodelProvider implements IMetamodelProvider {
213 } 225 }
214 226
215 override boolean isGeneratedCodeAvailable(EPackage ePackage, ResourceSet set) { 227 override boolean isGeneratedCodeAvailable(EPackage ePackage, ResourceSet set) {
216 true 228 EPACKAGE_TO_PLUGIN_MAP.containsKey(ePackage)
217 } 229 }
218 230
219 override String getModelPluginId(EPackage ePackage, ResourceSet set) { 231 override String getModelPluginId(EPackage ePackage, ResourceSet set) {
220 return "hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage" 232 EPACKAGE_TO_PLUGIN_MAP.get(ePackage)
221 } 233 }
222 234
223 override String getQualifiedClassName(EClassifier classifier, EObject context) { 235 override String getQualifiedClassName(EClassifier classifier, EObject context) {
224 classifier.name 236 val instanceClassName = classifier.instanceClassName
237 if (instanceClassName !== null) {
238 return instanceClassName
239 }
240 val javaPackage = EPACKAGE_TO_JAVA_PACKAGE_MAP.get(classifier.EPackage)
241 if (javaPackage !== null) {
242 javaPackage + "." + classifier.name
243 } else {
244 null
245 }
225 } 246 }
226 247
227 override loadEPackage(String uri, ResourceSet resourceSet) { 248 override loadEPackage(String uri, ResourceSet resourceSet) {
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/META-INF/MANIFEST.MF b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/META-INF/MANIFEST.MF
index 83c90829..639a8a9c 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/META-INF/MANIFEST.MF
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/META-INF/MANIFEST.MF
@@ -28,7 +28,8 @@ Require-Bundle: org.eclipse.core.runtime,
28 org.eclipse.xtend.lib.macro, 28 org.eclipse.xtend.lib.macro,
29 org.eclipse.viatra.query.runtime;bundle-version="1.5.0", 29 org.eclipse.viatra.query.runtime;bundle-version="1.5.0",
30 org.eclipse.viatra.dse;bundle-version="0.15.0", 30 org.eclipse.viatra.dse;bundle-version="0.15.0",
31 hu.bme.mit.inf.dslreasoner.ecore2logic;bundle-version="1.0.0" 31 hu.bme.mit.inf.dslreasoner.ecore2logic;bundle-version="1.0.0",
32 org.eclipse.collections;bundle-version="10.1.0"
32Bundle-ActivationPolicy: lazy 33Bundle-ActivationPolicy: lazy
33Automatic-Module-Name: hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage 34Automatic-Module-Name: hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage
34 35
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/PartialInterpretation.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/PartialInterpretation.java
index 098cc15b..9d0c3fea 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/PartialInterpretation.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/PartialInterpretation.java
@@ -30,6 +30,7 @@ import org.eclipse.emf.ecore.EObject;
30 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation#getScopes <em>Scopes</em>}</li> 30 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation#getScopes <em>Scopes</em>}</li>
31 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation#getMinNewElements <em>Min New Elements</em>}</li> 31 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation#getMinNewElements <em>Min New Elements</em>}</li>
32 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation#getMaxNewElements <em>Max New Elements</em>}</li> 32 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation#getMaxNewElements <em>Max New Elements</em>}</li>
33 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation#getMinNewElementsHeuristic <em>Min New Elements Heuristic</em>}</li>
33 * </ul> 34 * </ul>
34 * 35 *
35 * @see hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage#getPartialInterpretation() 36 * @see hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage#getPartialInterpretation()
@@ -255,4 +256,27 @@ public interface PartialInterpretation extends EObject {
255 */ 256 */
256 void setMaxNewElements(int value); 257 void setMaxNewElements(int value);
257 258
259 /**
260 * Returns the value of the '<em><b>Min New Elements Heuristic</b></em>' attribute.
261 * The default value is <code>"0"</code>.
262 * <!-- begin-user-doc -->
263 * <!-- end-user-doc -->
264 * @return the value of the '<em>Min New Elements Heuristic</em>' attribute.
265 * @see #setMinNewElementsHeuristic(int)
266 * @see hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage#getPartialInterpretation_MinNewElementsHeuristic()
267 * @model default="0" required="true"
268 * @generated
269 */
270 int getMinNewElementsHeuristic();
271
272 /**
273 * Sets the value of the '{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation#getMinNewElementsHeuristic <em>Min New Elements Heuristic</em>}' attribute.
274 * <!-- begin-user-doc -->
275 * <!-- end-user-doc -->
276 * @param value the new value of the '<em>Min New Elements Heuristic</em>' attribute.
277 * @see #getMinNewElementsHeuristic()
278 * @generated
279 */
280 void setMinNewElementsHeuristic(int value);
281
258} // PartialInterpretation 282} // PartialInterpretation
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/PartialinterpretationPackage.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/PartialinterpretationPackage.java
index 4f34b9b7..f462ebe4 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/PartialinterpretationPackage.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/PartialinterpretationPackage.java
@@ -167,13 +167,22 @@ public interface PartialinterpretationPackage extends EPackage {
167 int PARTIAL_INTERPRETATION__MAX_NEW_ELEMENTS = 10; 167 int PARTIAL_INTERPRETATION__MAX_NEW_ELEMENTS = 10;
168 168
169 /** 169 /**
170 * The feature id for the '<em><b>Min New Elements Heuristic</b></em>' attribute.
171 * <!-- begin-user-doc -->
172 * <!-- end-user-doc -->
173 * @generated
174 * @ordered
175 */
176 int PARTIAL_INTERPRETATION__MIN_NEW_ELEMENTS_HEURISTIC = 11;
177
178 /**
170 * The number of structural features of the '<em>Partial Interpretation</em>' class. 179 * The number of structural features of the '<em>Partial Interpretation</em>' class.
171 * <!-- begin-user-doc --> 180 * <!-- begin-user-doc -->
172 * <!-- end-user-doc --> 181 * <!-- end-user-doc -->
173 * @generated 182 * @generated
174 * @ordered 183 * @ordered
175 */ 184 */
176 int PARTIAL_INTERPRETATION_FEATURE_COUNT = 11; 185 int PARTIAL_INTERPRETATION_FEATURE_COUNT = 12;
177 186
178 /** 187 /**
179 * The number of operations of the '<em>Partial Interpretation</em>' class. 188 * The number of operations of the '<em>Partial Interpretation</em>' class.
@@ -913,13 +922,22 @@ public interface PartialinterpretationPackage extends EPackage {
913 int SCOPE__TARGET_TYPE_INTERPRETATION = 2; 922 int SCOPE__TARGET_TYPE_INTERPRETATION = 2;
914 923
915 /** 924 /**
925 * The feature id for the '<em><b>Min New Elements Heuristic</b></em>' attribute.
926 * <!-- begin-user-doc -->
927 * <!-- end-user-doc -->
928 * @generated
929 * @ordered
930 */
931 int SCOPE__MIN_NEW_ELEMENTS_HEURISTIC = 3;
932
933 /**
916 * The number of structural features of the '<em>Scope</em>' class. 934 * The number of structural features of the '<em>Scope</em>' class.
917 * <!-- begin-user-doc --> 935 * <!-- begin-user-doc -->
918 * <!-- end-user-doc --> 936 * <!-- end-user-doc -->
919 * @generated 937 * @generated
920 * @ordered 938 * @ordered
921 */ 939 */
922 int SCOPE_FEATURE_COUNT = 3; 940 int SCOPE_FEATURE_COUNT = 4;
923 941
924 /** 942 /**
925 * The number of operations of the '<em>Scope</em>' class. 943 * The number of operations of the '<em>Scope</em>' class.
@@ -1358,6 +1376,17 @@ public interface PartialinterpretationPackage extends EPackage {
1358 EAttribute getPartialInterpretation_MaxNewElements(); 1376 EAttribute getPartialInterpretation_MaxNewElements();
1359 1377
1360 /** 1378 /**
1379 * Returns the meta object for the attribute '{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation#getMinNewElementsHeuristic <em>Min New Elements Heuristic</em>}'.
1380 * <!-- begin-user-doc -->
1381 * <!-- end-user-doc -->
1382 * @return the meta object for the attribute '<em>Min New Elements Heuristic</em>'.
1383 * @see hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation#getMinNewElementsHeuristic()
1384 * @see #getPartialInterpretation()
1385 * @generated
1386 */
1387 EAttribute getPartialInterpretation_MinNewElementsHeuristic();
1388
1389 /**
1361 * Returns the meta object for class '{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialConstantInterpretation <em>Partial Constant Interpretation</em>}'. 1390 * Returns the meta object for class '{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialConstantInterpretation <em>Partial Constant Interpretation</em>}'.
1362 * <!-- begin-user-doc --> 1391 * <!-- begin-user-doc -->
1363 * <!-- end-user-doc --> 1392 * <!-- end-user-doc -->
@@ -1750,6 +1779,17 @@ public interface PartialinterpretationPackage extends EPackage {
1750 EReference getScope_TargetTypeInterpretation(); 1779 EReference getScope_TargetTypeInterpretation();
1751 1780
1752 /** 1781 /**
1782 * Returns the meta object for the attribute '{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope#getMinNewElementsHeuristic <em>Min New Elements Heuristic</em>}'.
1783 * <!-- begin-user-doc -->
1784 * <!-- end-user-doc -->
1785 * @return the meta object for the attribute '<em>Min New Elements Heuristic</em>'.
1786 * @see hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope#getMinNewElementsHeuristic()
1787 * @see #getScope()
1788 * @generated
1789 */
1790 EAttribute getScope_MinNewElementsHeuristic();
1791
1792 /**
1753 * Returns the meta object for class '{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation <em>Partial Primitive Interpretation</em>}'. 1793 * Returns the meta object for class '{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation <em>Partial Primitive Interpretation</em>}'.
1754 * <!-- begin-user-doc --> 1794 * <!-- begin-user-doc -->
1755 * <!-- end-user-doc --> 1795 * <!-- end-user-doc -->
@@ -1953,6 +1993,14 @@ public interface PartialinterpretationPackage extends EPackage {
1953 EAttribute PARTIAL_INTERPRETATION__MAX_NEW_ELEMENTS = eINSTANCE.getPartialInterpretation_MaxNewElements(); 1993 EAttribute PARTIAL_INTERPRETATION__MAX_NEW_ELEMENTS = eINSTANCE.getPartialInterpretation_MaxNewElements();
1954 1994
1955 /** 1995 /**
1996 * The meta object literal for the '<em><b>Min New Elements Heuristic</b></em>' attribute feature.
1997 * <!-- begin-user-doc -->
1998 * <!-- end-user-doc -->
1999 * @generated
2000 */
2001 EAttribute PARTIAL_INTERPRETATION__MIN_NEW_ELEMENTS_HEURISTIC = eINSTANCE.getPartialInterpretation_MinNewElementsHeuristic();
2002
2003 /**
1956 * The meta object literal for the '{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialConstantInterpretationImpl <em>Partial Constant Interpretation</em>}' class. 2004 * The meta object literal for the '{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialConstantInterpretationImpl <em>Partial Constant Interpretation</em>}' class.
1957 * <!-- begin-user-doc --> 2005 * <!-- begin-user-doc -->
1958 * <!-- end-user-doc --> 2006 * <!-- end-user-doc -->
@@ -2279,6 +2327,14 @@ public interface PartialinterpretationPackage extends EPackage {
2279 EReference SCOPE__TARGET_TYPE_INTERPRETATION = eINSTANCE.getScope_TargetTypeInterpretation(); 2327 EReference SCOPE__TARGET_TYPE_INTERPRETATION = eINSTANCE.getScope_TargetTypeInterpretation();
2280 2328
2281 /** 2329 /**
2330 * The meta object literal for the '<em><b>Min New Elements Heuristic</b></em>' attribute feature.
2331 * <!-- begin-user-doc -->
2332 * <!-- end-user-doc -->
2333 * @generated
2334 */
2335 EAttribute SCOPE__MIN_NEW_ELEMENTS_HEURISTIC = eINSTANCE.getScope_MinNewElementsHeuristic();
2336
2337 /**
2282 * The meta object literal for the '{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialPrimitiveInterpretationImpl <em>Partial Primitive Interpretation</em>}' class. 2338 * The meta object literal for the '{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialPrimitiveInterpretationImpl <em>Partial Primitive Interpretation</em>}' class.
2283 * <!-- begin-user-doc --> 2339 * <!-- begin-user-doc -->
2284 * <!-- end-user-doc --> 2340 * <!-- end-user-doc -->
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/Scope.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/Scope.java
index 155b9f00..a0b58615 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/Scope.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/Scope.java
@@ -16,6 +16,7 @@ import org.eclipse.emf.ecore.EObject;
16 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope#getMinNewElements <em>Min New Elements</em>}</li> 16 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope#getMinNewElements <em>Min New Elements</em>}</li>
17 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope#getMaxNewElements <em>Max New Elements</em>}</li> 17 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope#getMaxNewElements <em>Max New Elements</em>}</li>
18 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope#getTargetTypeInterpretation <em>Target Type Interpretation</em>}</li> 18 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope#getTargetTypeInterpretation <em>Target Type Interpretation</em>}</li>
19 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope#getMinNewElementsHeuristic <em>Min New Elements Heuristic</em>}</li>
19 * </ul> 20 * </ul>
20 * 21 *
21 * @see hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage#getScope() 22 * @see hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage#getScope()
@@ -105,4 +106,27 @@ public interface Scope extends EObject {
105 */ 106 */
106 void setTargetTypeInterpretation(PartialTypeInterpratation value); 107 void setTargetTypeInterpretation(PartialTypeInterpratation value);
107 108
109 /**
110 * Returns the value of the '<em><b>Min New Elements Heuristic</b></em>' attribute.
111 * The default value is <code>"0"</code>.
112 * <!-- begin-user-doc -->
113 * <!-- end-user-doc -->
114 * @return the value of the '<em>Min New Elements Heuristic</em>' attribute.
115 * @see #setMinNewElementsHeuristic(int)
116 * @see hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage#getScope_MinNewElementsHeuristic()
117 * @model default="0" required="true"
118 * @generated
119 */
120 int getMinNewElementsHeuristic();
121
122 /**
123 * Sets the value of the '{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope#getMinNewElementsHeuristic <em>Min New Elements Heuristic</em>}' attribute.
124 * <!-- begin-user-doc -->
125 * <!-- end-user-doc -->
126 * @param value the new value of the '<em>Min New Elements Heuristic</em>' attribute.
127 * @see #getMinNewElementsHeuristic()
128 * @generated
129 */
130 void setMinNewElementsHeuristic(int value);
131
108} // Scope 132} // Scope
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/BinaryElementRelationLinkImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/BinaryElementRelationLinkImpl.java
index f5efe02a..ca33dd65 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/BinaryElementRelationLinkImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/BinaryElementRelationLinkImpl.java
@@ -73,6 +73,7 @@ public class BinaryElementRelationLinkImpl extends RelationLinkImpl implements B
73 * <!-- end-user-doc --> 73 * <!-- end-user-doc -->
74 * @generated 74 * @generated
75 */ 75 */
76 @Override
76 public DefinedElement getParam1() { 77 public DefinedElement getParam1() {
77 if (param1 != null && param1.eIsProxy()) { 78 if (param1 != null && param1.eIsProxy()) {
78 InternalEObject oldParam1 = (InternalEObject)param1; 79 InternalEObject oldParam1 = (InternalEObject)param1;
@@ -99,6 +100,7 @@ public class BinaryElementRelationLinkImpl extends RelationLinkImpl implements B
99 * <!-- end-user-doc --> 100 * <!-- end-user-doc -->
100 * @generated 101 * @generated
101 */ 102 */
103 @Override
102 public void setParam1(DefinedElement newParam1) { 104 public void setParam1(DefinedElement newParam1) {
103 DefinedElement oldParam1 = param1; 105 DefinedElement oldParam1 = param1;
104 param1 = newParam1; 106 param1 = newParam1;
@@ -111,6 +113,7 @@ public class BinaryElementRelationLinkImpl extends RelationLinkImpl implements B
111 * <!-- end-user-doc --> 113 * <!-- end-user-doc -->
112 * @generated 114 * @generated
113 */ 115 */
116 @Override
114 public DefinedElement getParam2() { 117 public DefinedElement getParam2() {
115 if (param2 != null && param2.eIsProxy()) { 118 if (param2 != null && param2.eIsProxy()) {
116 InternalEObject oldParam2 = (InternalEObject)param2; 119 InternalEObject oldParam2 = (InternalEObject)param2;
@@ -137,6 +140,7 @@ public class BinaryElementRelationLinkImpl extends RelationLinkImpl implements B
137 * <!-- end-user-doc --> 140 * <!-- end-user-doc -->
138 * @generated 141 * @generated
139 */ 142 */
143 @Override
140 public void setParam2(DefinedElement newParam2) { 144 public void setParam2(DefinedElement newParam2) {
141 DefinedElement oldParam2 = param2; 145 DefinedElement oldParam2 = param2;
142 param2 = newParam2; 146 param2 = newParam2;
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/BooleanElementImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/BooleanElementImpl.java
index e906e07d..5f12d9e4 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/BooleanElementImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/BooleanElementImpl.java
@@ -69,6 +69,7 @@ public class BooleanElementImpl extends PrimitiveElementImpl implements BooleanE
69 * <!-- end-user-doc --> 69 * <!-- end-user-doc -->
70 * @generated 70 * @generated
71 */ 71 */
72 @Override
72 public boolean isValue() { 73 public boolean isValue() {
73 return value; 74 return value;
74 } 75 }
@@ -78,6 +79,7 @@ public class BooleanElementImpl extends PrimitiveElementImpl implements BooleanE
78 * <!-- end-user-doc --> 79 * <!-- end-user-doc -->
79 * @generated 80 * @generated
80 */ 81 */
82 @Override
81 public void setValue(boolean newValue) { 83 public void setValue(boolean newValue) {
82 boolean oldValue = value; 84 boolean oldValue = value;
83 value = newValue; 85 value = newValue;
@@ -152,7 +154,7 @@ public class BooleanElementImpl extends PrimitiveElementImpl implements BooleanE
152 public String toString() { 154 public String toString() {
153 if (eIsProxy()) return super.toString(); 155 if (eIsProxy()) return super.toString();
154 156
155 StringBuffer result = new StringBuffer(super.toString()); 157 StringBuilder result = new StringBuilder(super.toString());
156 result.append(" (value: "); 158 result.append(" (value: ");
157 result.append(value); 159 result.append(value);
158 result.append(')'); 160 result.append(')');
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/IntegerElementImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/IntegerElementImpl.java
index ef1a4b96..c8fbe1dd 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/IntegerElementImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/IntegerElementImpl.java
@@ -69,6 +69,7 @@ public class IntegerElementImpl extends PrimitiveElementImpl implements IntegerE
69 * <!-- end-user-doc --> 69 * <!-- end-user-doc -->
70 * @generated 70 * @generated
71 */ 71 */
72 @Override
72 public int getValue() { 73 public int getValue() {
73 return value; 74 return value;
74 } 75 }
@@ -78,6 +79,7 @@ public class IntegerElementImpl extends PrimitiveElementImpl implements IntegerE
78 * <!-- end-user-doc --> 79 * <!-- end-user-doc -->
79 * @generated 80 * @generated
80 */ 81 */
82 @Override
81 public void setValue(int newValue) { 83 public void setValue(int newValue) {
82 int oldValue = value; 84 int oldValue = value;
83 value = newValue; 85 value = newValue;
@@ -152,7 +154,7 @@ public class IntegerElementImpl extends PrimitiveElementImpl implements IntegerE
152 public String toString() { 154 public String toString() {
153 if (eIsProxy()) return super.toString(); 155 if (eIsProxy()) return super.toString();
154 156
155 StringBuffer result = new StringBuffer(super.toString()); 157 StringBuilder result = new StringBuilder(super.toString());
156 result.append(" (value: "); 158 result.append(" (value: ");
157 result.append(value); 159 result.append(value);
158 result.append(')'); 160 result.append(')');
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/NaryRelationLinkElementImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/NaryRelationLinkElementImpl.java
index 749a03c5..c319a3f4 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/NaryRelationLinkElementImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/NaryRelationLinkElementImpl.java
@@ -83,6 +83,7 @@ public class NaryRelationLinkElementImpl extends MinimalEObjectImpl.Container im
83 * <!-- end-user-doc --> 83 * <!-- end-user-doc -->
84 * @generated 84 * @generated
85 */ 85 */
86 @Override
86 public int getIndex() { 87 public int getIndex() {
87 return index; 88 return index;
88 } 89 }
@@ -92,6 +93,7 @@ public class NaryRelationLinkElementImpl extends MinimalEObjectImpl.Container im
92 * <!-- end-user-doc --> 93 * <!-- end-user-doc -->
93 * @generated 94 * @generated
94 */ 95 */
96 @Override
95 public void setIndex(int newIndex) { 97 public void setIndex(int newIndex) {
96 int oldIndex = index; 98 int oldIndex = index;
97 index = newIndex; 99 index = newIndex;
@@ -104,6 +106,7 @@ public class NaryRelationLinkElementImpl extends MinimalEObjectImpl.Container im
104 * <!-- end-user-doc --> 106 * <!-- end-user-doc -->
105 * @generated 107 * @generated
106 */ 108 */
109 @Override
107 public DefinedElement getParam() { 110 public DefinedElement getParam() {
108 if (param != null && param.eIsProxy()) { 111 if (param != null && param.eIsProxy()) {
109 InternalEObject oldParam = (InternalEObject)param; 112 InternalEObject oldParam = (InternalEObject)param;
@@ -130,6 +133,7 @@ public class NaryRelationLinkElementImpl extends MinimalEObjectImpl.Container im
130 * <!-- end-user-doc --> 133 * <!-- end-user-doc -->
131 * @generated 134 * @generated
132 */ 135 */
136 @Override
133 public void setParam(DefinedElement newParam) { 137 public void setParam(DefinedElement newParam) {
134 DefinedElement oldParam = param; 138 DefinedElement oldParam = param;
135 param = newParam; 139 param = newParam;
@@ -215,7 +219,7 @@ public class NaryRelationLinkElementImpl extends MinimalEObjectImpl.Container im
215 public String toString() { 219 public String toString() {
216 if (eIsProxy()) return super.toString(); 220 if (eIsProxy()) return super.toString();
217 221
218 StringBuffer result = new StringBuffer(super.toString()); 222 StringBuilder result = new StringBuilder(super.toString());
219 result.append(" (index: "); 223 result.append(" (index: ");
220 result.append(index); 224 result.append(index);
221 result.append(')'); 225 result.append(')');
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/NaryRelationLinkImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/NaryRelationLinkImpl.java
index f387ee06..9f7628cf 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/NaryRelationLinkImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/NaryRelationLinkImpl.java
@@ -66,6 +66,7 @@ public class NaryRelationLinkImpl extends RelationLinkImpl implements NaryRelati
66 * <!-- end-user-doc --> 66 * <!-- end-user-doc -->
67 * @generated 67 * @generated
68 */ 68 */
69 @Override
69 public EList<NaryRelationLinkElement> getElements() { 70 public EList<NaryRelationLinkElement> getElements() {
70 if (elements == null) { 71 if (elements == null) {
71 elements = new EObjectContainmentEList<NaryRelationLinkElement>(NaryRelationLinkElement.class, this, PartialinterpretationPackage.NARY_RELATION_LINK__ELEMENTS); 72 elements = new EObjectContainmentEList<NaryRelationLinkElement>(NaryRelationLinkElement.class, this, PartialinterpretationPackage.NARY_RELATION_LINK__ELEMENTS);
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialComplexTypeInterpretationImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialComplexTypeInterpretationImpl.java
index 07ee282d..c00b4278 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialComplexTypeInterpretationImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialComplexTypeInterpretationImpl.java
@@ -79,6 +79,7 @@ public class PartialComplexTypeInterpretationImpl extends PartialTypeInterpratat
79 * <!-- end-user-doc --> 79 * <!-- end-user-doc -->
80 * @generated 80 * @generated
81 */ 81 */
82 @Override
82 public EList<PartialComplexTypeInterpretation> getSupertypeInterpretation() { 83 public EList<PartialComplexTypeInterpretation> getSupertypeInterpretation() {
83 if (supertypeInterpretation == null) { 84 if (supertypeInterpretation == null) {
84 supertypeInterpretation = new EObjectResolvingEList<PartialComplexTypeInterpretation>(PartialComplexTypeInterpretation.class, this, PartialinterpretationPackage.PARTIAL_COMPLEX_TYPE_INTERPRETATION__SUPERTYPE_INTERPRETATION); 85 supertypeInterpretation = new EObjectResolvingEList<PartialComplexTypeInterpretation>(PartialComplexTypeInterpretation.class, this, PartialinterpretationPackage.PARTIAL_COMPLEX_TYPE_INTERPRETATION__SUPERTYPE_INTERPRETATION);
@@ -91,6 +92,7 @@ public class PartialComplexTypeInterpretationImpl extends PartialTypeInterpratat
91 * <!-- end-user-doc --> 92 * <!-- end-user-doc -->
92 * @generated 93 * @generated
93 */ 94 */
95 @Override
94 public TypeDeclaration getInterpretationOf() { 96 public TypeDeclaration getInterpretationOf() {
95 if (interpretationOf != null && interpretationOf.eIsProxy()) { 97 if (interpretationOf != null && interpretationOf.eIsProxy()) {
96 InternalEObject oldInterpretationOf = (InternalEObject)interpretationOf; 98 InternalEObject oldInterpretationOf = (InternalEObject)interpretationOf;
@@ -117,6 +119,7 @@ public class PartialComplexTypeInterpretationImpl extends PartialTypeInterpratat
117 * <!-- end-user-doc --> 119 * <!-- end-user-doc -->
118 * @generated 120 * @generated
119 */ 121 */
122 @Override
120 public void setInterpretationOf(TypeDeclaration newInterpretationOf) { 123 public void setInterpretationOf(TypeDeclaration newInterpretationOf) {
121 TypeDeclaration oldInterpretationOf = interpretationOf; 124 TypeDeclaration oldInterpretationOf = interpretationOf;
122 interpretationOf = newInterpretationOf; 125 interpretationOf = newInterpretationOf;
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialConstantInterpretationImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialConstantInterpretationImpl.java
index 81b2ce8d..6d51f0db 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialConstantInterpretationImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialConstantInterpretationImpl.java
@@ -63,6 +63,7 @@ public class PartialConstantInterpretationImpl extends MinimalEObjectImpl.Contai
63 * <!-- end-user-doc --> 63 * <!-- end-user-doc -->
64 * @generated 64 * @generated
65 */ 65 */
66 @Override
66 public ConstantDeclaration getInterpretationOf() { 67 public ConstantDeclaration getInterpretationOf() {
67 if (interpretationOf != null && interpretationOf.eIsProxy()) { 68 if (interpretationOf != null && interpretationOf.eIsProxy()) {
68 InternalEObject oldInterpretationOf = (InternalEObject)interpretationOf; 69 InternalEObject oldInterpretationOf = (InternalEObject)interpretationOf;
@@ -89,6 +90,7 @@ public class PartialConstantInterpretationImpl extends MinimalEObjectImpl.Contai
89 * <!-- end-user-doc --> 90 * <!-- end-user-doc -->
90 * @generated 91 * @generated
91 */ 92 */
93 @Override
92 public void setInterpretationOf(ConstantDeclaration newInterpretationOf) { 94 public void setInterpretationOf(ConstantDeclaration newInterpretationOf) {
93 ConstantDeclaration oldInterpretationOf = interpretationOf; 95 ConstantDeclaration oldInterpretationOf = interpretationOf;
94 interpretationOf = newInterpretationOf; 96 interpretationOf = newInterpretationOf;
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialFunctionInterpretationImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialFunctionInterpretationImpl.java
index 2d361e8e..855c4abc 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialFunctionInterpretationImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialFunctionInterpretationImpl.java
@@ -63,6 +63,7 @@ public class PartialFunctionInterpretationImpl extends MinimalEObjectImpl.Contai
63 * <!-- end-user-doc --> 63 * <!-- end-user-doc -->
64 * @generated 64 * @generated
65 */ 65 */
66 @Override
66 public FunctionDeclaration getInterpretationOf() { 67 public FunctionDeclaration getInterpretationOf() {
67 if (interpretationOf != null && interpretationOf.eIsProxy()) { 68 if (interpretationOf != null && interpretationOf.eIsProxy()) {
68 InternalEObject oldInterpretationOf = (InternalEObject)interpretationOf; 69 InternalEObject oldInterpretationOf = (InternalEObject)interpretationOf;
@@ -89,6 +90,7 @@ public class PartialFunctionInterpretationImpl extends MinimalEObjectImpl.Contai
89 * <!-- end-user-doc --> 90 * <!-- end-user-doc -->
90 * @generated 91 * @generated
91 */ 92 */
93 @Override
92 public void setInterpretationOf(FunctionDeclaration newInterpretationOf) { 94 public void setInterpretationOf(FunctionDeclaration newInterpretationOf) {
93 FunctionDeclaration oldInterpretationOf = interpretationOf; 95 FunctionDeclaration oldInterpretationOf = interpretationOf;
94 interpretationOf = newInterpretationOf; 96 interpretationOf = newInterpretationOf;
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialInterpretationImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialInterpretationImpl.java
index bce3e2e0..9afdd8d2 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialInterpretationImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialInterpretationImpl.java
@@ -47,6 +47,7 @@ import org.eclipse.emf.ecore.util.InternalEList;
47 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialInterpretationImpl#getScopes <em>Scopes</em>}</li> 47 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialInterpretationImpl#getScopes <em>Scopes</em>}</li>
48 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialInterpretationImpl#getMinNewElements <em>Min New Elements</em>}</li> 48 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialInterpretationImpl#getMinNewElements <em>Min New Elements</em>}</li>
49 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialInterpretationImpl#getMaxNewElements <em>Max New Elements</em>}</li> 49 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialInterpretationImpl#getMaxNewElements <em>Max New Elements</em>}</li>
50 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.PartialInterpretationImpl#getMinNewElementsHeuristic <em>Min New Elements Heuristic</em>}</li>
50 * </ul> 51 * </ul>
51 * 52 *
52 * @generated 53 * @generated
@@ -183,6 +184,26 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
183 protected int maxNewElements = MAX_NEW_ELEMENTS_EDEFAULT; 184 protected int maxNewElements = MAX_NEW_ELEMENTS_EDEFAULT;
184 185
185 /** 186 /**
187 * The default value of the '{@link #getMinNewElementsHeuristic() <em>Min New Elements Heuristic</em>}' attribute.
188 * <!-- begin-user-doc -->
189 * <!-- end-user-doc -->
190 * @see #getMinNewElementsHeuristic()
191 * @generated
192 * @ordered
193 */
194 protected static final int MIN_NEW_ELEMENTS_HEURISTIC_EDEFAULT = 0;
195
196 /**
197 * The cached value of the '{@link #getMinNewElementsHeuristic() <em>Min New Elements Heuristic</em>}' attribute.
198 * <!-- begin-user-doc -->
199 * <!-- end-user-doc -->
200 * @see #getMinNewElementsHeuristic()
201 * @generated
202 * @ordered
203 */
204 protected int minNewElementsHeuristic = MIN_NEW_ELEMENTS_HEURISTIC_EDEFAULT;
205
206 /**
186 * <!-- begin-user-doc --> 207 * <!-- begin-user-doc -->
187 * <!-- end-user-doc --> 208 * <!-- end-user-doc -->
188 * @generated 209 * @generated
@@ -206,6 +227,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
206 * <!-- end-user-doc --> 227 * <!-- end-user-doc -->
207 * @generated 228 * @generated
208 */ 229 */
230 @Override
209 public LogicProblem getProblem() { 231 public LogicProblem getProblem() {
210 if (problem != null && problem.eIsProxy()) { 232 if (problem != null && problem.eIsProxy()) {
211 InternalEObject oldProblem = (InternalEObject)problem; 233 InternalEObject oldProblem = (InternalEObject)problem;
@@ -232,6 +254,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
232 * <!-- end-user-doc --> 254 * <!-- end-user-doc -->
233 * @generated 255 * @generated
234 */ 256 */
257 @Override
235 public void setProblem(LogicProblem newProblem) { 258 public void setProblem(LogicProblem newProblem) {
236 LogicProblem oldProblem = problem; 259 LogicProblem oldProblem = problem;
237 problem = newProblem; 260 problem = newProblem;
@@ -244,6 +267,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
244 * <!-- end-user-doc --> 267 * <!-- end-user-doc -->
245 * @generated 268 * @generated
246 */ 269 */
270 @Override
247 public EList<PartialConstantInterpretation> getPartialconstantinterpretation() { 271 public EList<PartialConstantInterpretation> getPartialconstantinterpretation() {
248 if (partialconstantinterpretation == null) { 272 if (partialconstantinterpretation == null) {
249 partialconstantinterpretation = new EObjectContainmentEList<PartialConstantInterpretation>(PartialConstantInterpretation.class, this, PartialinterpretationPackage.PARTIAL_INTERPRETATION__PARTIALCONSTANTINTERPRETATION); 273 partialconstantinterpretation = new EObjectContainmentEList<PartialConstantInterpretation>(PartialConstantInterpretation.class, this, PartialinterpretationPackage.PARTIAL_INTERPRETATION__PARTIALCONSTANTINTERPRETATION);
@@ -256,6 +280,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
256 * <!-- end-user-doc --> 280 * <!-- end-user-doc -->
257 * @generated 281 * @generated
258 */ 282 */
283 @Override
259 public EList<PartialRelationInterpretation> getPartialrelationinterpretation() { 284 public EList<PartialRelationInterpretation> getPartialrelationinterpretation() {
260 if (partialrelationinterpretation == null) { 285 if (partialrelationinterpretation == null) {
261 partialrelationinterpretation = new EObjectContainmentEList<PartialRelationInterpretation>(PartialRelationInterpretation.class, this, PartialinterpretationPackage.PARTIAL_INTERPRETATION__PARTIALRELATIONINTERPRETATION); 286 partialrelationinterpretation = new EObjectContainmentEList<PartialRelationInterpretation>(PartialRelationInterpretation.class, this, PartialinterpretationPackage.PARTIAL_INTERPRETATION__PARTIALRELATIONINTERPRETATION);
@@ -268,6 +293,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
268 * <!-- end-user-doc --> 293 * <!-- end-user-doc -->
269 * @generated 294 * @generated
270 */ 295 */
296 @Override
271 public EList<PartialFunctionInterpretation> getPartialfunctioninterpretation() { 297 public EList<PartialFunctionInterpretation> getPartialfunctioninterpretation() {
272 if (partialfunctioninterpretation == null) { 298 if (partialfunctioninterpretation == null) {
273 partialfunctioninterpretation = new EObjectContainmentEList<PartialFunctionInterpretation>(PartialFunctionInterpretation.class, this, PartialinterpretationPackage.PARTIAL_INTERPRETATION__PARTIALFUNCTIONINTERPRETATION); 299 partialfunctioninterpretation = new EObjectContainmentEList<PartialFunctionInterpretation>(PartialFunctionInterpretation.class, this, PartialinterpretationPackage.PARTIAL_INTERPRETATION__PARTIALFUNCTIONINTERPRETATION);
@@ -280,6 +306,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
280 * <!-- end-user-doc --> 306 * <!-- end-user-doc -->
281 * @generated 307 * @generated
282 */ 308 */
309 @Override
283 public EList<DefinedElement> getNewElements() { 310 public EList<DefinedElement> getNewElements() {
284 if (newElements == null) { 311 if (newElements == null) {
285 newElements = new EObjectContainmentEList<DefinedElement>(DefinedElement.class, this, PartialinterpretationPackage.PARTIAL_INTERPRETATION__NEW_ELEMENTS); 312 newElements = new EObjectContainmentEList<DefinedElement>(DefinedElement.class, this, PartialinterpretationPackage.PARTIAL_INTERPRETATION__NEW_ELEMENTS);
@@ -292,6 +319,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
292 * <!-- end-user-doc --> 319 * <!-- end-user-doc -->
293 * @generated 320 * @generated
294 */ 321 */
322 @Override
295 public EList<PartialTypeInterpratation> getPartialtypeinterpratation() { 323 public EList<PartialTypeInterpratation> getPartialtypeinterpratation() {
296 if (partialtypeinterpratation == null) { 324 if (partialtypeinterpratation == null) {
297 partialtypeinterpratation = new EObjectContainmentEList<PartialTypeInterpratation>(PartialTypeInterpratation.class, this, PartialinterpretationPackage.PARTIAL_INTERPRETATION__PARTIALTYPEINTERPRATATION); 325 partialtypeinterpratation = new EObjectContainmentEList<PartialTypeInterpratation>(PartialTypeInterpratation.class, this, PartialinterpretationPackage.PARTIAL_INTERPRETATION__PARTIALTYPEINTERPRATATION);
@@ -304,6 +332,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
304 * <!-- end-user-doc --> 332 * <!-- end-user-doc -->
305 * @generated 333 * @generated
306 */ 334 */
335 @Override
307 public EList<DefinedElement> getOpenWorldElements() { 336 public EList<DefinedElement> getOpenWorldElements() {
308 if (openWorldElements == null) { 337 if (openWorldElements == null) {
309 openWorldElements = new EObjectContainmentEList<DefinedElement>(DefinedElement.class, this, PartialinterpretationPackage.PARTIAL_INTERPRETATION__OPEN_WORLD_ELEMENTS); 338 openWorldElements = new EObjectContainmentEList<DefinedElement>(DefinedElement.class, this, PartialinterpretationPackage.PARTIAL_INTERPRETATION__OPEN_WORLD_ELEMENTS);
@@ -316,6 +345,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
316 * <!-- end-user-doc --> 345 * <!-- end-user-doc -->
317 * @generated 346 * @generated
318 */ 347 */
348 @Override
319 public LogicProblem getProblemConainer() { 349 public LogicProblem getProblemConainer() {
320 return problemConainer; 350 return problemConainer;
321 } 351 }
@@ -340,6 +370,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
340 * <!-- end-user-doc --> 370 * <!-- end-user-doc -->
341 * @generated 371 * @generated
342 */ 372 */
373 @Override
343 public void setProblemConainer(LogicProblem newProblemConainer) { 374 public void setProblemConainer(LogicProblem newProblemConainer) {
344 if (newProblemConainer != problemConainer) { 375 if (newProblemConainer != problemConainer) {
345 NotificationChain msgs = null; 376 NotificationChain msgs = null;
@@ -359,6 +390,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
359 * <!-- end-user-doc --> 390 * <!-- end-user-doc -->
360 * @generated 391 * @generated
361 */ 392 */
393 @Override
362 public EList<Scope> getScopes() { 394 public EList<Scope> getScopes() {
363 if (scopes == null) { 395 if (scopes == null) {
364 scopes = new EObjectContainmentEList<Scope>(Scope.class, this, PartialinterpretationPackage.PARTIAL_INTERPRETATION__SCOPES); 396 scopes = new EObjectContainmentEList<Scope>(Scope.class, this, PartialinterpretationPackage.PARTIAL_INTERPRETATION__SCOPES);
@@ -371,6 +403,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
371 * <!-- end-user-doc --> 403 * <!-- end-user-doc -->
372 * @generated 404 * @generated
373 */ 405 */
406 @Override
374 public int getMinNewElements() { 407 public int getMinNewElements() {
375 return minNewElements; 408 return minNewElements;
376 } 409 }
@@ -380,6 +413,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
380 * <!-- end-user-doc --> 413 * <!-- end-user-doc -->
381 * @generated 414 * @generated
382 */ 415 */
416 @Override
383 public void setMinNewElements(int newMinNewElements) { 417 public void setMinNewElements(int newMinNewElements) {
384 int oldMinNewElements = minNewElements; 418 int oldMinNewElements = minNewElements;
385 minNewElements = newMinNewElements; 419 minNewElements = newMinNewElements;
@@ -392,6 +426,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
392 * <!-- end-user-doc --> 426 * <!-- end-user-doc -->
393 * @generated 427 * @generated
394 */ 428 */
429 @Override
395 public int getMaxNewElements() { 430 public int getMaxNewElements() {
396 return maxNewElements; 431 return maxNewElements;
397 } 432 }
@@ -401,6 +436,7 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
401 * <!-- end-user-doc --> 436 * <!-- end-user-doc -->
402 * @generated 437 * @generated
403 */ 438 */
439 @Override
404 public void setMaxNewElements(int newMaxNewElements) { 440 public void setMaxNewElements(int newMaxNewElements) {
405 int oldMaxNewElements = maxNewElements; 441 int oldMaxNewElements = maxNewElements;
406 maxNewElements = newMaxNewElements; 442 maxNewElements = newMaxNewElements;
@@ -414,6 +450,29 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
414 * @generated 450 * @generated
415 */ 451 */
416 @Override 452 @Override
453 public int getMinNewElementsHeuristic() {
454 return minNewElementsHeuristic;
455 }
456
457 /**
458 * <!-- begin-user-doc -->
459 * <!-- end-user-doc -->
460 * @generated
461 */
462 @Override
463 public void setMinNewElementsHeuristic(int newMinNewElementsHeuristic) {
464 int oldMinNewElementsHeuristic = minNewElementsHeuristic;
465 minNewElementsHeuristic = newMinNewElementsHeuristic;
466 if (eNotificationRequired())
467 eNotify(new ENotificationImpl(this, Notification.SET, PartialinterpretationPackage.PARTIAL_INTERPRETATION__MIN_NEW_ELEMENTS_HEURISTIC, oldMinNewElementsHeuristic, minNewElementsHeuristic));
468 }
469
470 /**
471 * <!-- begin-user-doc -->
472 * <!-- end-user-doc -->
473 * @generated
474 */
475 @Override
417 public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { 476 public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
418 switch (featureID) { 477 switch (featureID) {
419 case PartialinterpretationPackage.PARTIAL_INTERPRETATION__PARTIALCONSTANTINTERPRETATION: 478 case PartialinterpretationPackage.PARTIAL_INTERPRETATION__PARTIALCONSTANTINTERPRETATION:
@@ -467,6 +526,8 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
467 return getMinNewElements(); 526 return getMinNewElements();
468 case PartialinterpretationPackage.PARTIAL_INTERPRETATION__MAX_NEW_ELEMENTS: 527 case PartialinterpretationPackage.PARTIAL_INTERPRETATION__MAX_NEW_ELEMENTS:
469 return getMaxNewElements(); 528 return getMaxNewElements();
529 case PartialinterpretationPackage.PARTIAL_INTERPRETATION__MIN_NEW_ELEMENTS_HEURISTIC:
530 return getMinNewElementsHeuristic();
470 } 531 }
471 return super.eGet(featureID, resolve, coreType); 532 return super.eGet(featureID, resolve, coreType);
472 } 533 }
@@ -520,6 +581,9 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
520 case PartialinterpretationPackage.PARTIAL_INTERPRETATION__MAX_NEW_ELEMENTS: 581 case PartialinterpretationPackage.PARTIAL_INTERPRETATION__MAX_NEW_ELEMENTS:
521 setMaxNewElements((Integer)newValue); 582 setMaxNewElements((Integer)newValue);
522 return; 583 return;
584 case PartialinterpretationPackage.PARTIAL_INTERPRETATION__MIN_NEW_ELEMENTS_HEURISTIC:
585 setMinNewElementsHeuristic((Integer)newValue);
586 return;
523 } 587 }
524 super.eSet(featureID, newValue); 588 super.eSet(featureID, newValue);
525 } 589 }
@@ -565,6 +629,9 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
565 case PartialinterpretationPackage.PARTIAL_INTERPRETATION__MAX_NEW_ELEMENTS: 629 case PartialinterpretationPackage.PARTIAL_INTERPRETATION__MAX_NEW_ELEMENTS:
566 setMaxNewElements(MAX_NEW_ELEMENTS_EDEFAULT); 630 setMaxNewElements(MAX_NEW_ELEMENTS_EDEFAULT);
567 return; 631 return;
632 case PartialinterpretationPackage.PARTIAL_INTERPRETATION__MIN_NEW_ELEMENTS_HEURISTIC:
633 setMinNewElementsHeuristic(MIN_NEW_ELEMENTS_HEURISTIC_EDEFAULT);
634 return;
568 } 635 }
569 super.eUnset(featureID); 636 super.eUnset(featureID);
570 } 637 }
@@ -599,6 +666,8 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
599 return minNewElements != MIN_NEW_ELEMENTS_EDEFAULT; 666 return minNewElements != MIN_NEW_ELEMENTS_EDEFAULT;
600 case PartialinterpretationPackage.PARTIAL_INTERPRETATION__MAX_NEW_ELEMENTS: 667 case PartialinterpretationPackage.PARTIAL_INTERPRETATION__MAX_NEW_ELEMENTS:
601 return maxNewElements != MAX_NEW_ELEMENTS_EDEFAULT; 668 return maxNewElements != MAX_NEW_ELEMENTS_EDEFAULT;
669 case PartialinterpretationPackage.PARTIAL_INTERPRETATION__MIN_NEW_ELEMENTS_HEURISTIC:
670 return minNewElementsHeuristic != MIN_NEW_ELEMENTS_HEURISTIC_EDEFAULT;
602 } 671 }
603 return super.eIsSet(featureID); 672 return super.eIsSet(featureID);
604 } 673 }
@@ -612,11 +681,13 @@ public class PartialInterpretationImpl extends MinimalEObjectImpl.Container impl
612 public String toString() { 681 public String toString() {
613 if (eIsProxy()) return super.toString(); 682 if (eIsProxy()) return super.toString();
614 683
615 StringBuffer result = new StringBuffer(super.toString()); 684 StringBuilder result = new StringBuilder(super.toString());
616 result.append(" (minNewElements: "); 685 result.append(" (minNewElements: ");
617 result.append(minNewElements); 686 result.append(minNewElements);
618 result.append(", maxNewElements: "); 687 result.append(", maxNewElements: ");
619 result.append(maxNewElements); 688 result.append(maxNewElements);
689 result.append(", minNewElementsHeuristic: ");
690 result.append(minNewElementsHeuristic);
620 result.append(')'); 691 result.append(')');
621 return result.toString(); 692 return result.toString();
622 } 693 }
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialRelationInterpretationImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialRelationInterpretationImpl.java
index 71aef9af..7ad06504 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialRelationInterpretationImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialRelationInterpretationImpl.java
@@ -106,6 +106,7 @@ public class PartialRelationInterpretationImpl extends MinimalEObjectImpl.Contai
106 * <!-- end-user-doc --> 106 * <!-- end-user-doc -->
107 * @generated 107 * @generated
108 */ 108 */
109 @Override
109 public RelationDeclaration getInterpretationOf() { 110 public RelationDeclaration getInterpretationOf() {
110 if (interpretationOf != null && interpretationOf.eIsProxy()) { 111 if (interpretationOf != null && interpretationOf.eIsProxy()) {
111 InternalEObject oldInterpretationOf = (InternalEObject)interpretationOf; 112 InternalEObject oldInterpretationOf = (InternalEObject)interpretationOf;
@@ -132,6 +133,7 @@ public class PartialRelationInterpretationImpl extends MinimalEObjectImpl.Contai
132 * <!-- end-user-doc --> 133 * <!-- end-user-doc -->
133 * @generated 134 * @generated
134 */ 135 */
136 @Override
135 public void setInterpretationOf(RelationDeclaration newInterpretationOf) { 137 public void setInterpretationOf(RelationDeclaration newInterpretationOf) {
136 RelationDeclaration oldInterpretationOf = interpretationOf; 138 RelationDeclaration oldInterpretationOf = interpretationOf;
137 interpretationOf = newInterpretationOf; 139 interpretationOf = newInterpretationOf;
@@ -144,6 +146,7 @@ public class PartialRelationInterpretationImpl extends MinimalEObjectImpl.Contai
144 * <!-- end-user-doc --> 146 * <!-- end-user-doc -->
145 * @generated 147 * @generated
146 */ 148 */
149 @Override
147 public EList<RelationLink> getRelationlinks() { 150 public EList<RelationLink> getRelationlinks() {
148 if (relationlinks == null) { 151 if (relationlinks == null) {
149 relationlinks = new EObjectContainmentEList<RelationLink>(RelationLink.class, this, PartialinterpretationPackage.PARTIAL_RELATION_INTERPRETATION__RELATIONLINKS); 152 relationlinks = new EObjectContainmentEList<RelationLink>(RelationLink.class, this, PartialinterpretationPackage.PARTIAL_RELATION_INTERPRETATION__RELATIONLINKS);
@@ -156,6 +159,7 @@ public class PartialRelationInterpretationImpl extends MinimalEObjectImpl.Contai
156 * <!-- end-user-doc --> 159 * <!-- end-user-doc -->
157 * @generated 160 * @generated
158 */ 161 */
162 @Override
159 public TypeReference getParam1() { 163 public TypeReference getParam1() {
160 if (param1 != null && param1.eIsProxy()) { 164 if (param1 != null && param1.eIsProxy()) {
161 InternalEObject oldParam1 = (InternalEObject)param1; 165 InternalEObject oldParam1 = (InternalEObject)param1;
@@ -182,6 +186,7 @@ public class PartialRelationInterpretationImpl extends MinimalEObjectImpl.Contai
182 * <!-- end-user-doc --> 186 * <!-- end-user-doc -->
183 * @generated 187 * @generated
184 */ 188 */
189 @Override
185 public void setParam1(TypeReference newParam1) { 190 public void setParam1(TypeReference newParam1) {
186 TypeReference oldParam1 = param1; 191 TypeReference oldParam1 = param1;
187 param1 = newParam1; 192 param1 = newParam1;
@@ -194,6 +199,7 @@ public class PartialRelationInterpretationImpl extends MinimalEObjectImpl.Contai
194 * <!-- end-user-doc --> 199 * <!-- end-user-doc -->
195 * @generated 200 * @generated
196 */ 201 */
202 @Override
197 public TypeReference getParam2() { 203 public TypeReference getParam2() {
198 if (param2 != null && param2.eIsProxy()) { 204 if (param2 != null && param2.eIsProxy()) {
199 InternalEObject oldParam2 = (InternalEObject)param2; 205 InternalEObject oldParam2 = (InternalEObject)param2;
@@ -220,6 +226,7 @@ public class PartialRelationInterpretationImpl extends MinimalEObjectImpl.Contai
220 * <!-- end-user-doc --> 226 * <!-- end-user-doc -->
221 * @generated 227 * @generated
222 */ 228 */
229 @Override
223 public void setParam2(TypeReference newParam2) { 230 public void setParam2(TypeReference newParam2) {
224 TypeReference oldParam2 = param2; 231 TypeReference oldParam2 = param2;
225 param2 = newParam2; 232 param2 = newParam2;
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialTypeInterpratationImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialTypeInterpratationImpl.java
index da9b1472..51eabd2c 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialTypeInterpratationImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialTypeInterpratationImpl.java
@@ -76,6 +76,7 @@ public abstract class PartialTypeInterpratationImpl extends MinimalEObjectImpl.C
76 * <!-- end-user-doc --> 76 * <!-- end-user-doc -->
77 * @generated 77 * @generated
78 */ 78 */
79 @Override
79 public EList<DefinedElement> getElements() { 80 public EList<DefinedElement> getElements() {
80 if (elements == null) { 81 if (elements == null) {
81 elements = new EObjectResolvingEList<DefinedElement>(DefinedElement.class, this, PartialinterpretationPackage.PARTIAL_TYPE_INTERPRATATION__ELEMENTS); 82 elements = new EObjectResolvingEList<DefinedElement>(DefinedElement.class, this, PartialinterpretationPackage.PARTIAL_TYPE_INTERPRATATION__ELEMENTS);
@@ -88,6 +89,7 @@ public abstract class PartialTypeInterpratationImpl extends MinimalEObjectImpl.C
88 * <!-- end-user-doc --> 89 * <!-- end-user-doc -->
89 * @generated 90 * @generated
90 */ 91 */
92 @Override
91 public EList<Scope> getScopes() { 93 public EList<Scope> getScopes() {
92 if (scopes == null) { 94 if (scopes == null) {
93 scopes = new EObjectWithInverseResolvingEList<Scope>(Scope.class, this, PartialinterpretationPackage.PARTIAL_TYPE_INTERPRATATION__SCOPES, PartialinterpretationPackage.SCOPE__TARGET_TYPE_INTERPRETATION); 95 scopes = new EObjectWithInverseResolvingEList<Scope>(Scope.class, this, PartialinterpretationPackage.PARTIAL_TYPE_INTERPRATATION__SCOPES, PartialinterpretationPackage.SCOPE__TARGET_TYPE_INTERPRETATION);
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialinterpretationFactoryImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialinterpretationFactoryImpl.java
index af1db8a1..06ca4e37 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialinterpretationFactoryImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialinterpretationFactoryImpl.java
@@ -84,6 +84,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
84 * <!-- end-user-doc --> 84 * <!-- end-user-doc -->
85 * @generated 85 * @generated
86 */ 86 */
87 @Override
87 public PartialInterpretation createPartialInterpretation() { 88 public PartialInterpretation createPartialInterpretation() {
88 PartialInterpretationImpl partialInterpretation = new PartialInterpretationImpl(); 89 PartialInterpretationImpl partialInterpretation = new PartialInterpretationImpl();
89 return partialInterpretation; 90 return partialInterpretation;
@@ -94,6 +95,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
94 * <!-- end-user-doc --> 95 * <!-- end-user-doc -->
95 * @generated 96 * @generated
96 */ 97 */
98 @Override
97 public PartialConstantInterpretation createPartialConstantInterpretation() { 99 public PartialConstantInterpretation createPartialConstantInterpretation() {
98 PartialConstantInterpretationImpl partialConstantInterpretation = new PartialConstantInterpretationImpl(); 100 PartialConstantInterpretationImpl partialConstantInterpretation = new PartialConstantInterpretationImpl();
99 return partialConstantInterpretation; 101 return partialConstantInterpretation;
@@ -104,6 +106,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
104 * <!-- end-user-doc --> 106 * <!-- end-user-doc -->
105 * @generated 107 * @generated
106 */ 108 */
109 @Override
107 public PartialRelationInterpretation createPartialRelationInterpretation() { 110 public PartialRelationInterpretation createPartialRelationInterpretation() {
108 PartialRelationInterpretationImpl partialRelationInterpretation = new PartialRelationInterpretationImpl(); 111 PartialRelationInterpretationImpl partialRelationInterpretation = new PartialRelationInterpretationImpl();
109 return partialRelationInterpretation; 112 return partialRelationInterpretation;
@@ -114,6 +117,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
114 * <!-- end-user-doc --> 117 * <!-- end-user-doc -->
115 * @generated 118 * @generated
116 */ 119 */
120 @Override
117 public PartialFunctionInterpretation createPartialFunctionInterpretation() { 121 public PartialFunctionInterpretation createPartialFunctionInterpretation() {
118 PartialFunctionInterpretationImpl partialFunctionInterpretation = new PartialFunctionInterpretationImpl(); 122 PartialFunctionInterpretationImpl partialFunctionInterpretation = new PartialFunctionInterpretationImpl();
119 return partialFunctionInterpretation; 123 return partialFunctionInterpretation;
@@ -124,6 +128,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
124 * <!-- end-user-doc --> 128 * <!-- end-user-doc -->
125 * @generated 129 * @generated
126 */ 130 */
131 @Override
127 public UnaryElementRelationLink createUnaryElementRelationLink() { 132 public UnaryElementRelationLink createUnaryElementRelationLink() {
128 UnaryElementRelationLinkImpl unaryElementRelationLink = new UnaryElementRelationLinkImpl(); 133 UnaryElementRelationLinkImpl unaryElementRelationLink = new UnaryElementRelationLinkImpl();
129 return unaryElementRelationLink; 134 return unaryElementRelationLink;
@@ -134,6 +139,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
134 * <!-- end-user-doc --> 139 * <!-- end-user-doc -->
135 * @generated 140 * @generated
136 */ 141 */
142 @Override
137 public BinaryElementRelationLink createBinaryElementRelationLink() { 143 public BinaryElementRelationLink createBinaryElementRelationLink() {
138 BinaryElementRelationLinkImpl binaryElementRelationLink = new BinaryElementRelationLinkImpl(); 144 BinaryElementRelationLinkImpl binaryElementRelationLink = new BinaryElementRelationLinkImpl();
139 return binaryElementRelationLink; 145 return binaryElementRelationLink;
@@ -144,6 +150,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
144 * <!-- end-user-doc --> 150 * <!-- end-user-doc -->
145 * @generated 151 * @generated
146 */ 152 */
153 @Override
147 public NaryRelationLink createNaryRelationLink() { 154 public NaryRelationLink createNaryRelationLink() {
148 NaryRelationLinkImpl naryRelationLink = new NaryRelationLinkImpl(); 155 NaryRelationLinkImpl naryRelationLink = new NaryRelationLinkImpl();
149 return naryRelationLink; 156 return naryRelationLink;
@@ -154,6 +161,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
154 * <!-- end-user-doc --> 161 * <!-- end-user-doc -->
155 * @generated 162 * @generated
156 */ 163 */
164 @Override
157 public NaryRelationLinkElement createNaryRelationLinkElement() { 165 public NaryRelationLinkElement createNaryRelationLinkElement() {
158 NaryRelationLinkElementImpl naryRelationLinkElement = new NaryRelationLinkElementImpl(); 166 NaryRelationLinkElementImpl naryRelationLinkElement = new NaryRelationLinkElementImpl();
159 return naryRelationLinkElement; 167 return naryRelationLinkElement;
@@ -164,6 +172,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
164 * <!-- end-user-doc --> 172 * <!-- end-user-doc -->
165 * @generated 173 * @generated
166 */ 174 */
175 @Override
167 public BooleanElement createBooleanElement() { 176 public BooleanElement createBooleanElement() {
168 BooleanElementImpl booleanElement = new BooleanElementImpl(); 177 BooleanElementImpl booleanElement = new BooleanElementImpl();
169 return booleanElement; 178 return booleanElement;
@@ -174,6 +183,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
174 * <!-- end-user-doc --> 183 * <!-- end-user-doc -->
175 * @generated 184 * @generated
176 */ 185 */
186 @Override
177 public IntegerElement createIntegerElement() { 187 public IntegerElement createIntegerElement() {
178 IntegerElementImpl integerElement = new IntegerElementImpl(); 188 IntegerElementImpl integerElement = new IntegerElementImpl();
179 return integerElement; 189 return integerElement;
@@ -184,6 +194,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
184 * <!-- end-user-doc --> 194 * <!-- end-user-doc -->
185 * @generated 195 * @generated
186 */ 196 */
197 @Override
187 public RealElement createRealElement() { 198 public RealElement createRealElement() {
188 RealElementImpl realElement = new RealElementImpl(); 199 RealElementImpl realElement = new RealElementImpl();
189 return realElement; 200 return realElement;
@@ -194,6 +205,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
194 * <!-- end-user-doc --> 205 * <!-- end-user-doc -->
195 * @generated 206 * @generated
196 */ 207 */
208 @Override
197 public StringElement createStringElement() { 209 public StringElement createStringElement() {
198 StringElementImpl stringElement = new StringElementImpl(); 210 StringElementImpl stringElement = new StringElementImpl();
199 return stringElement; 211 return stringElement;
@@ -204,6 +216,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
204 * <!-- end-user-doc --> 216 * <!-- end-user-doc -->
205 * @generated 217 * @generated
206 */ 218 */
219 @Override
207 public Scope createScope() { 220 public Scope createScope() {
208 ScopeImpl scope = new ScopeImpl(); 221 ScopeImpl scope = new ScopeImpl();
209 return scope; 222 return scope;
@@ -214,6 +227,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
214 * <!-- end-user-doc --> 227 * <!-- end-user-doc -->
215 * @generated 228 * @generated
216 */ 229 */
230 @Override
217 public PartialBooleanInterpretation createPartialBooleanInterpretation() { 231 public PartialBooleanInterpretation createPartialBooleanInterpretation() {
218 PartialBooleanInterpretationImpl partialBooleanInterpretation = new PartialBooleanInterpretationImpl(); 232 PartialBooleanInterpretationImpl partialBooleanInterpretation = new PartialBooleanInterpretationImpl();
219 return partialBooleanInterpretation; 233 return partialBooleanInterpretation;
@@ -224,6 +238,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
224 * <!-- end-user-doc --> 238 * <!-- end-user-doc -->
225 * @generated 239 * @generated
226 */ 240 */
241 @Override
227 public PartialIntegerInterpretation createPartialIntegerInterpretation() { 242 public PartialIntegerInterpretation createPartialIntegerInterpretation() {
228 PartialIntegerInterpretationImpl partialIntegerInterpretation = new PartialIntegerInterpretationImpl(); 243 PartialIntegerInterpretationImpl partialIntegerInterpretation = new PartialIntegerInterpretationImpl();
229 return partialIntegerInterpretation; 244 return partialIntegerInterpretation;
@@ -234,6 +249,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
234 * <!-- end-user-doc --> 249 * <!-- end-user-doc -->
235 * @generated 250 * @generated
236 */ 251 */
252 @Override
237 public PartialRealInterpretation createPartialRealInterpretation() { 253 public PartialRealInterpretation createPartialRealInterpretation() {
238 PartialRealInterpretationImpl partialRealInterpretation = new PartialRealInterpretationImpl(); 254 PartialRealInterpretationImpl partialRealInterpretation = new PartialRealInterpretationImpl();
239 return partialRealInterpretation; 255 return partialRealInterpretation;
@@ -244,6 +260,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
244 * <!-- end-user-doc --> 260 * <!-- end-user-doc -->
245 * @generated 261 * @generated
246 */ 262 */
263 @Override
247 public PartialStringInterpretation createPartialStringInterpretation() { 264 public PartialStringInterpretation createPartialStringInterpretation() {
248 PartialStringInterpretationImpl partialStringInterpretation = new PartialStringInterpretationImpl(); 265 PartialStringInterpretationImpl partialStringInterpretation = new PartialStringInterpretationImpl();
249 return partialStringInterpretation; 266 return partialStringInterpretation;
@@ -254,6 +271,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
254 * <!-- end-user-doc --> 271 * <!-- end-user-doc -->
255 * @generated 272 * @generated
256 */ 273 */
274 @Override
257 public PartialComplexTypeInterpretation createPartialComplexTypeInterpretation() { 275 public PartialComplexTypeInterpretation createPartialComplexTypeInterpretation() {
258 PartialComplexTypeInterpretationImpl partialComplexTypeInterpretation = new PartialComplexTypeInterpretationImpl(); 276 PartialComplexTypeInterpretationImpl partialComplexTypeInterpretation = new PartialComplexTypeInterpretationImpl();
259 return partialComplexTypeInterpretation; 277 return partialComplexTypeInterpretation;
@@ -264,6 +282,7 @@ public class PartialinterpretationFactoryImpl extends EFactoryImpl implements Pa
264 * <!-- end-user-doc --> 282 * <!-- end-user-doc -->
265 * @generated 283 * @generated
266 */ 284 */
285 @Override
267 public PartialinterpretationPackage getPartialinterpretationPackage() { 286 public PartialinterpretationPackage getPartialinterpretationPackage() {
268 return (PartialinterpretationPackage)getEPackage(); 287 return (PartialinterpretationPackage)getEPackage();
269 } 288 }
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialinterpretationPackageImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialinterpretationPackageImpl.java
index a21dc306..1ea3a11d 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialinterpretationPackageImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PartialinterpretationPackageImpl.java
@@ -227,7 +227,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
227 227
228 /** 228 /**
229 * Creates, registers, and initializes the <b>Package</b> for this model, and for any others upon which it depends. 229 * Creates, registers, and initializes the <b>Package</b> for this model, and for any others upon which it depends.
230 * 230 *
231 * <p>This method is used to initialize {@link PartialinterpretationPackage#eINSTANCE} when that field is accessed. 231 * <p>This method is used to initialize {@link PartialinterpretationPackage#eINSTANCE} when that field is accessed.
232 * Clients should not invoke it directly. Instead, they should simply access that field to obtain the package. 232 * Clients should not invoke it directly. Instead, they should simply access that field to obtain the package.
233 * <!-- begin-user-doc --> 233 * <!-- begin-user-doc -->
@@ -241,7 +241,8 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
241 if (isInited) return (PartialinterpretationPackage)EPackage.Registry.INSTANCE.getEPackage(PartialinterpretationPackage.eNS_URI); 241 if (isInited) return (PartialinterpretationPackage)EPackage.Registry.INSTANCE.getEPackage(PartialinterpretationPackage.eNS_URI);
242 242
243 // Obtain or create and register package 243 // Obtain or create and register package
244 PartialinterpretationPackageImpl thePartialinterpretationPackage = (PartialinterpretationPackageImpl)(EPackage.Registry.INSTANCE.get(eNS_URI) instanceof PartialinterpretationPackageImpl ? EPackage.Registry.INSTANCE.get(eNS_URI) : new PartialinterpretationPackageImpl()); 244 Object registeredPartialinterpretationPackage = EPackage.Registry.INSTANCE.get(eNS_URI);
245 PartialinterpretationPackageImpl thePartialinterpretationPackage = registeredPartialinterpretationPackage instanceof PartialinterpretationPackageImpl ? (PartialinterpretationPackageImpl)registeredPartialinterpretationPackage : new PartialinterpretationPackageImpl();
245 246
246 isInited = true; 247 isInited = true;
247 248
@@ -258,7 +259,6 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
258 // Mark meta-data to indicate it can't be changed 259 // Mark meta-data to indicate it can't be changed
259 thePartialinterpretationPackage.freeze(); 260 thePartialinterpretationPackage.freeze();
260 261
261
262 // Update the registry and return the package 262 // Update the registry and return the package
263 EPackage.Registry.INSTANCE.put(PartialinterpretationPackage.eNS_URI, thePartialinterpretationPackage); 263 EPackage.Registry.INSTANCE.put(PartialinterpretationPackage.eNS_URI, thePartialinterpretationPackage);
264 return thePartialinterpretationPackage; 264 return thePartialinterpretationPackage;
@@ -269,6 +269,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
269 * <!-- end-user-doc --> 269 * <!-- end-user-doc -->
270 * @generated 270 * @generated
271 */ 271 */
272 @Override
272 public EClass getPartialInterpretation() { 273 public EClass getPartialInterpretation() {
273 return partialInterpretationEClass; 274 return partialInterpretationEClass;
274 } 275 }
@@ -278,6 +279,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
278 * <!-- end-user-doc --> 279 * <!-- end-user-doc -->
279 * @generated 280 * @generated
280 */ 281 */
282 @Override
281 public EReference getPartialInterpretation_Problem() { 283 public EReference getPartialInterpretation_Problem() {
282 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(0); 284 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(0);
283 } 285 }
@@ -287,6 +289,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
287 * <!-- end-user-doc --> 289 * <!-- end-user-doc -->
288 * @generated 290 * @generated
289 */ 291 */
292 @Override
290 public EReference getPartialInterpretation_Partialconstantinterpretation() { 293 public EReference getPartialInterpretation_Partialconstantinterpretation() {
291 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(1); 294 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(1);
292 } 295 }
@@ -296,6 +299,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
296 * <!-- end-user-doc --> 299 * <!-- end-user-doc -->
297 * @generated 300 * @generated
298 */ 301 */
302 @Override
299 public EReference getPartialInterpretation_Partialrelationinterpretation() { 303 public EReference getPartialInterpretation_Partialrelationinterpretation() {
300 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(2); 304 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(2);
301 } 305 }
@@ -305,6 +309,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
305 * <!-- end-user-doc --> 309 * <!-- end-user-doc -->
306 * @generated 310 * @generated
307 */ 311 */
312 @Override
308 public EReference getPartialInterpretation_Partialfunctioninterpretation() { 313 public EReference getPartialInterpretation_Partialfunctioninterpretation() {
309 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(3); 314 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(3);
310 } 315 }
@@ -314,6 +319,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
314 * <!-- end-user-doc --> 319 * <!-- end-user-doc -->
315 * @generated 320 * @generated
316 */ 321 */
322 @Override
317 public EReference getPartialInterpretation_NewElements() { 323 public EReference getPartialInterpretation_NewElements() {
318 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(4); 324 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(4);
319 } 325 }
@@ -323,6 +329,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
323 * <!-- end-user-doc --> 329 * <!-- end-user-doc -->
324 * @generated 330 * @generated
325 */ 331 */
332 @Override
326 public EReference getPartialInterpretation_Partialtypeinterpratation() { 333 public EReference getPartialInterpretation_Partialtypeinterpratation() {
327 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(5); 334 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(5);
328 } 335 }
@@ -332,6 +339,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
332 * <!-- end-user-doc --> 339 * <!-- end-user-doc -->
333 * @generated 340 * @generated
334 */ 341 */
342 @Override
335 public EReference getPartialInterpretation_OpenWorldElements() { 343 public EReference getPartialInterpretation_OpenWorldElements() {
336 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(6); 344 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(6);
337 } 345 }
@@ -341,6 +349,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
341 * <!-- end-user-doc --> 349 * <!-- end-user-doc -->
342 * @generated 350 * @generated
343 */ 351 */
352 @Override
344 public EReference getPartialInterpretation_ProblemConainer() { 353 public EReference getPartialInterpretation_ProblemConainer() {
345 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(7); 354 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(7);
346 } 355 }
@@ -350,6 +359,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
350 * <!-- end-user-doc --> 359 * <!-- end-user-doc -->
351 * @generated 360 * @generated
352 */ 361 */
362 @Override
353 public EReference getPartialInterpretation_Scopes() { 363 public EReference getPartialInterpretation_Scopes() {
354 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(8); 364 return (EReference)partialInterpretationEClass.getEStructuralFeatures().get(8);
355 } 365 }
@@ -359,6 +369,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
359 * <!-- end-user-doc --> 369 * <!-- end-user-doc -->
360 * @generated 370 * @generated
361 */ 371 */
372 @Override
362 public EAttribute getPartialInterpretation_MinNewElements() { 373 public EAttribute getPartialInterpretation_MinNewElements() {
363 return (EAttribute)partialInterpretationEClass.getEStructuralFeatures().get(9); 374 return (EAttribute)partialInterpretationEClass.getEStructuralFeatures().get(9);
364 } 375 }
@@ -368,6 +379,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
368 * <!-- end-user-doc --> 379 * <!-- end-user-doc -->
369 * @generated 380 * @generated
370 */ 381 */
382 @Override
371 public EAttribute getPartialInterpretation_MaxNewElements() { 383 public EAttribute getPartialInterpretation_MaxNewElements() {
372 return (EAttribute)partialInterpretationEClass.getEStructuralFeatures().get(10); 384 return (EAttribute)partialInterpretationEClass.getEStructuralFeatures().get(10);
373 } 385 }
@@ -377,6 +389,17 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
377 * <!-- end-user-doc --> 389 * <!-- end-user-doc -->
378 * @generated 390 * @generated
379 */ 391 */
392 @Override
393 public EAttribute getPartialInterpretation_MinNewElementsHeuristic() {
394 return (EAttribute)partialInterpretationEClass.getEStructuralFeatures().get(11);
395 }
396
397 /**
398 * <!-- begin-user-doc -->
399 * <!-- end-user-doc -->
400 * @generated
401 */
402 @Override
380 public EClass getPartialConstantInterpretation() { 403 public EClass getPartialConstantInterpretation() {
381 return partialConstantInterpretationEClass; 404 return partialConstantInterpretationEClass;
382 } 405 }
@@ -386,6 +409,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
386 * <!-- end-user-doc --> 409 * <!-- end-user-doc -->
387 * @generated 410 * @generated
388 */ 411 */
412 @Override
389 public EReference getPartialConstantInterpretation_InterpretationOf() { 413 public EReference getPartialConstantInterpretation_InterpretationOf() {
390 return (EReference)partialConstantInterpretationEClass.getEStructuralFeatures().get(0); 414 return (EReference)partialConstantInterpretationEClass.getEStructuralFeatures().get(0);
391 } 415 }
@@ -395,6 +419,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
395 * <!-- end-user-doc --> 419 * <!-- end-user-doc -->
396 * @generated 420 * @generated
397 */ 421 */
422 @Override
398 public EClass getPartialRelationInterpretation() { 423 public EClass getPartialRelationInterpretation() {
399 return partialRelationInterpretationEClass; 424 return partialRelationInterpretationEClass;
400 } 425 }
@@ -404,6 +429,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
404 * <!-- end-user-doc --> 429 * <!-- end-user-doc -->
405 * @generated 430 * @generated
406 */ 431 */
432 @Override
407 public EReference getPartialRelationInterpretation_InterpretationOf() { 433 public EReference getPartialRelationInterpretation_InterpretationOf() {
408 return (EReference)partialRelationInterpretationEClass.getEStructuralFeatures().get(0); 434 return (EReference)partialRelationInterpretationEClass.getEStructuralFeatures().get(0);
409 } 435 }
@@ -413,6 +439,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
413 * <!-- end-user-doc --> 439 * <!-- end-user-doc -->
414 * @generated 440 * @generated
415 */ 441 */
442 @Override
416 public EReference getPartialRelationInterpretation_Relationlinks() { 443 public EReference getPartialRelationInterpretation_Relationlinks() {
417 return (EReference)partialRelationInterpretationEClass.getEStructuralFeatures().get(1); 444 return (EReference)partialRelationInterpretationEClass.getEStructuralFeatures().get(1);
418 } 445 }
@@ -422,6 +449,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
422 * <!-- end-user-doc --> 449 * <!-- end-user-doc -->
423 * @generated 450 * @generated
424 */ 451 */
452 @Override
425 public EReference getPartialRelationInterpretation_Param1() { 453 public EReference getPartialRelationInterpretation_Param1() {
426 return (EReference)partialRelationInterpretationEClass.getEStructuralFeatures().get(2); 454 return (EReference)partialRelationInterpretationEClass.getEStructuralFeatures().get(2);
427 } 455 }
@@ -431,6 +459,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
431 * <!-- end-user-doc --> 459 * <!-- end-user-doc -->
432 * @generated 460 * @generated
433 */ 461 */
462 @Override
434 public EReference getPartialRelationInterpretation_Param2() { 463 public EReference getPartialRelationInterpretation_Param2() {
435 return (EReference)partialRelationInterpretationEClass.getEStructuralFeatures().get(3); 464 return (EReference)partialRelationInterpretationEClass.getEStructuralFeatures().get(3);
436 } 465 }
@@ -440,6 +469,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
440 * <!-- end-user-doc --> 469 * <!-- end-user-doc -->
441 * @generated 470 * @generated
442 */ 471 */
472 @Override
443 public EClass getPartialFunctionInterpretation() { 473 public EClass getPartialFunctionInterpretation() {
444 return partialFunctionInterpretationEClass; 474 return partialFunctionInterpretationEClass;
445 } 475 }
@@ -449,6 +479,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
449 * <!-- end-user-doc --> 479 * <!-- end-user-doc -->
450 * @generated 480 * @generated
451 */ 481 */
482 @Override
452 public EReference getPartialFunctionInterpretation_InterpretationOf() { 483 public EReference getPartialFunctionInterpretation_InterpretationOf() {
453 return (EReference)partialFunctionInterpretationEClass.getEStructuralFeatures().get(0); 484 return (EReference)partialFunctionInterpretationEClass.getEStructuralFeatures().get(0);
454 } 485 }
@@ -458,6 +489,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
458 * <!-- end-user-doc --> 489 * <!-- end-user-doc -->
459 * @generated 490 * @generated
460 */ 491 */
492 @Override
461 public EClass getPartialTypeInterpratation() { 493 public EClass getPartialTypeInterpratation() {
462 return partialTypeInterpratationEClass; 494 return partialTypeInterpratationEClass;
463 } 495 }
@@ -467,6 +499,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
467 * <!-- end-user-doc --> 499 * <!-- end-user-doc -->
468 * @generated 500 * @generated
469 */ 501 */
502 @Override
470 public EReference getPartialTypeInterpratation_Elements() { 503 public EReference getPartialTypeInterpratation_Elements() {
471 return (EReference)partialTypeInterpratationEClass.getEStructuralFeatures().get(0); 504 return (EReference)partialTypeInterpratationEClass.getEStructuralFeatures().get(0);
472 } 505 }
@@ -476,6 +509,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
476 * <!-- end-user-doc --> 509 * <!-- end-user-doc -->
477 * @generated 510 * @generated
478 */ 511 */
512 @Override
479 public EReference getPartialTypeInterpratation_Scopes() { 513 public EReference getPartialTypeInterpratation_Scopes() {
480 return (EReference)partialTypeInterpratationEClass.getEStructuralFeatures().get(1); 514 return (EReference)partialTypeInterpratationEClass.getEStructuralFeatures().get(1);
481 } 515 }
@@ -485,6 +519,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
485 * <!-- end-user-doc --> 519 * <!-- end-user-doc -->
486 * @generated 520 * @generated
487 */ 521 */
522 @Override
488 public EClass getRelationLink() { 523 public EClass getRelationLink() {
489 return relationLinkEClass; 524 return relationLinkEClass;
490 } 525 }
@@ -494,6 +529,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
494 * <!-- end-user-doc --> 529 * <!-- end-user-doc -->
495 * @generated 530 * @generated
496 */ 531 */
532 @Override
497 public EClass getUnaryElementRelationLink() { 533 public EClass getUnaryElementRelationLink() {
498 return unaryElementRelationLinkEClass; 534 return unaryElementRelationLinkEClass;
499 } 535 }
@@ -503,6 +539,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
503 * <!-- end-user-doc --> 539 * <!-- end-user-doc -->
504 * @generated 540 * @generated
505 */ 541 */
542 @Override
506 public EReference getUnaryElementRelationLink_Param1() { 543 public EReference getUnaryElementRelationLink_Param1() {
507 return (EReference)unaryElementRelationLinkEClass.getEStructuralFeatures().get(0); 544 return (EReference)unaryElementRelationLinkEClass.getEStructuralFeatures().get(0);
508 } 545 }
@@ -512,6 +549,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
512 * <!-- end-user-doc --> 549 * <!-- end-user-doc -->
513 * @generated 550 * @generated
514 */ 551 */
552 @Override
515 public EClass getBinaryElementRelationLink() { 553 public EClass getBinaryElementRelationLink() {
516 return binaryElementRelationLinkEClass; 554 return binaryElementRelationLinkEClass;
517 } 555 }
@@ -521,6 +559,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
521 * <!-- end-user-doc --> 559 * <!-- end-user-doc -->
522 * @generated 560 * @generated
523 */ 561 */
562 @Override
524 public EReference getBinaryElementRelationLink_Param1() { 563 public EReference getBinaryElementRelationLink_Param1() {
525 return (EReference)binaryElementRelationLinkEClass.getEStructuralFeatures().get(0); 564 return (EReference)binaryElementRelationLinkEClass.getEStructuralFeatures().get(0);
526 } 565 }
@@ -530,6 +569,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
530 * <!-- end-user-doc --> 569 * <!-- end-user-doc -->
531 * @generated 570 * @generated
532 */ 571 */
572 @Override
533 public EReference getBinaryElementRelationLink_Param2() { 573 public EReference getBinaryElementRelationLink_Param2() {
534 return (EReference)binaryElementRelationLinkEClass.getEStructuralFeatures().get(1); 574 return (EReference)binaryElementRelationLinkEClass.getEStructuralFeatures().get(1);
535 } 575 }
@@ -539,6 +579,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
539 * <!-- end-user-doc --> 579 * <!-- end-user-doc -->
540 * @generated 580 * @generated
541 */ 581 */
582 @Override
542 public EClass getNaryRelationLink() { 583 public EClass getNaryRelationLink() {
543 return naryRelationLinkEClass; 584 return naryRelationLinkEClass;
544 } 585 }
@@ -548,6 +589,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
548 * <!-- end-user-doc --> 589 * <!-- end-user-doc -->
549 * @generated 590 * @generated
550 */ 591 */
592 @Override
551 public EReference getNaryRelationLink_Elements() { 593 public EReference getNaryRelationLink_Elements() {
552 return (EReference)naryRelationLinkEClass.getEStructuralFeatures().get(0); 594 return (EReference)naryRelationLinkEClass.getEStructuralFeatures().get(0);
553 } 595 }
@@ -557,6 +599,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
557 * <!-- end-user-doc --> 599 * <!-- end-user-doc -->
558 * @generated 600 * @generated
559 */ 601 */
602 @Override
560 public EClass getNaryRelationLinkElement() { 603 public EClass getNaryRelationLinkElement() {
561 return naryRelationLinkElementEClass; 604 return naryRelationLinkElementEClass;
562 } 605 }
@@ -566,6 +609,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
566 * <!-- end-user-doc --> 609 * <!-- end-user-doc -->
567 * @generated 610 * @generated
568 */ 611 */
612 @Override
569 public EAttribute getNaryRelationLinkElement_Index() { 613 public EAttribute getNaryRelationLinkElement_Index() {
570 return (EAttribute)naryRelationLinkElementEClass.getEStructuralFeatures().get(0); 614 return (EAttribute)naryRelationLinkElementEClass.getEStructuralFeatures().get(0);
571 } 615 }
@@ -575,6 +619,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
575 * <!-- end-user-doc --> 619 * <!-- end-user-doc -->
576 * @generated 620 * @generated
577 */ 621 */
622 @Override
578 public EReference getNaryRelationLinkElement_Param() { 623 public EReference getNaryRelationLinkElement_Param() {
579 return (EReference)naryRelationLinkElementEClass.getEStructuralFeatures().get(1); 624 return (EReference)naryRelationLinkElementEClass.getEStructuralFeatures().get(1);
580 } 625 }
@@ -584,6 +629,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
584 * <!-- end-user-doc --> 629 * <!-- end-user-doc -->
585 * @generated 630 * @generated
586 */ 631 */
632 @Override
587 public EClass getPrimitiveElement() { 633 public EClass getPrimitiveElement() {
588 return primitiveElementEClass; 634 return primitiveElementEClass;
589 } 635 }
@@ -593,6 +639,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
593 * <!-- end-user-doc --> 639 * <!-- end-user-doc -->
594 * @generated 640 * @generated
595 */ 641 */
642 @Override
596 public EAttribute getPrimitiveElement_ValueSet() { 643 public EAttribute getPrimitiveElement_ValueSet() {
597 return (EAttribute)primitiveElementEClass.getEStructuralFeatures().get(0); 644 return (EAttribute)primitiveElementEClass.getEStructuralFeatures().get(0);
598 } 645 }
@@ -602,6 +649,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
602 * <!-- end-user-doc --> 649 * <!-- end-user-doc -->
603 * @generated 650 * @generated
604 */ 651 */
652 @Override
605 public EClass getBooleanElement() { 653 public EClass getBooleanElement() {
606 return booleanElementEClass; 654 return booleanElementEClass;
607 } 655 }
@@ -611,6 +659,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
611 * <!-- end-user-doc --> 659 * <!-- end-user-doc -->
612 * @generated 660 * @generated
613 */ 661 */
662 @Override
614 public EAttribute getBooleanElement_Value() { 663 public EAttribute getBooleanElement_Value() {
615 return (EAttribute)booleanElementEClass.getEStructuralFeatures().get(0); 664 return (EAttribute)booleanElementEClass.getEStructuralFeatures().get(0);
616 } 665 }
@@ -620,6 +669,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
620 * <!-- end-user-doc --> 669 * <!-- end-user-doc -->
621 * @generated 670 * @generated
622 */ 671 */
672 @Override
623 public EClass getIntegerElement() { 673 public EClass getIntegerElement() {
624 return integerElementEClass; 674 return integerElementEClass;
625 } 675 }
@@ -629,6 +679,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
629 * <!-- end-user-doc --> 679 * <!-- end-user-doc -->
630 * @generated 680 * @generated
631 */ 681 */
682 @Override
632 public EAttribute getIntegerElement_Value() { 683 public EAttribute getIntegerElement_Value() {
633 return (EAttribute)integerElementEClass.getEStructuralFeatures().get(0); 684 return (EAttribute)integerElementEClass.getEStructuralFeatures().get(0);
634 } 685 }
@@ -638,6 +689,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
638 * <!-- end-user-doc --> 689 * <!-- end-user-doc -->
639 * @generated 690 * @generated
640 */ 691 */
692 @Override
641 public EClass getRealElement() { 693 public EClass getRealElement() {
642 return realElementEClass; 694 return realElementEClass;
643 } 695 }
@@ -647,6 +699,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
647 * <!-- end-user-doc --> 699 * <!-- end-user-doc -->
648 * @generated 700 * @generated
649 */ 701 */
702 @Override
650 public EAttribute getRealElement_Value() { 703 public EAttribute getRealElement_Value() {
651 return (EAttribute)realElementEClass.getEStructuralFeatures().get(0); 704 return (EAttribute)realElementEClass.getEStructuralFeatures().get(0);
652 } 705 }
@@ -656,6 +709,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
656 * <!-- end-user-doc --> 709 * <!-- end-user-doc -->
657 * @generated 710 * @generated
658 */ 711 */
712 @Override
659 public EClass getStringElement() { 713 public EClass getStringElement() {
660 return stringElementEClass; 714 return stringElementEClass;
661 } 715 }
@@ -665,6 +719,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
665 * <!-- end-user-doc --> 719 * <!-- end-user-doc -->
666 * @generated 720 * @generated
667 */ 721 */
722 @Override
668 public EAttribute getStringElement_Value() { 723 public EAttribute getStringElement_Value() {
669 return (EAttribute)stringElementEClass.getEStructuralFeatures().get(0); 724 return (EAttribute)stringElementEClass.getEStructuralFeatures().get(0);
670 } 725 }
@@ -674,6 +729,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
674 * <!-- end-user-doc --> 729 * <!-- end-user-doc -->
675 * @generated 730 * @generated
676 */ 731 */
732 @Override
677 public EClass getScope() { 733 public EClass getScope() {
678 return scopeEClass; 734 return scopeEClass;
679 } 735 }
@@ -683,6 +739,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
683 * <!-- end-user-doc --> 739 * <!-- end-user-doc -->
684 * @generated 740 * @generated
685 */ 741 */
742 @Override
686 public EAttribute getScope_MinNewElements() { 743 public EAttribute getScope_MinNewElements() {
687 return (EAttribute)scopeEClass.getEStructuralFeatures().get(0); 744 return (EAttribute)scopeEClass.getEStructuralFeatures().get(0);
688 } 745 }
@@ -692,6 +749,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
692 * <!-- end-user-doc --> 749 * <!-- end-user-doc -->
693 * @generated 750 * @generated
694 */ 751 */
752 @Override
695 public EAttribute getScope_MaxNewElements() { 753 public EAttribute getScope_MaxNewElements() {
696 return (EAttribute)scopeEClass.getEStructuralFeatures().get(1); 754 return (EAttribute)scopeEClass.getEStructuralFeatures().get(1);
697 } 755 }
@@ -701,6 +759,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
701 * <!-- end-user-doc --> 759 * <!-- end-user-doc -->
702 * @generated 760 * @generated
703 */ 761 */
762 @Override
704 public EReference getScope_TargetTypeInterpretation() { 763 public EReference getScope_TargetTypeInterpretation() {
705 return (EReference)scopeEClass.getEStructuralFeatures().get(2); 764 return (EReference)scopeEClass.getEStructuralFeatures().get(2);
706 } 765 }
@@ -710,6 +769,17 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
710 * <!-- end-user-doc --> 769 * <!-- end-user-doc -->
711 * @generated 770 * @generated
712 */ 771 */
772 @Override
773 public EAttribute getScope_MinNewElementsHeuristic() {
774 return (EAttribute)scopeEClass.getEStructuralFeatures().get(3);
775 }
776
777 /**
778 * <!-- begin-user-doc -->
779 * <!-- end-user-doc -->
780 * @generated
781 */
782 @Override
713 public EClass getPartialPrimitiveInterpretation() { 783 public EClass getPartialPrimitiveInterpretation() {
714 return partialPrimitiveInterpretationEClass; 784 return partialPrimitiveInterpretationEClass;
715 } 785 }
@@ -719,6 +789,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
719 * <!-- end-user-doc --> 789 * <!-- end-user-doc -->
720 * @generated 790 * @generated
721 */ 791 */
792 @Override
722 public EClass getPartialBooleanInterpretation() { 793 public EClass getPartialBooleanInterpretation() {
723 return partialBooleanInterpretationEClass; 794 return partialBooleanInterpretationEClass;
724 } 795 }
@@ -728,6 +799,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
728 * <!-- end-user-doc --> 799 * <!-- end-user-doc -->
729 * @generated 800 * @generated
730 */ 801 */
802 @Override
731 public EClass getPartialIntegerInterpretation() { 803 public EClass getPartialIntegerInterpretation() {
732 return partialIntegerInterpretationEClass; 804 return partialIntegerInterpretationEClass;
733 } 805 }
@@ -737,6 +809,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
737 * <!-- end-user-doc --> 809 * <!-- end-user-doc -->
738 * @generated 810 * @generated
739 */ 811 */
812 @Override
740 public EClass getPartialRealInterpretation() { 813 public EClass getPartialRealInterpretation() {
741 return partialRealInterpretationEClass; 814 return partialRealInterpretationEClass;
742 } 815 }
@@ -746,6 +819,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
746 * <!-- end-user-doc --> 819 * <!-- end-user-doc -->
747 * @generated 820 * @generated
748 */ 821 */
822 @Override
749 public EClass getPartialStringInterpretation() { 823 public EClass getPartialStringInterpretation() {
750 return partialStringInterpretationEClass; 824 return partialStringInterpretationEClass;
751 } 825 }
@@ -755,6 +829,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
755 * <!-- end-user-doc --> 829 * <!-- end-user-doc -->
756 * @generated 830 * @generated
757 */ 831 */
832 @Override
758 public EClass getPartialComplexTypeInterpretation() { 833 public EClass getPartialComplexTypeInterpretation() {
759 return partialComplexTypeInterpretationEClass; 834 return partialComplexTypeInterpretationEClass;
760 } 835 }
@@ -764,6 +839,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
764 * <!-- end-user-doc --> 839 * <!-- end-user-doc -->
765 * @generated 840 * @generated
766 */ 841 */
842 @Override
767 public EReference getPartialComplexTypeInterpretation_SupertypeInterpretation() { 843 public EReference getPartialComplexTypeInterpretation_SupertypeInterpretation() {
768 return (EReference)partialComplexTypeInterpretationEClass.getEStructuralFeatures().get(0); 844 return (EReference)partialComplexTypeInterpretationEClass.getEStructuralFeatures().get(0);
769 } 845 }
@@ -773,6 +849,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
773 * <!-- end-user-doc --> 849 * <!-- end-user-doc -->
774 * @generated 850 * @generated
775 */ 851 */
852 @Override
776 public EReference getPartialComplexTypeInterpretation_InterpretationOf() { 853 public EReference getPartialComplexTypeInterpretation_InterpretationOf() {
777 return (EReference)partialComplexTypeInterpretationEClass.getEStructuralFeatures().get(1); 854 return (EReference)partialComplexTypeInterpretationEClass.getEStructuralFeatures().get(1);
778 } 855 }
@@ -782,6 +859,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
782 * <!-- end-user-doc --> 859 * <!-- end-user-doc -->
783 * @generated 860 * @generated
784 */ 861 */
862 @Override
785 public PartialinterpretationFactory getPartialinterpretationFactory() { 863 public PartialinterpretationFactory getPartialinterpretationFactory() {
786 return (PartialinterpretationFactory)getEFactoryInstance(); 864 return (PartialinterpretationFactory)getEFactoryInstance();
787 } 865 }
@@ -817,6 +895,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
817 createEReference(partialInterpretationEClass, PARTIAL_INTERPRETATION__SCOPES); 895 createEReference(partialInterpretationEClass, PARTIAL_INTERPRETATION__SCOPES);
818 createEAttribute(partialInterpretationEClass, PARTIAL_INTERPRETATION__MIN_NEW_ELEMENTS); 896 createEAttribute(partialInterpretationEClass, PARTIAL_INTERPRETATION__MIN_NEW_ELEMENTS);
819 createEAttribute(partialInterpretationEClass, PARTIAL_INTERPRETATION__MAX_NEW_ELEMENTS); 897 createEAttribute(partialInterpretationEClass, PARTIAL_INTERPRETATION__MAX_NEW_ELEMENTS);
898 createEAttribute(partialInterpretationEClass, PARTIAL_INTERPRETATION__MIN_NEW_ELEMENTS_HEURISTIC);
820 899
821 partialConstantInterpretationEClass = createEClass(PARTIAL_CONSTANT_INTERPRETATION); 900 partialConstantInterpretationEClass = createEClass(PARTIAL_CONSTANT_INTERPRETATION);
822 createEReference(partialConstantInterpretationEClass, PARTIAL_CONSTANT_INTERPRETATION__INTERPRETATION_OF); 901 createEReference(partialConstantInterpretationEClass, PARTIAL_CONSTANT_INTERPRETATION__INTERPRETATION_OF);
@@ -869,6 +948,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
869 createEAttribute(scopeEClass, SCOPE__MIN_NEW_ELEMENTS); 948 createEAttribute(scopeEClass, SCOPE__MIN_NEW_ELEMENTS);
870 createEAttribute(scopeEClass, SCOPE__MAX_NEW_ELEMENTS); 949 createEAttribute(scopeEClass, SCOPE__MAX_NEW_ELEMENTS);
871 createEReference(scopeEClass, SCOPE__TARGET_TYPE_INTERPRETATION); 950 createEReference(scopeEClass, SCOPE__TARGET_TYPE_INTERPRETATION);
951 createEAttribute(scopeEClass, SCOPE__MIN_NEW_ELEMENTS_HEURISTIC);
872 952
873 partialPrimitiveInterpretationEClass = createEClass(PARTIAL_PRIMITIVE_INTERPRETATION); 953 partialPrimitiveInterpretationEClass = createEClass(PARTIAL_PRIMITIVE_INTERPRETATION);
874 954
@@ -945,6 +1025,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
945 initEReference(getPartialInterpretation_Scopes(), this.getScope(), null, "scopes", null, 0, -1, PartialInterpretation.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); 1025 initEReference(getPartialInterpretation_Scopes(), this.getScope(), null, "scopes", null, 0, -1, PartialInterpretation.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
946 initEAttribute(getPartialInterpretation_MinNewElements(), ecorePackage.getEInt(), "minNewElements", "0", 1, 1, PartialInterpretation.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); 1026 initEAttribute(getPartialInterpretation_MinNewElements(), ecorePackage.getEInt(), "minNewElements", "0", 1, 1, PartialInterpretation.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
947 initEAttribute(getPartialInterpretation_MaxNewElements(), ecorePackage.getEInt(), "maxNewElements", "-1", 1, 1, PartialInterpretation.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); 1027 initEAttribute(getPartialInterpretation_MaxNewElements(), ecorePackage.getEInt(), "maxNewElements", "-1", 1, 1, PartialInterpretation.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
1028 initEAttribute(getPartialInterpretation_MinNewElementsHeuristic(), ecorePackage.getEInt(), "minNewElementsHeuristic", "0", 1, 1, PartialInterpretation.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
948 1029
949 initEClass(partialConstantInterpretationEClass, PartialConstantInterpretation.class, "PartialConstantInterpretation", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); 1030 initEClass(partialConstantInterpretationEClass, PartialConstantInterpretation.class, "PartialConstantInterpretation", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
950 initEReference(getPartialConstantInterpretation_InterpretationOf(), theLogiclanguagePackage.getConstantDeclaration(), null, "interpretationOf", null, 1, 1, PartialConstantInterpretation.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); 1031 initEReference(getPartialConstantInterpretation_InterpretationOf(), theLogiclanguagePackage.getConstantDeclaration(), null, "interpretationOf", null, 1, 1, PartialConstantInterpretation.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
@@ -997,6 +1078,7 @@ public class PartialinterpretationPackageImpl extends EPackageImpl implements Pa
997 initEAttribute(getScope_MinNewElements(), ecorePackage.getEInt(), "minNewElements", "0", 1, 1, Scope.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); 1078 initEAttribute(getScope_MinNewElements(), ecorePackage.getEInt(), "minNewElements", "0", 1, 1, Scope.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
998 initEAttribute(getScope_MaxNewElements(), ecorePackage.getEInt(), "maxNewElements", "-1", 1, 1, Scope.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); 1079 initEAttribute(getScope_MaxNewElements(), ecorePackage.getEInt(), "maxNewElements", "-1", 1, 1, Scope.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
999 initEReference(getScope_TargetTypeInterpretation(), this.getPartialTypeInterpratation(), this.getPartialTypeInterpratation_Scopes(), "targetTypeInterpretation", null, 1, 1, Scope.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); 1080 initEReference(getScope_TargetTypeInterpretation(), this.getPartialTypeInterpratation(), this.getPartialTypeInterpratation_Scopes(), "targetTypeInterpretation", null, 1, 1, Scope.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
1081 initEAttribute(getScope_MinNewElementsHeuristic(), ecorePackage.getEInt(), "minNewElementsHeuristic", "0", 1, 1, Scope.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
1000 1082
1001 initEClass(partialPrimitiveInterpretationEClass, PartialPrimitiveInterpretation.class, "PartialPrimitiveInterpretation", IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); 1083 initEClass(partialPrimitiveInterpretationEClass, PartialPrimitiveInterpretation.class, "PartialPrimitiveInterpretation", IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
1002 1084
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PrimitiveElementImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PrimitiveElementImpl.java
index 29a1e1be..a8ef81b0 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PrimitiveElementImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/PrimitiveElementImpl.java
@@ -71,6 +71,7 @@ public abstract class PrimitiveElementImpl extends DefinedElementImpl implements
71 * <!-- end-user-doc --> 71 * <!-- end-user-doc -->
72 * @generated 72 * @generated
73 */ 73 */
74 @Override
74 public boolean isValueSet() { 75 public boolean isValueSet() {
75 return valueSet; 76 return valueSet;
76 } 77 }
@@ -80,6 +81,7 @@ public abstract class PrimitiveElementImpl extends DefinedElementImpl implements
80 * <!-- end-user-doc --> 81 * <!-- end-user-doc -->
81 * @generated 82 * @generated
82 */ 83 */
84 @Override
83 public void setValueSet(boolean newValueSet) { 85 public void setValueSet(boolean newValueSet) {
84 boolean oldValueSet = valueSet; 86 boolean oldValueSet = valueSet;
85 valueSet = newValueSet; 87 valueSet = newValueSet;
@@ -154,7 +156,7 @@ public abstract class PrimitiveElementImpl extends DefinedElementImpl implements
154 public String toString() { 156 public String toString() {
155 if (eIsProxy()) return super.toString(); 157 if (eIsProxy()) return super.toString();
156 158
157 StringBuffer result = new StringBuffer(super.toString()); 159 StringBuilder result = new StringBuilder(super.toString());
158 result.append(" (valueSet: "); 160 result.append(" (valueSet: ");
159 result.append(valueSet); 161 result.append(valueSet);
160 result.append(')'); 162 result.append(')');
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/RealElementImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/RealElementImpl.java
index 0361a3e9..67cff5a2 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/RealElementImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/RealElementImpl.java
@@ -71,6 +71,7 @@ public class RealElementImpl extends PrimitiveElementImpl implements RealElement
71 * <!-- end-user-doc --> 71 * <!-- end-user-doc -->
72 * @generated 72 * @generated
73 */ 73 */
74 @Override
74 public BigDecimal getValue() { 75 public BigDecimal getValue() {
75 return value; 76 return value;
76 } 77 }
@@ -80,6 +81,7 @@ public class RealElementImpl extends PrimitiveElementImpl implements RealElement
80 * <!-- end-user-doc --> 81 * <!-- end-user-doc -->
81 * @generated 82 * @generated
82 */ 83 */
84 @Override
83 public void setValue(BigDecimal newValue) { 85 public void setValue(BigDecimal newValue) {
84 BigDecimal oldValue = value; 86 BigDecimal oldValue = value;
85 value = newValue; 87 value = newValue;
@@ -154,7 +156,7 @@ public class RealElementImpl extends PrimitiveElementImpl implements RealElement
154 public String toString() { 156 public String toString() {
155 if (eIsProxy()) return super.toString(); 157 if (eIsProxy()) return super.toString();
156 158
157 StringBuffer result = new StringBuffer(super.toString()); 159 StringBuilder result = new StringBuilder(super.toString());
158 result.append(" (value: "); 160 result.append(" (value: ");
159 result.append(value); 161 result.append(value);
160 result.append(')'); 162 result.append(')');
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/ScopeImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/ScopeImpl.java
index d8ade871..a1b6de35 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/ScopeImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/ScopeImpl.java
@@ -26,6 +26,7 @@ import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
26 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.ScopeImpl#getMinNewElements <em>Min New Elements</em>}</li> 26 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.ScopeImpl#getMinNewElements <em>Min New Elements</em>}</li>
27 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.ScopeImpl#getMaxNewElements <em>Max New Elements</em>}</li> 27 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.ScopeImpl#getMaxNewElements <em>Max New Elements</em>}</li>
28 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.ScopeImpl#getTargetTypeInterpretation <em>Target Type Interpretation</em>}</li> 28 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.ScopeImpl#getTargetTypeInterpretation <em>Target Type Interpretation</em>}</li>
29 * <li>{@link hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.impl.ScopeImpl#getMinNewElementsHeuristic <em>Min New Elements Heuristic</em>}</li>
29 * </ul> 30 * </ul>
30 * 31 *
31 * @generated 32 * @generated
@@ -82,6 +83,26 @@ public class ScopeImpl extends MinimalEObjectImpl.Container implements Scope {
82 protected PartialTypeInterpratation targetTypeInterpretation; 83 protected PartialTypeInterpratation targetTypeInterpretation;
83 84
84 /** 85 /**
86 * The default value of the '{@link #getMinNewElementsHeuristic() <em>Min New Elements Heuristic</em>}' attribute.
87 * <!-- begin-user-doc -->
88 * <!-- end-user-doc -->
89 * @see #getMinNewElementsHeuristic()
90 * @generated
91 * @ordered
92 */
93 protected static final int MIN_NEW_ELEMENTS_HEURISTIC_EDEFAULT = 0;
94
95 /**
96 * The cached value of the '{@link #getMinNewElementsHeuristic() <em>Min New Elements Heuristic</em>}' attribute.
97 * <!-- begin-user-doc -->
98 * <!-- end-user-doc -->
99 * @see #getMinNewElementsHeuristic()
100 * @generated
101 * @ordered
102 */
103 protected int minNewElementsHeuristic = MIN_NEW_ELEMENTS_HEURISTIC_EDEFAULT;
104
105 /**
85 * <!-- begin-user-doc --> 106 * <!-- begin-user-doc -->
86 * <!-- end-user-doc --> 107 * <!-- end-user-doc -->
87 * @generated 108 * @generated
@@ -105,6 +126,7 @@ public class ScopeImpl extends MinimalEObjectImpl.Container implements Scope {
105 * <!-- end-user-doc --> 126 * <!-- end-user-doc -->
106 * @generated 127 * @generated
107 */ 128 */
129 @Override
108 public int getMinNewElements() { 130 public int getMinNewElements() {
109 return minNewElements; 131 return minNewElements;
110 } 132 }
@@ -114,6 +136,7 @@ public class ScopeImpl extends MinimalEObjectImpl.Container implements Scope {
114 * <!-- end-user-doc --> 136 * <!-- end-user-doc -->
115 * @generated 137 * @generated
116 */ 138 */
139 @Override
117 public void setMinNewElements(int newMinNewElements) { 140 public void setMinNewElements(int newMinNewElements) {
118 int oldMinNewElements = minNewElements; 141 int oldMinNewElements = minNewElements;
119 minNewElements = newMinNewElements; 142 minNewElements = newMinNewElements;
@@ -126,6 +149,7 @@ public class ScopeImpl extends MinimalEObjectImpl.Container implements Scope {
126 * <!-- end-user-doc --> 149 * <!-- end-user-doc -->
127 * @generated 150 * @generated
128 */ 151 */
152 @Override
129 public int getMaxNewElements() { 153 public int getMaxNewElements() {
130 return maxNewElements; 154 return maxNewElements;
131 } 155 }
@@ -135,6 +159,7 @@ public class ScopeImpl extends MinimalEObjectImpl.Container implements Scope {
135 * <!-- end-user-doc --> 159 * <!-- end-user-doc -->
136 * @generated 160 * @generated
137 */ 161 */
162 @Override
138 public void setMaxNewElements(int newMaxNewElements) { 163 public void setMaxNewElements(int newMaxNewElements) {
139 int oldMaxNewElements = maxNewElements; 164 int oldMaxNewElements = maxNewElements;
140 maxNewElements = newMaxNewElements; 165 maxNewElements = newMaxNewElements;
@@ -147,6 +172,7 @@ public class ScopeImpl extends MinimalEObjectImpl.Container implements Scope {
147 * <!-- end-user-doc --> 172 * <!-- end-user-doc -->
148 * @generated 173 * @generated
149 */ 174 */
175 @Override
150 public PartialTypeInterpratation getTargetTypeInterpretation() { 176 public PartialTypeInterpratation getTargetTypeInterpretation() {
151 if (targetTypeInterpretation != null && targetTypeInterpretation.eIsProxy()) { 177 if (targetTypeInterpretation != null && targetTypeInterpretation.eIsProxy()) {
152 InternalEObject oldTargetTypeInterpretation = (InternalEObject)targetTypeInterpretation; 178 InternalEObject oldTargetTypeInterpretation = (InternalEObject)targetTypeInterpretation;
@@ -188,6 +214,7 @@ public class ScopeImpl extends MinimalEObjectImpl.Container implements Scope {
188 * <!-- end-user-doc --> 214 * <!-- end-user-doc -->
189 * @generated 215 * @generated
190 */ 216 */
217 @Override
191 public void setTargetTypeInterpretation(PartialTypeInterpratation newTargetTypeInterpretation) { 218 public void setTargetTypeInterpretation(PartialTypeInterpratation newTargetTypeInterpretation) {
192 if (newTargetTypeInterpretation != targetTypeInterpretation) { 219 if (newTargetTypeInterpretation != targetTypeInterpretation) {
193 NotificationChain msgs = null; 220 NotificationChain msgs = null;
@@ -208,6 +235,29 @@ public class ScopeImpl extends MinimalEObjectImpl.Container implements Scope {
208 * @generated 235 * @generated
209 */ 236 */
210 @Override 237 @Override
238 public int getMinNewElementsHeuristic() {
239 return minNewElementsHeuristic;
240 }
241
242 /**
243 * <!-- begin-user-doc -->
244 * <!-- end-user-doc -->
245 * @generated
246 */
247 @Override
248 public void setMinNewElementsHeuristic(int newMinNewElementsHeuristic) {
249 int oldMinNewElementsHeuristic = minNewElementsHeuristic;
250 minNewElementsHeuristic = newMinNewElementsHeuristic;
251 if (eNotificationRequired())
252 eNotify(new ENotificationImpl(this, Notification.SET, PartialinterpretationPackage.SCOPE__MIN_NEW_ELEMENTS_HEURISTIC, oldMinNewElementsHeuristic, minNewElementsHeuristic));
253 }
254
255 /**
256 * <!-- begin-user-doc -->
257 * <!-- end-user-doc -->
258 * @generated
259 */
260 @Override
211 public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) { 261 public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
212 switch (featureID) { 262 switch (featureID) {
213 case PartialinterpretationPackage.SCOPE__TARGET_TYPE_INTERPRETATION: 263 case PartialinterpretationPackage.SCOPE__TARGET_TYPE_INTERPRETATION:
@@ -247,6 +297,8 @@ public class ScopeImpl extends MinimalEObjectImpl.Container implements Scope {
247 case PartialinterpretationPackage.SCOPE__TARGET_TYPE_INTERPRETATION: 297 case PartialinterpretationPackage.SCOPE__TARGET_TYPE_INTERPRETATION:
248 if (resolve) return getTargetTypeInterpretation(); 298 if (resolve) return getTargetTypeInterpretation();
249 return basicGetTargetTypeInterpretation(); 299 return basicGetTargetTypeInterpretation();
300 case PartialinterpretationPackage.SCOPE__MIN_NEW_ELEMENTS_HEURISTIC:
301 return getMinNewElementsHeuristic();
250 } 302 }
251 return super.eGet(featureID, resolve, coreType); 303 return super.eGet(featureID, resolve, coreType);
252 } 304 }
@@ -268,6 +320,9 @@ public class ScopeImpl extends MinimalEObjectImpl.Container implements Scope {
268 case PartialinterpretationPackage.SCOPE__TARGET_TYPE_INTERPRETATION: 320 case PartialinterpretationPackage.SCOPE__TARGET_TYPE_INTERPRETATION:
269 setTargetTypeInterpretation((PartialTypeInterpratation)newValue); 321 setTargetTypeInterpretation((PartialTypeInterpratation)newValue);
270 return; 322 return;
323 case PartialinterpretationPackage.SCOPE__MIN_NEW_ELEMENTS_HEURISTIC:
324 setMinNewElementsHeuristic((Integer)newValue);
325 return;
271 } 326 }
272 super.eSet(featureID, newValue); 327 super.eSet(featureID, newValue);
273 } 328 }
@@ -289,6 +344,9 @@ public class ScopeImpl extends MinimalEObjectImpl.Container implements Scope {
289 case PartialinterpretationPackage.SCOPE__TARGET_TYPE_INTERPRETATION: 344 case PartialinterpretationPackage.SCOPE__TARGET_TYPE_INTERPRETATION:
290 setTargetTypeInterpretation((PartialTypeInterpratation)null); 345 setTargetTypeInterpretation((PartialTypeInterpratation)null);
291 return; 346 return;
347 case PartialinterpretationPackage.SCOPE__MIN_NEW_ELEMENTS_HEURISTIC:
348 setMinNewElementsHeuristic(MIN_NEW_ELEMENTS_HEURISTIC_EDEFAULT);
349 return;
292 } 350 }
293 super.eUnset(featureID); 351 super.eUnset(featureID);
294 } 352 }
@@ -307,6 +365,8 @@ public class ScopeImpl extends MinimalEObjectImpl.Container implements Scope {
307 return maxNewElements != MAX_NEW_ELEMENTS_EDEFAULT; 365 return maxNewElements != MAX_NEW_ELEMENTS_EDEFAULT;
308 case PartialinterpretationPackage.SCOPE__TARGET_TYPE_INTERPRETATION: 366 case PartialinterpretationPackage.SCOPE__TARGET_TYPE_INTERPRETATION:
309 return targetTypeInterpretation != null; 367 return targetTypeInterpretation != null;
368 case PartialinterpretationPackage.SCOPE__MIN_NEW_ELEMENTS_HEURISTIC:
369 return minNewElementsHeuristic != MIN_NEW_ELEMENTS_HEURISTIC_EDEFAULT;
310 } 370 }
311 return super.eIsSet(featureID); 371 return super.eIsSet(featureID);
312 } 372 }
@@ -320,11 +380,13 @@ public class ScopeImpl extends MinimalEObjectImpl.Container implements Scope {
320 public String toString() { 380 public String toString() {
321 if (eIsProxy()) return super.toString(); 381 if (eIsProxy()) return super.toString();
322 382
323 StringBuffer result = new StringBuffer(super.toString()); 383 StringBuilder result = new StringBuilder(super.toString());
324 result.append(" (minNewElements: "); 384 result.append(" (minNewElements: ");
325 result.append(minNewElements); 385 result.append(minNewElements);
326 result.append(", maxNewElements: "); 386 result.append(", maxNewElements: ");
327 result.append(maxNewElements); 387 result.append(maxNewElements);
388 result.append(", minNewElementsHeuristic: ");
389 result.append(minNewElementsHeuristic);
328 result.append(')'); 390 result.append(')');
329 return result.toString(); 391 return result.toString();
330 } 392 }
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/StringElementImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/StringElementImpl.java
index f207401d..0242c9b2 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/StringElementImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/StringElementImpl.java
@@ -69,6 +69,7 @@ public class StringElementImpl extends PrimitiveElementImpl implements StringEle
69 * <!-- end-user-doc --> 69 * <!-- end-user-doc -->
70 * @generated 70 * @generated
71 */ 71 */
72 @Override
72 public String getValue() { 73 public String getValue() {
73 return value; 74 return value;
74 } 75 }
@@ -78,6 +79,7 @@ public class StringElementImpl extends PrimitiveElementImpl implements StringEle
78 * <!-- end-user-doc --> 79 * <!-- end-user-doc -->
79 * @generated 80 * @generated
80 */ 81 */
82 @Override
81 public void setValue(String newValue) { 83 public void setValue(String newValue) {
82 String oldValue = value; 84 String oldValue = value;
83 value = newValue; 85 value = newValue;
@@ -152,7 +154,7 @@ public class StringElementImpl extends PrimitiveElementImpl implements StringEle
152 public String toString() { 154 public String toString() {
153 if (eIsProxy()) return super.toString(); 155 if (eIsProxy()) return super.toString();
154 156
155 StringBuffer result = new StringBuffer(super.toString()); 157 StringBuilder result = new StringBuilder(super.toString());
156 result.append(" (value: "); 158 result.append(" (value: ");
157 result.append(value); 159 result.append(value);
158 result.append(')'); 160 result.append(')');
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/UnaryElementRelationLinkImpl.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/UnaryElementRelationLinkImpl.java
index 2cb56323..e76a89b7 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/UnaryElementRelationLinkImpl.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/ecore-gen/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/partialinterpretation/impl/UnaryElementRelationLinkImpl.java
@@ -62,6 +62,7 @@ public class UnaryElementRelationLinkImpl extends RelationLinkImpl implements Un
62 * <!-- end-user-doc --> 62 * <!-- end-user-doc -->
63 * @generated 63 * @generated
64 */ 64 */
65 @Override
65 public DefinedElement getParam1() { 66 public DefinedElement getParam1() {
66 if (param1 != null && param1.eIsProxy()) { 67 if (param1 != null && param1.eIsProxy()) {
67 InternalEObject oldParam1 = (InternalEObject)param1; 68 InternalEObject oldParam1 = (InternalEObject)param1;
@@ -88,6 +89,7 @@ public class UnaryElementRelationLinkImpl extends RelationLinkImpl implements Un
88 * <!-- end-user-doc --> 89 * <!-- end-user-doc -->
89 * @generated 90 * @generated
90 */ 91 */
92 @Override
91 public void setParam1(DefinedElement newParam1) { 93 public void setParam1(DefinedElement newParam1) {
92 DefinedElement oldParam1 = param1; 94 DefinedElement oldParam1 = param1;
93 param1 = newParam1; 95 param1 = newParam1;
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/model/PartialInterpretation.ecore b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/model/PartialInterpretation.ecore
index acf82a3f..47d54258 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/model/PartialInterpretation.ecore
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/model/PartialInterpretation.ecore
@@ -27,6 +27,9 @@
27 eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt" defaultValueLiteral="0"/> 27 eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt" defaultValueLiteral="0"/>
28 <eStructuralFeatures xsi:type="ecore:EAttribute" name="maxNewElements" lowerBound="1" 28 <eStructuralFeatures xsi:type="ecore:EAttribute" name="maxNewElements" lowerBound="1"
29 eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt" defaultValueLiteral="-1"/> 29 eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt" defaultValueLiteral="-1"/>
30 <eStructuralFeatures xsi:type="ecore:EAttribute" name="minNewElementsHeuristic"
31 lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"
32 defaultValueLiteral="0"/>
30 </eClassifiers> 33 </eClassifiers>
31 <eClassifiers xsi:type="ecore:EClass" name="PartialConstantInterpretation"> 34 <eClassifiers xsi:type="ecore:EClass" name="PartialConstantInterpretation">
32 <eStructuralFeatures xsi:type="ecore:EReference" name="interpretationOf" lowerBound="1" 35 <eStructuralFeatures xsi:type="ecore:EReference" name="interpretationOf" lowerBound="1"
@@ -92,6 +95,9 @@
92 eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt" defaultValueLiteral="-1"/> 95 eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt" defaultValueLiteral="-1"/>
93 <eStructuralFeatures xsi:type="ecore:EReference" name="targetTypeInterpretation" 96 <eStructuralFeatures xsi:type="ecore:EReference" name="targetTypeInterpretation"
94 lowerBound="1" eType="#//PartialTypeInterpratation" eOpposite="#//PartialTypeInterpratation/scopes"/> 97 lowerBound="1" eType="#//PartialTypeInterpratation" eOpposite="#//PartialTypeInterpratation/scopes"/>
98 <eStructuralFeatures xsi:type="ecore:EAttribute" name="minNewElementsHeuristic"
99 lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"
100 defaultValueLiteral="0"/>
95 </eClassifiers> 101 </eClassifiers>
96 <eClassifiers xsi:type="ecore:EClass" name="PartialPrimitiveInterpretation" abstract="true" 102 <eClassifiers xsi:type="ecore:EClass" name="PartialPrimitiveInterpretation" abstract="true"
97 eSuperTypes="#//PartialTypeInterpratation"/> 103 eSuperTypes="#//PartialTypeInterpratation"/>
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/model/PartialInterpretation.genmodel b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/model/PartialInterpretation.genmodel
index 2ac0a4f3..daeaf594 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/model/PartialInterpretation.genmodel
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/model/PartialInterpretation.genmodel
@@ -18,7 +18,10 @@
18 <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialInterpretation/partialtypeinterpratation"/> 18 <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialInterpretation/partialtypeinterpratation"/>
19 <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialInterpretation/openWorldElements"/> 19 <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialInterpretation/openWorldElements"/>
20 <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialInterpretation/problemConainer"/> 20 <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialInterpretation/problemConainer"/>
21 <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialInterpretation/scope"/> 21 <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialInterpretation/scopes"/>
22 <genFeatures createChild="false" ecoreFeature="ecore:EAttribute PartialInterpretation.ecore#//PartialInterpretation/minNewElements"/>
23 <genFeatures createChild="false" ecoreFeature="ecore:EAttribute PartialInterpretation.ecore#//PartialInterpretation/maxNewElements"/>
24 <genFeatures createChild="false" ecoreFeature="ecore:EAttribute PartialInterpretation.ecore#//PartialInterpretation/minNewElementsHeuristic"/>
22 </genClasses> 25 </genClasses>
23 <genClasses ecoreClass="PartialInterpretation.ecore#//PartialConstantInterpretation"> 26 <genClasses ecoreClass="PartialInterpretation.ecore#//PartialConstantInterpretation">
24 <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialConstantInterpretation/interpretationOf"/> 27 <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialConstantInterpretation/interpretationOf"/>
@@ -33,9 +36,8 @@
33 <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialFunctionInterpretation/interpretationOf"/> 36 <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialFunctionInterpretation/interpretationOf"/>
34 </genClasses> 37 </genClasses>
35 <genClasses ecoreClass="PartialInterpretation.ecore#//PartialTypeInterpratation"> 38 <genClasses ecoreClass="PartialInterpretation.ecore#//PartialTypeInterpratation">
36 <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialTypeInterpratation/interpretationOf"/>
37 <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialTypeInterpratation/elements"/> 39 <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialTypeInterpratation/elements"/>
38 <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialTypeInterpratation/supertypeInterpretation"/> 40 <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialTypeInterpratation/scopes"/>
39 </genClasses> 41 </genClasses>
40 <genClasses image="false" ecoreClass="PartialInterpretation.ecore#//RelationLink"/> 42 <genClasses image="false" ecoreClass="PartialInterpretation.ecore#//RelationLink"/>
41 <genClasses ecoreClass="PartialInterpretation.ecore#//UnaryElementRelationLink"> 43 <genClasses ecoreClass="PartialInterpretation.ecore#//UnaryElementRelationLink">
@@ -50,6 +52,7 @@
50 </genClasses> 52 </genClasses>
51 <genClasses ecoreClass="PartialInterpretation.ecore#//NaryRelationLinkElement"> 53 <genClasses ecoreClass="PartialInterpretation.ecore#//NaryRelationLinkElement">
52 <genFeatures createChild="false" ecoreFeature="ecore:EAttribute PartialInterpretation.ecore#//NaryRelationLinkElement/index"/> 54 <genFeatures createChild="false" ecoreFeature="ecore:EAttribute PartialInterpretation.ecore#//NaryRelationLinkElement/index"/>
55 <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//NaryRelationLinkElement/param"/>
53 </genClasses> 56 </genClasses>
54 <genClasses image="false" ecoreClass="PartialInterpretation.ecore#//PrimitiveElement"> 57 <genClasses image="false" ecoreClass="PartialInterpretation.ecore#//PrimitiveElement">
55 <genFeatures createChild="false" ecoreFeature="ecore:EAttribute PartialInterpretation.ecore#//PrimitiveElement/valueSet"/> 58 <genFeatures createChild="false" ecoreFeature="ecore:EAttribute PartialInterpretation.ecore#//PrimitiveElement/valueSet"/>
@@ -70,11 +73,16 @@
70 <genFeatures createChild="false" ecoreFeature="ecore:EAttribute PartialInterpretation.ecore#//Scope/minNewElements"/> 73 <genFeatures createChild="false" ecoreFeature="ecore:EAttribute PartialInterpretation.ecore#//Scope/minNewElements"/>
71 <genFeatures createChild="false" ecoreFeature="ecore:EAttribute PartialInterpretation.ecore#//Scope/maxNewElements"/> 74 <genFeatures createChild="false" ecoreFeature="ecore:EAttribute PartialInterpretation.ecore#//Scope/maxNewElements"/>
72 <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//Scope/targetTypeInterpretation"/> 75 <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//Scope/targetTypeInterpretation"/>
76 <genFeatures createChild="false" ecoreFeature="ecore:EAttribute PartialInterpretation.ecore#//Scope/minNewElementsHeuristic"/>
73 </genClasses> 77 </genClasses>
74 <genClasses image="false" ecoreClass="PartialInterpretation.ecore#//PartialPrimitiveInterpretation"/> 78 <genClasses image="false" ecoreClass="PartialInterpretation.ecore#//PartialPrimitiveInterpretation"/>
75 <genClasses ecoreClass="PartialInterpretation.ecore#//PartialBooleanInterpretation"/> 79 <genClasses ecoreClass="PartialInterpretation.ecore#//PartialBooleanInterpretation"/>
76 <genClasses ecoreClass="PartialInterpretation.ecore#//PartialIntegerInterpretation"/> 80 <genClasses ecoreClass="PartialInterpretation.ecore#//PartialIntegerInterpretation"/>
77 <genClasses ecoreClass="PartialInterpretation.ecore#//PartialRealInterpretation"/> 81 <genClasses ecoreClass="PartialInterpretation.ecore#//PartialRealInterpretation"/>
78 <genClasses ecoreClass="PartialInterpretation.ecore#//PartialStringInterpretation"/> 82 <genClasses ecoreClass="PartialInterpretation.ecore#//PartialStringInterpretation"/>
83 <genClasses ecoreClass="PartialInterpretation.ecore#//PartialComplexTypeInterpretation">
84 <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialComplexTypeInterpretation/supertypeInterpretation"/>
85 <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PartialInterpretation.ecore#//PartialComplexTypeInterpretation/interpretationOf"/>
86 </genClasses>
79 </genPackages> 87 </genPackages>
80</genmodel:GenModel> 88</genmodel:GenModel>
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretation2logic/InstanceModel2PartialInterpretation.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretation2logic/InstanceModel2PartialInterpretation.xtend
index 8aaaacb5..cb5b587f 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretation2logic/InstanceModel2PartialInterpretation.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretation2logic/InstanceModel2PartialInterpretation.xtend
@@ -1,5 +1,6 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic 1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic
2 2
3import com.google.common.collect.ImmutableList
3import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic 4import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic
4import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic_Trace 5import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic_Trace
5import hu.bme.mit.inf.dslreasoner.logic.model.builder.TracedOutput 6import hu.bme.mit.inf.dslreasoner.logic.model.builder.TracedOutput
@@ -12,18 +13,18 @@ import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.Par
12import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.Problem2PartialInterpretationTrace 13import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.Problem2PartialInterpretationTrace
13import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation 14import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation
14import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory 15import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory
16import java.math.BigDecimal
15import java.util.HashMap 17import java.util.HashMap
18import java.util.HashSet
16import java.util.List 19import java.util.List
17import java.util.Map 20import java.util.Map
21import java.util.Set
18import org.eclipse.emf.common.util.Enumerator 22import org.eclipse.emf.common.util.Enumerator
23import org.eclipse.emf.ecore.EAttribute
19import org.eclipse.emf.ecore.EObject 24import org.eclipse.emf.ecore.EObject
20import org.eclipse.emf.ecore.resource.Resource 25import org.eclipse.emf.ecore.resource.Resource
21 26
22import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* 27import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
23import java.util.HashSet
24import java.util.Set
25import java.math.BigDecimal
26import org.eclipse.emf.ecore.EAttribute
27 28
28class InstanceModel2PartialInterpretation { 29class InstanceModel2PartialInterpretation {
29 val extension LogiclanguageFactory factory = LogiclanguageFactory.eINSTANCE 30 val extension LogiclanguageFactory factory = LogiclanguageFactory.eINSTANCE
@@ -36,7 +37,19 @@ class InstanceModel2PartialInterpretation {
36 Resource resource, 37 Resource resource,
37 boolean withID) 38 boolean withID)
38 { 39 {
39 val objects = resource.allContents.toList 40 val objectsBuilder = ImmutableList.builder
41 val treeIterator = resource.allContents
42 val referencesUsed = ecore2Logic.allReferencesInScope(metamodelTranslationResult.trace).toSet
43 while (treeIterator.hasNext) {
44 val object = treeIterator.next
45 val containingReference = object.eContainmentFeature
46 if (containingReference === null || referencesUsed.contains(containingReference)) {
47 objectsBuilder.add(object)
48 } else {
49 treeIterator.prune
50 }
51 }
52 val objects = objectsBuilder.build
40 return transform(metamodelTranslationResult,objects,withID) 53 return transform(metamodelTranslationResult,objects,withID)
41 } 54 }
42 55
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/PartialInterpretationInitialiser.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/PartialInterpretationInitialiser.xtend
index f7a1ce4f..20ff58f2 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/PartialInterpretationInitialiser.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/PartialInterpretationInitialiser.xtend
@@ -2,19 +2,24 @@ package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage
2 2
3import hu.bme.mit.inf.dslreasoner.logic.model.builder.TracedOutput 3import hu.bme.mit.inf.dslreasoner.logic.model.builder.TracedOutput
4import hu.bme.mit.inf.dslreasoner.logic.model.builder.TypeScopes 4import hu.bme.mit.inf.dslreasoner.logic.model.builder.TypeScopes
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.And
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolLiteral
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement 7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement
8import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntLiteral
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.LogiclanguageFactory 9import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.LogiclanguageFactory
10import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealLiteral
7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration 11import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
12import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDefinition
13import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.StringLiteral
14import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.SymbolicValue
8import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type 15import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
9import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration 16import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration
10import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDefinition 17import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDefinition
11import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem 18import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
12import hu.bme.mit.inf.dslreasoner.logic.model.patterns.SupertypeStar 19import hu.bme.mit.inf.dslreasoner.logic.model.patterns.SupertypeStar
13import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partial2logicannotations.PartialModelRelation2Assertion 20import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partial2logicannotations.PartialModelRelation2Assertion
14import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink
15import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BooleanElement 21import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BooleanElement
16import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.IntegerElement 22import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.IntegerElement
17import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.NaryRelationLink
18import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialBooleanInterpretation 23import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialBooleanInterpretation
19import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation 24import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
20import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialIntegerInterpretation 25import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialIntegerInterpretation
@@ -22,10 +27,10 @@ import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.par
22import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRealInterpretation 27import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRealInterpretation
23import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation 28import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation
24import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialStringInterpretation 29import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialStringInterpretation
30import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation
25import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory 31import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory
26import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.RealElement 32import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.RealElement
27import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.StringElement 33import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.StringElement
28import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.UnaryElementRelationLink
29import java.math.BigDecimal 34import java.math.BigDecimal
30import java.util.HashMap 35import java.util.HashMap
31import java.util.Map 36import java.util.Map
@@ -35,13 +40,6 @@ import org.eclipse.viatra.query.runtime.emf.EMFScope
35import org.eclipse.xtend.lib.annotations.Data 40import org.eclipse.xtend.lib.annotations.Data
36 41
37import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* 42import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
38import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.SymbolicValue
39import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.And
40import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolLiteral
41import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntLiteral
42import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealLiteral
43import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.StringLiteral
44import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation
45 43
46@Data class Problem2PartialInterpretationTrace { 44@Data class Problem2PartialInterpretationTrace {
47 Map<TypeDeclaration, PartialComplexTypeInterpretation> type2Interpretation 45 Map<TypeDeclaration, PartialComplexTypeInterpretation> type2Interpretation
@@ -193,7 +191,7 @@ class PartialInterpretationInitialiser {
193 interpretation.minNewElements = minNewElements 191 interpretation.minNewElements = minNewElements
194 interpretation.maxNewElements = maxNewElements 192 interpretation.maxNewElements = maxNewElements
195 // elements from problem are included 193 // elements from problem are included
196 if(maxNewElements>0) { 194 if(maxNewElements != 0) {
197 val newElements = createDefinedElement => [it.name = "New Objects"] 195 val newElements = createDefinedElement => [it.name = "New Objects"]
198 interpretation.openWorldElements += newElements 196 interpretation.openWorldElements += newElements
199 } 197 }
@@ -212,12 +210,8 @@ class PartialInterpretationInitialiser {
212 def private initialiseTypeScope(PartialTypeInterpratation interpretation, Integer min, Integer max) { 210 def private initialiseTypeScope(PartialTypeInterpratation interpretation, Integer min, Integer max) {
213 val res = createScope 211 val res = createScope
214 res.targetTypeInterpretation = interpretation 212 res.targetTypeInterpretation = interpretation
215 if(min !== null) { 213 res.minNewElements = min ?: 0
216 res.minNewElements = min 214 res.maxNewElements = max ?: -1
217 }
218 if(max !== null) {
219 res.maxNewElements = max
220 }
221 return res 215 return res
222 } 216 }
223 217
@@ -233,7 +227,11 @@ class PartialInterpretationInitialiser {
233 227
234 def private Map<RelationDeclaration, PartialRelationInterpretation> initRelations(PartialInterpretation interpretation, PrimitiveValueTrace trace) { 228 def private Map<RelationDeclaration, PartialRelationInterpretation> initRelations(PartialInterpretation interpretation, PrimitiveValueTrace trace) {
235 val Map<RelationDeclaration, PartialRelationInterpretation> relation2Interpretation = new HashMap 229 val Map<RelationDeclaration, PartialRelationInterpretation> relation2Interpretation = new HashMap
236 for(relation : interpretation.problem.relations.filter(RelationDeclaration)) { 230 val definedRelationDeclarations = interpretation.problem.relations.filter(RelationDefinition).map[defines]
231 val undefinedRelationDeclarations = interpretation.problem.relations.filter(RelationDeclaration).filter[
232 declared | !definedRelationDeclarations.exists[defined | defined === declared]
233 ]
234 for(relation : undefinedRelationDeclarations) {
237 val partialInterpretation = relation.initialisePartialRelationInterpretation 235 val partialInterpretation = relation.initialisePartialRelationInterpretation
238 interpretation.partialrelationinterpretation += partialInterpretation 236 interpretation.partialrelationinterpretation += partialInterpretation
239 relation2Interpretation.put(relation,partialInterpretation) 237 relation2Interpretation.put(relation,partialInterpretation)
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/Descriptor.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/Descriptor.xtend
index 41482b28..685a1f5a 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/Descriptor.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/Descriptor.xtend
@@ -4,10 +4,21 @@ import java.util.HashMap
4import java.util.Map 4import java.util.Map
5import java.util.Set 5import java.util.Set
6import org.eclipse.xtend.lib.annotations.Data 6import org.eclipse.xtend.lib.annotations.Data
7import org.eclipse.xtend2.lib.StringConcatenationClient
7 8
8@Data abstract class AbstractNodeDescriptor { 9@Data abstract class AbstractNodeDescriptor {
9 long dataHash 10 int dataHash
10 11
12 protected def StringConcatenationClient prettyPrint() {
13 '''(«dataHash»)[«class.simpleName»]'''
14 }
15
16 override toString() {
17 '''
18 «prettyPrint»
19 '''
20 }
21
11// @Pure 22// @Pure
12// @Override 23// @Override
13// override public boolean equals(Object obj) { 24// override public boolean equals(Object obj) {
@@ -24,34 +35,45 @@ import org.eclipse.xtend.lib.annotations.Data
24// } 35// }
25} 36}
26 37
27@Data class LocalNodeDescriptor extends AbstractNodeDescriptor{ 38@Data class LocalNodeDescriptor extends AbstractNodeDescriptor {
28 Set<String> types 39 Set<String> types
29 String id; 40 String id;
41
30 new(String id, Set<String> types) { 42 new(String id, Set<String> types) {
31 super(calcualteDataHash(id,types)) 43 super(calcualteDataHash(id, types))
32 this.types = types 44 this.types = types
33 this.id = id 45 this.id = id
34 } 46 }
35 47
36 def private static calcualteDataHash(String id, Set<String> types) { 48 def private static calcualteDataHash(String id, Set<String> types) {
37 val int prime = 31; 49 val int prime = 31;
38 var result = 0 50 var result = 0
39 if(id !== null) 51 if (id !== null)
40 result = id.hashCode(); 52 result = id.hashCode();
41 if(types !== null) { 53 if (types !== null) {
42 result = prime * result + types.hashCode 54 result = prime * result + types.hashCode
43 } 55 }
44 return result 56 return result
45 } 57 }
46 58
47 override hashCode() { 59 override hashCode() {
48 return this.dataHash.hashCode 60 return this.dataHash
49 } 61 }
50 62
63 override equals(Object other) {
64 other.class == LocalNodeDescriptor && (other as AbstractNodeDescriptor).hashCode == hashCode
65 }
66
67 override protected prettyPrint() {
68 '''(«dataHash»)[«IF id !== null»id = "«id»"«IF types === null || !types.empty», «ENDIF»«ENDIF»«IF types === null»TYPES = null«ELSE»«FOR type : types SEPARATOR ", "»«type»«ENDFOR»«ENDIF»]'''
69 }
70
51 override toString() { 71 override toString() {
52 return class.name + this.dataHash 72 '''
73 «prettyPrint»
74 '''
53 } 75 }
54 76
55// @Pure 77// @Pure
56// @Override 78// @Override
57// override public boolean equals(Object obj) { 79// override public boolean equals(Object obj) {
@@ -66,7 +88,6 @@ import org.eclipse.xtend.lib.annotations.Data
66// return false; 88// return false;
67// return true; 89// return true;
68// } 90// }
69
70// @Pure 91// @Pure
71// override public boolean equals(Object obj) { 92// override public boolean equals(Object obj) {
72// if (this === obj) 93// if (this === obj)
@@ -97,118 +118,91 @@ import org.eclipse.xtend.lib.annotations.Data
97 String type 118 String type
98} 119}
99 120
100@Data class FurtherNodeDescriptor<NodeRep> extends AbstractNodeDescriptor{ 121@Data class FurtherNodeDescriptor<NodeRep> extends AbstractNodeDescriptor {
101 122 NodeRep previousRepresentation
102 NodeRep previousRepresentation 123 Map<IncomingRelation<NodeRep>, Integer> incomingEdges
103 Map<IncomingRelation<NodeRep>,Integer> incomingEdges 124 Map<OutgoingRelation<NodeRep>, Integer> outgoingEdges
104 Map<OutgoingRelation<NodeRep>,Integer> outgoingEdges 125
105 126 new(NodeRep previousRepresentation, Map<IncomingRelation<NodeRep>, Integer> incomingEdges,
106 new( 127 Map<OutgoingRelation<NodeRep>, Integer> outgoingEdges) {
107 NodeRep previousRepresentation, 128 super(calculateDataHash(previousRepresentation, incomingEdges, outgoingEdges))
108 Map<IncomingRelation<NodeRep>,Integer> incomingEdges, 129 this.previousRepresentation = previousRepresentation
109 Map<OutgoingRelation<NodeRep>,Integer> outgoingEdges) 130 this.incomingEdges = incomingEdges
110 { 131 this.outgoingEdges = outgoingEdges
111 super(calculateDataHash(previousRepresentation,incomingEdges,outgoingEdges))
112 this.previousRepresentation = previousRepresentation
113 this.incomingEdges = new HashMap(incomingEdges)
114 this.outgoingEdges = new HashMap(outgoingEdges)
115 }
116
117 static def private <NodeRep> int calculateDataHash(
118 NodeRep previousRepresentation,
119 Map<IncomingRelation<NodeRep>,Integer> incomingEdges,
120 Map<OutgoingRelation<NodeRep>,Integer> outgoingEdges)
121 {
122 val int prime = 31;
123 var int result = previousRepresentation.hashCode;
124 if(incomingEdges !== null)
125 result = prime * result + incomingEdges.hashCode();
126 if(outgoingEdges !== null)
127 result = prime * result + outgoingEdges.hashCode();
128 return result;
129 }
130
131 override hashCode() {
132 return this.dataHash.hashCode
133 } 132 }
134 133
135 override toString() { 134 static def private <NodeRep> int calculateDataHash(NodeRep previousRepresentation,
136 return class.name + dataHash 135 Map<IncomingRelation<NodeRep>, Integer> incomingEdges, Map<OutgoingRelation<NodeRep>, Integer> outgoingEdges) {
137// return '''[«previousRepresentation»,(«FOR 136 val int prime = 31;
138// in: incomingEdges.entrySet»(«in.key.type.name»=«in.key.from»,«in.value»)«ENDFOR»),(«FOR 137 var int result = previousRepresentation.hashCode;
139// out: outgoingEdges.entrySet»(«out.key.type.name»=«out.key.to»,«out.value»)«ENDFOR»),«FOR 138 if (incomingEdges !== null)
140// att: attributeValues»(«att.type.name»=«att.value»)«ENDFOR»]''' 139 result = prime * result + hashIncomingNeighborhood(incomingEdges)
140 if (outgoingEdges !== null)
141 result = prime * result + hashOutgoingNeighborhood(outgoingEdges)
142 return result;
141 } 143 }
142
143// @Pure
144// @Override
145// override public boolean equals(Object obj) {
146// if (this === obj)
147// return true;
148// if (obj === null)
149// return false;
150// if (getClass() != obj.getClass())
151// return false;
152// val AbstractNodeDescriptor other = obj as AbstractNodeDescriptor;
153// if (other.dataHash != this.dataHash)
154// return false;
155// return true;
156// }
157
158// @Pure
159// override public boolean equals(Object obj) {
160// if (this === obj)
161// return true;
162// if (obj === null)
163// return false;
164// if (getClass() != obj.getClass())
165// return false;
166// if (!super.equals(obj))
167// return false;
168// val FurtherNodeDescriptor<?> other = obj as FurtherNodeDescriptor<?>;
169// if (this.previousRepresentation === null) {
170// if (other.previousRepresentation != null)
171// return false;
172//
173// }
174//// } else if (!this.previousRepresentation.equals(other.previousRepresentation))
175//// return false;
176// if (this.incomingEdges === null) {
177// if (other.incomingEdges != null)
178// return false;
179// } else if (!this.incomingEdges.equals(other.incomingEdges))
180// return false;
181// if (this.outgoingEdges === null) {
182// if (other.outgoingEdges != null)
183// return false;
184// } else if (!this.outgoingEdges.equals(other.outgoingEdges))
185// return false;
186// if (this.attributeValues === null) {
187// if (other.attributeValues != null)
188// return false;
189// } else if (!this.attributeValues.equals(other.attributeValues))
190// return false;
191// return true;
192// }
193}
194 144
195/* 145 override hashCode() {
196@Data 146 return this.dataHash
197class ModelDescriptor { 147 }
198 int dataHash 148
199 int unknownElements 149 override equals(Object other) {
200 Map<? extends AbstractNodeDescriptor,Integer> knownElements 150 other.class == FurtherNodeDescriptor && (other as AbstractNodeDescriptor).hashCode == hashCode
151 }
152
153 override prettyPrint() {
154 '''
155 («dataHash»)[
156 PREV = «previousRepresentation?.prettyPrint»
157 «IF incomingEdges === null»
158 IN null
159 «ELSE»
160 «FOR edge : incomingEdges.entrySet»
161 IN «edge.value» «edge.key.type» = «edge.key.from.prettyPrint»
162 «ENDFOR»
163 «ENDIF»
164 «IF outgoingEdges === null»
165 OUT null
166 «ELSE»
167 «FOR edge : outgoingEdges.entrySet»
168 OUT «edge.value» «edge.key.type» = «edge.key.to.prettyPrint»
169 «ENDFOR»
170 «ENDIF»
171 ]'''
172 }
173
174 private def StringConcatenationClient prettyPrint(NodeRep rep) {
175 if (rep instanceof AbstractNodeDescriptor) {
176 rep.prettyPrint
177 } else {
178 '''«rep»'''
179 }
180 }
201 181
202 public new(Map<? extends AbstractNodeDescriptor,Integer> knownElements, int unknownElements) { 182 private static def <NodeRep> hashIncomingNeighborhood(Map<IncomingRelation<NodeRep>, Integer> neighborhood) {
203 this.dataHash = calculateDataHash(knownElements,unknownElements) 183 val int prime = 31
204 this.unknownElements = unknownElements 184 var int hash = 0
205 this.knownElements = knownElements 185 for (entry : neighborhood.entrySet) {
186 val relation = entry.key
187 hash += (prime * relation.from.hashCode + relation.type.hashCode).bitwiseXor(entry.value.hashCode)
188 }
189 hash
206 } 190 }
207 191
208 def private static calculateDataHash(Map<? extends AbstractNodeDescriptor,Integer> knownElements, int unknownElements) 192 private static def <NodeRep> hashOutgoingNeighborhood(Map<OutgoingRelation<NodeRep>, Integer> neighborhood) {
209 { 193 val int prime = 31
210 val int prime = 31; 194 var int hash = 0
211 return knownElements.hashCode * prime + unknownElements.hashCode 195 for (entry : neighborhood.entrySet) {
196 val relation = entry.key
197 hash += (prime * relation.to.hashCode + relation.type.hashCode).bitwiseXor(entry.value.hashCode)
198 }
199 hash
200 }
201
202 override toString() {
203 '''
204 «prettyPrint»
205 '''
212 } 206 }
213} 207}
214*/ \ No newline at end of file 208
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/NeighbourhoodOptions.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/NeighbourhoodOptions.xtend
new file mode 100644
index 00000000..c6e03f75
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/NeighbourhoodOptions.xtend
@@ -0,0 +1,22 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood
2
3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration
5import java.util.Set
6import org.eclipse.xtend.lib.annotations.Data
7
8@Data
9class NeighbourhoodOptions {
10 public static val FixPointRange = -1
11 public static val GraphWidthRange = -2
12 public static val FullParallels = Integer.MAX_VALUE
13 public static val MaxNumbers = Integer.MAX_VALUE
14
15 public static val DEFAULT = new NeighbourhoodOptions(FixPointRange, FullParallels, MaxNumbers, null, null)
16
17 val int range
18 val int parallels
19 val int maxNumber
20 val Set<TypeDeclaration> relevantTypes
21 val Set<RelationDeclaration> relevantRelations
22}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2Hash.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2Hash.xtend
index d474877d..5da202eb 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2Hash.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2Hash.xtend
@@ -1,25 +1,33 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood 1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood
2 2
3import java.util.Map
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement 3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement
4import java.util.Map
5import org.eclipse.collections.api.factory.Maps
5 6
6class PartialInterpretation2Hash extends PartialInterpretation2NeighbourhoodRepresentation<Integer, Integer>{ 7class PartialInterpretation2Hash extends PartialInterpretation2NeighbourhoodRepresentation<Integer, Integer>{
7 8
8 protected new() { 9 new() {
9 super(false, true) 10 super(false, true)
10 } 11 }
11 12
12 override protected createLocalRepresentation(Map<DefinedElement, LocalNodeDescriptor> node2Representation, Map<LocalNodeDescriptor, Integer> representation2Amount) { 13 override protected createLocalRepresentation(Map<DefinedElement, LocalNodeDescriptor> node2Representation, Map<LocalNodeDescriptor, Integer> representation2Amount) {
13 return new NeighbourhoodWithTraces( 14 return new NeighbourhoodWithTraces(
14 representation2Amount.hashCode,node2Representation.mapValues[it.hashCode], 15 representation2Amount.hashCode,node2Representation.hashValues,
15 null) 16 null)
16 } 17 }
17 18
18 override protected createFurtherRepresentation(Map<FurtherNodeDescriptor<Integer>, Integer> nodeDescriptors, Map<DefinedElement, FurtherNodeDescriptor<Integer>> node2Representation, NeighbourhoodWithTraces<Integer, Integer> previous, boolean deepRepresentation) { 19 override protected createFurtherRepresentation(Map<FurtherNodeDescriptor<Integer>, Integer> nodeDescriptors, Map<DefinedElement, FurtherNodeDescriptor<Integer>> node2Representation, NeighbourhoodWithTraces<Integer, Integer> previous, boolean deepRepresentation) {
19 return new NeighbourhoodWithTraces( 20 return new NeighbourhoodWithTraces(
20 nodeDescriptors.hashCode, 21 nodeDescriptors.hashCode,
21 node2Representation.mapValues[it.hashCode], 22 node2Representation.hashValues,
22 if(deepRepresentation) {previous} else {null}) 23 if(deepRepresentation) {previous} else {null})
23 } 24 }
24 25
26 private def <T> hashValues(Map<DefinedElement, T> map) {
27 val hashedMap = Maps.mutable.ofInitialCapacity(map.size)
28 for (entry : map.entrySet) {
29 hashedMap.put(entry.key, entry.value.hashCode)
30 }
31 hashedMap
32 }
25} 33}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend
index 6dc40705..93eab816 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2NeighbourhoodRepresentation.xtend
@@ -4,32 +4,34 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration 4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration 5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink 6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
8import java.util.HashMap 9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation
9import java.util.HashSet 10import java.util.ArrayList
10import java.util.LinkedList
11import java.util.List 11import java.util.List
12import java.util.Map 12import java.util.Map
13import java.util.Set 13import java.util.Set
14import org.eclipse.collections.api.factory.Maps
15import org.eclipse.collections.impl.factory.Sets
14 16
15import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* 17import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
16import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation
17import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
18 18
19abstract class PartialInterpretation2NeighbourhoodRepresentation<ModelRepresentation,NodeRepresentation> { 19abstract class PartialInterpretation2NeighbourhoodRepresentation<ModelRepresentation, NodeRepresentation> {
20 private val boolean deepRepresentation 20 val boolean deepRepresentation
21 private val boolean mergeSimilarNeighbourhood 21 val boolean mergeSimilarNeighbourhood
22 22
23 protected new(boolean deeprepresentation, boolean mergeSimilarNeighbourhood) { 23 protected new(boolean deeprepresentation, boolean mergeSimilarNeighbourhood) {
24 this.deepRepresentation = deeprepresentation 24 this.deepRepresentation = deeprepresentation
25 this.mergeSimilarNeighbourhood = mergeSimilarNeighbourhood 25 this.mergeSimilarNeighbourhood = mergeSimilarNeighbourhood
26 } 26 }
27 27
28 public static val FixPointRage = -1 28 public static val FixPointRange = NeighbourhoodOptions.FixPointRange
29 public static val GraphWidthRange = -2 29 public static val GraphWidthRange = NeighbourhoodOptions.GraphWidthRange
30 public static val FullParallels = Integer.MAX_VALUE 30 public static val FullParallels = NeighbourhoodOptions.FullParallels
31 public static val MaxNumbers = Integer.MAX_VALUE 31 public static val MaxNumbers = NeighbourhoodOptions.MaxNumbers
32 32
33 static val FOCUSED_ELEMENT_NAME = "<<THIS>>"
34
33 /** 35 /**
34 * Creates a neighbourhood representation with traces 36 * Creates a neighbourhood representation with traces
35 * @param model The model to be represented. 37 * @param model The model to be represented.
@@ -37,10 +39,15 @@ abstract class PartialInterpretation2NeighbourhoodRepresentation<ModelRepresenta
37 * @param parallels The maximal number of parallel references to be differentiated. 39 * @param parallels The maximal number of parallel references to be differentiated.
38 * @param maxNumber The maximal number of elements in a equivalence class that chan be differentiated. 40 * @param maxNumber The maximal number of elements in a equivalence class that chan be differentiated.
39 */ 41 */
40 def public createRepresentation(PartialInterpretation model, int range, int parallels, int maxNumber) { 42 def createRepresentation(PartialInterpretation model, int range, int parallels, int maxNumber) {
41 return createRepresentation(model,range,parallels,maxNumber,null,null) 43 return createRepresentation(model, range, parallels, maxNumber, null, null)
44 }
45
46 def createRepresentation(PartialInterpretation model, NeighbourhoodOptions options) {
47 createRepresentation(model, options.range, options.parallels, options.maxNumber, options.relevantTypes,
48 options.relevantRelations)
42 } 49 }
43 50
44 /** 51 /**
45 * Creates a neighbourhood representation with traces 52 * Creates a neighbourhood representation with traces
46 * @param model The model to be represented. 53 * @param model The model to be represented.
@@ -48,72 +55,87 @@ abstract class PartialInterpretation2NeighbourhoodRepresentation<ModelRepresenta
48 * @param parallels The maximal number of parallel references to be differentiated. 55 * @param parallels The maximal number of parallel references to be differentiated.
49 * @param maxNumber The maximal number of elements in a equivalence class that chan be differentiated. 56 * @param maxNumber The maximal number of elements in a equivalence class that chan be differentiated.
50 */ 57 */
51 def public createRepresentation( 58 def createRepresentation(PartialInterpretation model, int range, int parallels, int maxNumber,
52 PartialInterpretation model, 59 Set<TypeDeclaration> relevantTypes, Set<RelationDeclaration> relevantRelations) {
53 int range, int parallels, int maxNumber, 60 createRepresentationWithFocus(model, range, parallels, maxNumber, relevantTypes, relevantRelations, null)
54 Set<TypeDeclaration> relevantTypes, Set<RelationDeclaration> relevantRelations) 61 }
55 { 62
56 val Map<DefinedElement, Set<String>> types = new HashMap 63 def createRepresentationWithFocus(PartialInterpretation model, NeighbourhoodOptions options,
57 fillTypes(model,types,relevantTypes) 64 DefinedElement focusedElement) {
58 val Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations = new HashMap; 65 createRepresentationWithFocus(model, options.range, options.parallels, options.maxNumber, options.relevantTypes,
59 val Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations = new HashMap; 66 options.relevantRelations, focusedElement)
60 fillReferences(model,IncomingRelations,OutgoingRelations,relevantRelations) 67 }
61 68
62 val res = doRecursiveNeighbourCalculation(model,types,IncomingRelations,OutgoingRelations,range,parallels,maxNumber); 69 def createRepresentationWithFocus(PartialInterpretation model, int range, int parallels, int maxNumber,
63 70 Set<TypeDeclaration> relevantTypes, Set<RelationDeclaration> relevantRelations, DefinedElement focusedElement) {
71 val initialSize = model.elements.size
72 val Map<DefinedElement, Set<String>> types = Maps.mutable.ofInitialCapacity(initialSize)
73 fillTypes(model, types, relevantTypes)
74 val Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations = Maps.mutable.ofInitialCapacity(initialSize);
75 val Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations = Maps.mutable.ofInitialCapacity(initialSize);
76 fillReferences(model, IncomingRelations, OutgoingRelations, relevantRelations)
77
78 val res = doRecursiveNeighbourCalculation(model, types, IncomingRelations, OutgoingRelations, range, parallels,
79 maxNumber, focusedElement);
80
64 return res; 81 return res;
65 } 82 }
66 83
67 def private isRelevant(TypeDeclaration t, Set<TypeDeclaration> relevantTypes) { 84 def private isRelevant(TypeDeclaration t, Set<TypeDeclaration> relevantTypes) {
68 if(relevantTypes === null) { 85 if (relevantTypes === null) {
69 return true 86 return true
70 } else { 87 } else {
71 return relevantTypes.contains(t) 88 return relevantTypes.contains(t)
72 } 89 }
73 } 90 }
91
74 def private isRelevant(RelationDeclaration r, Set<RelationDeclaration> relevantRelations) { 92 def private isRelevant(RelationDeclaration r, Set<RelationDeclaration> relevantRelations) {
75 if(relevantRelations === null) { 93 if (relevantRelations === null) {
76 return true 94 return true
77 } else { 95 } else {
78 return relevantRelations.contains(r) 96 return relevantRelations.contains(r)
79 } 97 }
80 } 98 }
99
81 /** 100 /**
82 * Gets the largest 101 * Gets the minimal neighbourhood size such that every reachable node appears in the shape of every other at least once.
83 */ 102 */
84 def private getWidth(Map<DefinedElement, Set<String>> types, 103 def private getWidth(Map<DefinedElement, Set<String>> types,
85 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations, 104 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations,
86 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations) 105 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations) {
87 { 106 val elements = types.keySet
88 val elements = types.keySet 107 var Map<DefinedElement, Set<DefinedElement>> reachable = Maps.mutable.ofInitialCapacity(elements.size)
89 val Map<DefinedElement,Set<DefinedElement>> reachable = new HashMap 108 var Map<DefinedElement, Set<DefinedElement>> newReachable = Maps.mutable.ofInitialCapacity(elements.size)
90 for(element : elements) { 109 for (element : elements) {
91 val set = new HashSet 110 val set = Sets.mutable.of
92 set.add(element) 111 set.add(element)
93 reachable.put(element,set) 112 reachable.put(element, Sets.mutable.of)
113 newReachable.put(element, set)
94 } 114 }
95 115
96 var int width = 0 116 var int width = 0
97 var boolean newAdded 117 var boolean newAdded
98 do { 118 do {
119 var tmp = reachable
120 reachable = newReachable
121 newReachable = tmp
99 newAdded = false 122 newAdded = false
100 for(element : elements) { 123 for (element : elements) {
101 val elementNeigbours = element.lookup(reachable) 124 val elementNeigbours = element.lookup(reachable)
102 val size = elementNeigbours.size 125 val newElementNeigbours = element.lookup(newReachable)
103 for(incoming : element.lookup(IncomingRelations)) { 126 newElementNeigbours.addAll(elementNeigbours)
104 elementNeigbours.addAll(incoming.from.lookup(reachable)) 127 for (incoming : element.lookup(IncomingRelations)) {
128 newElementNeigbours.addAll(incoming.from.lookup(reachable))
105 } 129 }
106 for(outgoing : element.lookup(OutgoingRelations)) { 130 for (outgoing : element.lookup(OutgoingRelations)) {
107 elementNeigbours.addAll(outgoing.to.lookup(reachable)) 131 newElementNeigbours.addAll(outgoing.to.lookup(reachable))
108 } 132 }
109 newAdded = newAdded || (elementNeigbours.size > size) 133 newAdded = newAdded || (newElementNeigbours.size > elementNeigbours.size)
110 } 134 }
111 135 width += 1
112 width +=1 136 } while (newAdded)
113 } while(newAdded)
114 return width 137 return width
115 } 138 }
116
117 /** 139 /**
118 * Creates a neighbourhood representation with traces 140 * Creates a neighbourhood representation with traces
119 * @param model The model to be represented. 141 * @param model The model to be represented.
@@ -122,68 +144,71 @@ abstract class PartialInterpretation2NeighbourhoodRepresentation<ModelRepresenta
122 * @param range The range of the neighbourhood. 144 * @param range The range of the neighbourhood.
123 * @param parallels The maximal number of parallel references to be differentiated. 145 * @param parallels The maximal number of parallel references to be differentiated.
124 */ 146 */
125 def private NeighbourhoodWithTraces<ModelRepresentation,NodeRepresentation> doRecursiveNeighbourCalculation( 147 def private NeighbourhoodWithTraces<ModelRepresentation, NodeRepresentation> doRecursiveNeighbourCalculation(
126 PartialInterpretation model, 148 PartialInterpretation model, Map<DefinedElement, Set<String>> types,
127 Map<DefinedElement, Set<String>> types,
128 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations, 149 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations,
129 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations, 150 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations, int range, int parallels,
130 int range, int parallels, int maxNumber) 151 int maxNumber, DefinedElement focusedElement) {
131 { 152 if (range == 0) {
132 if(range == 0){ 153 val r = calculateLocalNodeDescriptors(model, types, maxNumber, focusedElement)
133 val r = calculateLocalNodeDescriptors(model,types,maxNumber) 154 val res = this.createLocalRepresentation(r.value, r.key)
134 val res = this.createLocalRepresentation(r.value,r.key) 155 if (res.modelRepresentation === null) {
135 if(res.modelRepresentation === null) {
136 throw new IllegalArgumentException('''Model representation is null''') 156 throw new IllegalArgumentException('''Model representation is null''')
137 } else if(res.nodeRepresentations === null || res.nodeRepresentations.empty) { 157 } else if (res.nodeRepresentations === null || res.nodeRepresentations.empty) {
138 throw new IllegalArgumentException('''No node representation''') 158 throw new IllegalArgumentException('''No node representation''')
139 } else if(res.previousRepresentation !== null) { 159 } else if (res.previousRepresentation !== null) {
140 throw new IllegalArgumentException('''The previous representation of the first neighbourhood have to be null''') 160 throw new IllegalArgumentException('''The previous representation of the first neighbourhood have to be null''')
141 } else return res 161 } else
142 } else if(range > 0) { 162 return res
143 val previous = doRecursiveNeighbourCalculation(model,types,IncomingRelations,OutgoingRelations,range-1,parallels,maxNumber) 163 } else if (range > 0) {
144 val r = calculateFurtherNodeDescriptors(model,previous,IncomingRelations,OutgoingRelations,parallels,maxNumber) 164 val previous = doRecursiveNeighbourCalculation(model, types, IncomingRelations, OutgoingRelations,
145 //println('''Level «range» finished.''') 165 range - 1, parallels, maxNumber, focusedElement)
146 val res = createFurtherRepresentation(r.key,r.value,previous,deepRepresentation) 166 val r = calculateFurtherNodeDescriptors(model, previous, IncomingRelations, OutgoingRelations, parallels,
147 if(res.modelRepresentation === null) { 167 maxNumber)
168 // println('''Level «range» finished.''')
169 val res = createFurtherRepresentation(r.key, r.value, previous, deepRepresentation)
170 if (res.modelRepresentation === null) {
148 throw new IllegalArgumentException('''Model representation is null''') 171 throw new IllegalArgumentException('''Model representation is null''')
149 } else if(res.nodeRepresentations === null || res.nodeRepresentations.empty) { 172 } else if (res.nodeRepresentations === null || res.nodeRepresentations.empty) {
150 throw new IllegalArgumentException('''No node representation''') 173 throw new IllegalArgumentException('''No node representation''')
151 } else if(res.previousRepresentation === null && deepRepresentation) { 174 } else if (res.previousRepresentation === null && deepRepresentation) {
152 throw new IllegalArgumentException('''Need previous representations''') 175 throw new IllegalArgumentException('''Need previous representations''')
153 } else return res 176 } else
154 } else if (range == FixPointRage) { 177 return res
155 return refineUntilFixpoint(model,types,IncomingRelations,OutgoingRelations,parallels,maxNumber) 178 } else if (range == FixPointRange) {
179 return refineUntilFixpoint(model, types, IncomingRelations, OutgoingRelations, parallels, maxNumber,
180 focusedElement)
156 } else if (range == GraphWidthRange) { 181 } else if (range == GraphWidthRange) {
157 val width = this.getWidth(types,IncomingRelations,OutgoingRelations) 182 val width = this.getWidth(types, IncomingRelations, OutgoingRelations)
158 //println(width) 183 // println(width)
159 return doRecursiveNeighbourCalculation(model,types,IncomingRelations,OutgoingRelations,width,parallels,maxNumber) 184 return doRecursiveNeighbourCalculation(model, types, IncomingRelations, OutgoingRelations, width, parallels,
185 maxNumber, focusedElement)
160 } 186 }
161 } 187 }
162 188
163 def private refineUntilFixpoint( 189 def private refineUntilFixpoint(PartialInterpretation model, Map<DefinedElement, Set<String>> types,
164 PartialInterpretation model,
165 Map<DefinedElement, Set<String>> types,
166 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations, 190 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations,
167 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations, 191 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations, int parallels, int maxNumbers,
168 int parallels, int maxNumbers) 192 DefinedElement focusedElement) {
169 {
170 var lastRange = 0 193 var lastRange = 0
171 val last = calculateLocalNodeDescriptors(model,types,maxNumbers) 194 val last = calculateLocalNodeDescriptors(model, types, maxNumbers, focusedElement)
172 var lastRepresentation = this.createLocalRepresentation(last.value,last.key) 195 var lastRepresentation = this.createLocalRepresentation(last.value, last.key)
173 //println('''Level 0 finished.''') 196 // println('''Level 0 finished.''')
174 var boolean hasRefined 197 var boolean hasRefined
175 do { 198 do {
176 val nextRange = lastRange+1 199 val nextRange = lastRange + 1
177 val next = calculateFurtherNodeDescriptors(model,lastRepresentation,IncomingRelations,OutgoingRelations,parallels,maxNumbers) 200 val next = calculateFurtherNodeDescriptors(model, lastRepresentation, IncomingRelations, OutgoingRelations,
178 val nextRepresentation = createFurtherRepresentation(next.key,next.value,lastRepresentation,deepRepresentation) 201 parallels, maxNumbers)
179 202 val nextRepresentation = createFurtherRepresentation(next.key, next.value, lastRepresentation,
180 val previousNumberOfTypes =lastRepresentation.nodeRepresentations.values.toSet.size 203 deepRepresentation)
181 val nextNumberOfTypes = nextRepresentation.nodeRepresentations.values.toSet.size 204
182 hasRefined = nextNumberOfTypes > previousNumberOfTypes 205 val previousNumberOfTypes = Sets.immutable.withAll(lastRepresentation.nodeRepresentations.values).size
183 206 val nextNumberOfTypes = Sets.immutable.withAll(nextRepresentation.nodeRepresentations.values).size
207 hasRefined = nextNumberOfTypes > previousNumberOfTypes
208
184 lastRange = nextRange 209 lastRange = nextRange
185 lastRepresentation = nextRepresentation 210 lastRepresentation = nextRepresentation
186 211
187// if(hasRefined) { 212// if(hasRefined) {
188// println('''Level «nextRange» is calculated, number of types is refined: «previousNumberOfTypes» -> «nextNumberOfTypes»''') 213// println('''Level «nextRange» is calculated, number of types is refined: «previousNumberOfTypes» -> «nextNumberOfTypes»''')
189// } else { 214// } else {
@@ -192,211 +217,217 @@ abstract class PartialInterpretation2NeighbourhoodRepresentation<ModelRepresenta
192 } while (hasRefined) 217 } while (hasRefined)
193 return lastRepresentation 218 return lastRepresentation
194 } 219 }
195 220
196 def private getElements(PartialInterpretation model) { 221 def private getElements(PartialInterpretation model) {
197 return 222 return model.problem.elements + model.newElements + model.openWorldElements
198 model.problem.elements +
199 model.newElements +
200 model.openWorldElements
201 } 223 }
202 224
203 def private fillTypes(PartialInterpretation model, Map<DefinedElement, Set<String>> node2Type, Set<TypeDeclaration> relevantTypes) { 225 def private fillTypes(PartialInterpretation model, Map<DefinedElement, Set<String>> node2Type,
204 for(element : model.elements) { 226 Set<TypeDeclaration> relevantTypes) {
205 node2Type.put(element, new HashSet) 227 for (element : model.elements) {
228 node2Type.put(element, Sets.mutable.of)
206 } 229 }
207 230
208// for(typeDefinition : model.problem.types.filter(TypeDefinition)) { 231// for(typeDefinition : model.problem.types.filter(TypeDefinition)) {
209// // Dont need 232// // Dont need
210// } 233// }
211 for(typeInterpretation : model.partialtypeinterpratation) { 234 for (typeInterpretation : model.partialtypeinterpratation) {
212 if(typeInterpretation instanceof PartialPrimitiveInterpretation) { 235 if (typeInterpretation instanceof PartialPrimitiveInterpretation) {
213 236 } else if (typeInterpretation instanceof PartialComplexTypeInterpretation) {
214 } else if(typeInterpretation instanceof PartialComplexTypeInterpretation) {
215 val type = typeInterpretation.interpretationOf 237 val type = typeInterpretation.interpretationOf
216 if(type.isRelevant(relevantTypes)) { 238 if (type.isRelevant(relevantTypes)) {
217 for(element : typeInterpretation.elements) { 239 for (element : typeInterpretation.elements) {
218 element.lookup(node2Type).add(type.name) 240 element.lookup(node2Type).add(type.name)
219 } 241 }
220 } 242 }
221 } 243 }
222 } 244 }
223 } 245 }
224 246
225 /** 247 /**
226 * Indexes the references 248 * Indexes the references
227 */ 249 */
228 def private fillReferences(PartialInterpretation model, 250 def private fillReferences(PartialInterpretation model,
229 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations, 251 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations,
230 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations, 252 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations,
231 Set<RelationDeclaration> relevantRelations) 253 Set<RelationDeclaration> relevantRelations) {
232 { 254 for (object : model.elements) {
233 for(object : model.elements) { 255 IncomingRelations.put(object, new ArrayList)
234 IncomingRelations.put(object,new LinkedList) 256 OutgoingRelations.put(object, new ArrayList)
235 OutgoingRelations.put(object,new LinkedList)
236 } 257 }
237 for(relationInterpretation : model.partialrelationinterpretation) { 258 for (relationInterpretation : model.partialrelationinterpretation) {
238 val type = relationInterpretation.interpretationOf 259 val type = relationInterpretation.interpretationOf
239 if(type.isRelevant(relevantRelations)) { 260 if (type.isRelevant(relevantRelations)) {
240 for(link : relationInterpretation.relationlinks) { 261 for (link : relationInterpretation.relationlinks) {
241 if(link instanceof BinaryElementRelationLink) { 262 if (link instanceof BinaryElementRelationLink) {
242 OutgoingRelations.get(link.param1) += new OutgoingRelation(link.param2,type.name) 263 OutgoingRelations.get(link.param1) += new OutgoingRelation(link.param2, type.name)
243 IncomingRelations.get(link.param2) += new IncomingRelation(link.param1,type.name) 264 IncomingRelations.get(link.param2) += new IncomingRelation(link.param1, type.name)
244 } else throw new UnsupportedOperationException 265 } else
266 throw new UnsupportedOperationException
245 } 267 }
246 } 268 }
247 } 269 }
248 } 270 }
249 271
250 /** 272 /**
251 * Creates a local representation of the objects (aka zero range neighbourhood) 273 * Creates a local representation of the objects (aka zero range neighbourhood)
252 */ 274 */
253 def abstract protected NeighbourhoodWithTraces<ModelRepresentation,NodeRepresentation> createLocalRepresentation( 275 def abstract protected NeighbourhoodWithTraces<ModelRepresentation, NodeRepresentation> createLocalRepresentation(
254 Map<DefinedElement, LocalNodeDescriptor> node2Representation, 276 Map<DefinedElement, LocalNodeDescriptor> node2Representation,
255 Map<LocalNodeDescriptor, Integer> representation2Amount 277 Map<LocalNodeDescriptor, Integer> representation2Amount
256 ) 278 )
257 279
258 /** 280 /**
259 * Creates a 281 * Creates a
260 */ 282 */
261 def abstract protected NeighbourhoodWithTraces<ModelRepresentation,NodeRepresentation> createFurtherRepresentation( 283 def abstract protected NeighbourhoodWithTraces<ModelRepresentation, NodeRepresentation> createFurtherRepresentation(
262 Map<FurtherNodeDescriptor<NodeRepresentation>, Integer> nodeDescriptors, 284 Map<FurtherNodeDescriptor<NodeRepresentation>, Integer> nodeDescriptors,
263 Map<DefinedElement, FurtherNodeDescriptor<NodeRepresentation>> node2Representation, 285 Map<DefinedElement, FurtherNodeDescriptor<NodeRepresentation>> node2Representation,
264 NeighbourhoodWithTraces<ModelRepresentation,NodeRepresentation> previous, 286 NeighbourhoodWithTraces<ModelRepresentation, NodeRepresentation> previous,
265 boolean deepRepresentation 287 boolean deepRepresentation
266 ) 288 )
267 289
268 def private addOne(int original, int max) { 290 def private addOne(Integer originalObj, int max) {
291 if (originalObj === null) {
292 return 1
293 }
294 val original = originalObj.intValue
269 if(original == Integer.MAX_VALUE) return Integer.MAX_VALUE 295 if(original == Integer.MAX_VALUE) return Integer.MAX_VALUE
270 if(original +1 > max) return Integer.MAX_VALUE 296 if(original + 1 > max) return Integer.MAX_VALUE else return original + 1
271 else return original+1
272 } 297 }
273 298
274 private def calculateIncomingEdges(Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations, 299 private def calculateIncomingEdges(Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations,
275 DefinedElement object, Map<DefinedElement, ? extends NodeRepresentation> previousNodeRepresentations, int parallel) 300 DefinedElement object, Map<DefinedElement, ? extends NodeRepresentation> previousNodeRepresentations,
276 { 301 int parallel) {
277 val Map<IncomingRelation<NodeRepresentation>, Integer> res = new HashMap 302 val Map<IncomingRelation<NodeRepresentation>, Integer> res = Maps.mutable.of
278 for (incomingConcreteEdge : IncomingRelations.get(object)) { 303 for (incomingConcreteEdge : IncomingRelations.get(object)) {
279 val IncomingRelation<NodeRepresentation> e = new IncomingRelation( 304 val IncomingRelation<NodeRepresentation> e = new IncomingRelation(
280 previousNodeRepresentations.get(incomingConcreteEdge.from), incomingConcreteEdge.type) 305 previousNodeRepresentations.get(incomingConcreteEdge.from), incomingConcreteEdge.type)
281 if (res.containsKey(e)) { 306 res.compute(e, [key, value | addOne(value, parallel)])
282 res.put(e, addOne(res.get(e),parallel))
283 } else {
284 res.put(e, 1)
285 }
286 } 307 }
287 return res 308 return res
288 } 309 }
289 310
290 private def calcuateOutgoingEdges(Map<DefinedElement,List<OutgoingRelation<DefinedElement>>> OutgoingRelations, 311 private def calcuateOutgoingEdges(Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations,
291 DefinedElement object, Map<DefinedElement, ? extends NodeRepresentation> previousNodeRepresentations, int parallel) 312 DefinedElement object, Map<DefinedElement, ? extends NodeRepresentation> previousNodeRepresentations,
292 { 313 int parallel) {
293 val Map<OutgoingRelation<NodeRepresentation>,Integer> res= new HashMap 314 val Map<OutgoingRelation<NodeRepresentation>, Integer> res = Maps.mutable.of
294 for(outgoingConcreteEdge : OutgoingRelations.get(object)) { 315 for (outgoingConcreteEdge : OutgoingRelations.get(object)) {
295 val OutgoingRelation<NodeRepresentation> e = 316 val OutgoingRelation<NodeRepresentation> e = new OutgoingRelation(
296 new OutgoingRelation( 317 previousNodeRepresentations.get(outgoingConcreteEdge.to), outgoingConcreteEdge.type)
297 previousNodeRepresentations.get(outgoingConcreteEdge.to), 318 res.compute(e, [key, value | addOne(value, parallel)])
298 outgoingConcreteEdge.type)
299 if(res.containsKey(e)) {
300 res.put(e,addOne(res.get(e),parallel))
301 } else {
302 res.put(e,1)
303 }
304 } 319 }
305 return res; 320 return res
306 } 321 }
307 322
308 /*def private <KEY,VALUE> void addOrCreate_Set(Map<KEY,Set<VALUE>> map, KEY key, VALUE value) { 323 /*def private <KEY,VALUE> void addOrCreate_Set(Map<KEY,Set<VALUE>> map, KEY key, VALUE value) {
309 var Set<VALUE> s; 324 * var Set<VALUE> s;
310 if(map.containsKey(key)) { 325 * if(map.containsKey(key)) {
311 s = map.get(key); 326 * s = map.get(key);
312 } else { 327 * } else {
313 s = new HashSet 328 * s = new HashSet
314 map.put(key,s) 329 * map.put(key,s)
315 } 330 * }
316 s.add(value) 331 * s.add(value)
317 }*/ 332 }*/
318 333 private def calculateFurtherNodeDescriptors(PartialInterpretation model,
319
320 private def calculateFurtherNodeDescriptors(
321 PartialInterpretation model,
322 NeighbourhoodWithTraces<ModelRepresentation, NodeRepresentation> previous, 334 NeighbourhoodWithTraces<ModelRepresentation, NodeRepresentation> previous,
323 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations, 335 Map<DefinedElement, List<IncomingRelation<DefinedElement>>> IncomingRelations,
324 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations, 336 Map<DefinedElement, List<OutgoingRelation<DefinedElement>>> OutgoingRelations, int parallels, int maxNumber) {
325 int parallels, int maxNumber)
326 {
327 val previousNodeRepresentations = previous.nodeRepresentations 337 val previousNodeRepresentations = previous.nodeRepresentations
328 val node2Representation = new HashMap<DefinedElement,FurtherNodeDescriptor<NodeRepresentation>> 338 val size = previousNodeRepresentations.size
329 val Map<FurtherNodeDescriptor<NodeRepresentation>,Integer> descriptor2Number = 339 val node2Representation = Maps.mutable.<DefinedElement, FurtherNodeDescriptor<NodeRepresentation>>ofInitialCapacity(size)
330 if(this.mergeSimilarNeighbourhood){ new HashMap } else { null } 340 val Map<FurtherNodeDescriptor<NodeRepresentation>, Integer> descriptor2Number = if (this.
331 val Map<FurtherNodeDescriptor<NodeRepresentation>,FurtherNodeDescriptor<NodeRepresentation>> uniqueDescription = 341 mergeSimilarNeighbourhood) {
332 if(this.mergeSimilarNeighbourhood){ new HashMap } else { null } 342 Maps.mutable.ofInitialCapacity(size)
333 343 } else {
334 for(object: model.elements) { 344 null
335 val incomingEdges = this.calculateIncomingEdges(IncomingRelations, object, previousNodeRepresentations,parallels) 345 }
336 val outgoingEdges = this.calcuateOutgoingEdges(OutgoingRelations,object, previousNodeRepresentations,parallels) 346 val Map<FurtherNodeDescriptor<NodeRepresentation>, FurtherNodeDescriptor<NodeRepresentation>> uniqueDescription = if (this.
337 347 mergeSimilarNeighbourhood) {
348 Maps.mutable.ofInitialCapacity(size)
349 } else {
350 null
351 }
352
353 for (object : model.elements) {
354 val incomingEdges = this.calculateIncomingEdges(IncomingRelations, object, previousNodeRepresentations,
355 parallels)
356 val outgoingEdges = this.calcuateOutgoingEdges(OutgoingRelations, object, previousNodeRepresentations,
357 parallels)
358
338 val previousType = previousNodeRepresentations.get(object) 359 val previousType = previousNodeRepresentations.get(object)
339 360
340 if(previousType === null) { 361 if (previousType === null) {
341 println("Error in state coder") 362 println("Error in state coder")
342 } 363 }
343 364
344 val nodeDescriptor = new FurtherNodeDescriptor( 365 val nodeDescriptor = new FurtherNodeDescriptor(previousType, incomingEdges, outgoingEdges)
345 previousType, 366
346 incomingEdges, 367 if (this.mergeSimilarNeighbourhood) {
347 outgoingEdges) 368 if (descriptor2Number.containsKey(nodeDescriptor)) {
348
349 if(this.mergeSimilarNeighbourhood) {
350 if(descriptor2Number.containsKey(nodeDescriptor)) {
351 descriptor2Number.put( 369 descriptor2Number.put(
352 nodeDescriptor, 370 nodeDescriptor,
353 addOne(descriptor2Number.get(nodeDescriptor),maxNumber) 371 addOne(descriptor2Number.get(nodeDescriptor), maxNumber)
354 ) 372 )
355 node2Representation.put(object,uniqueDescription.get(nodeDescriptor)) 373 node2Representation.put(object, uniqueDescription.get(nodeDescriptor))
356 } else { 374 } else {
357 descriptor2Number.put(nodeDescriptor,if(1>maxNumber){Integer.MAX_VALUE}else{1}) 375 descriptor2Number.put(nodeDescriptor, if (1 > maxNumber) {
358 uniqueDescription.put(nodeDescriptor,nodeDescriptor) 376 Integer.MAX_VALUE
359 node2Representation.put(object,nodeDescriptor) 377 } else {
378 1
379 })
380 uniqueDescription.put(nodeDescriptor, nodeDescriptor)
381 node2Representation.put(object, nodeDescriptor)
360 } 382 }
361 } else { 383 } else {
362 node2Representation.put(object,nodeDescriptor) 384 node2Representation.put(object, nodeDescriptor)
363 } 385 }
364 } 386 }
365 387
366 return descriptor2Number -> node2Representation 388 return descriptor2Number -> node2Representation
367 } 389 }
368 390
369 private def calculateLocalNodeDescriptors( 391 private def calculateLocalNodeDescriptors(PartialInterpretation model, Map<DefinedElement, Set<String>> types,
370 PartialInterpretation model, 392 int maxNumber, DefinedElement focusedElement) {
371 Map<DefinedElement, Set<String>> types, 393 val size = types.size
372 int maxNumber) 394 val Map<DefinedElement, LocalNodeDescriptor> node2Representation = Maps.mutable.ofInitialCapacity(size)
373 { 395 val Map<LocalNodeDescriptor, Integer> representation2Amount = if (mergeSimilarNeighbourhood) {
374 val Map<DefinedElement, LocalNodeDescriptor> node2Representation = new HashMap 396 Maps.mutable.ofInitialCapacity(size)
375 val Map<LocalNodeDescriptor, Integer> representation2Amount = 397 } else {
376 if(mergeSimilarNeighbourhood){ new HashMap } else { null } 398 null
377 val Map<LocalNodeDescriptor, LocalNodeDescriptor> uniqueRepresentation = 399 }
378 if(this.mergeSimilarNeighbourhood){ new HashMap } else { null } 400 val Map<LocalNodeDescriptor, LocalNodeDescriptor> uniqueRepresentation = if (this.mergeSimilarNeighbourhood) {
379 401 Maps.mutable.ofInitialCapacity(size)
380 for(element : model.elements) { 402 } else {
381 var newDescriptor = new LocalNodeDescriptor(element.name,element.lookup(types)) 403 null
382 if(this.mergeSimilarNeighbourhood){ 404 }
383 if(uniqueRepresentation.containsKey(newDescriptor)) { 405
406 for (element : model.elements) {
407 val name = if(element == focusedElement) FOCUSED_ELEMENT_NAME else element.name
408 var newDescriptor = new LocalNodeDescriptor(name, element.lookup(types))
409 if (this.mergeSimilarNeighbourhood) {
410 if (uniqueRepresentation.containsKey(newDescriptor)) {
384 newDescriptor = newDescriptor.lookup(uniqueRepresentation) 411 newDescriptor = newDescriptor.lookup(uniqueRepresentation)
385 node2Representation.put(element,newDescriptor) 412 node2Representation.put(element, newDescriptor)
386 representation2Amount.put( 413 representation2Amount.put(
387 newDescriptor, 414 newDescriptor,
388 addOne(newDescriptor.lookup(representation2Amount),maxNumber) 415 addOne(newDescriptor.lookup(representation2Amount), maxNumber)
389 ) 416 )
390 } else { 417 } else {
391 uniqueRepresentation.put(newDescriptor,newDescriptor) 418 uniqueRepresentation.put(newDescriptor, newDescriptor)
392 node2Representation.put(element,newDescriptor) 419 node2Representation.put(element, newDescriptor)
393 representation2Amount.put(newDescriptor, if(1>maxNumber){Integer.MAX_VALUE}else{1}) 420 representation2Amount.put(newDescriptor, if (1 > maxNumber) {
421 Integer.MAX_VALUE
422 } else {
423 1
424 })
394 } 425 }
395 } else { 426 } else {
396 node2Representation.put(element,newDescriptor) 427 node2Representation.put(element, newDescriptor)
397 } 428 }
398 } 429 }
399 430
400 return representation2Amount -> node2Representation 431 return representation2Amount -> node2Representation
401 } 432 }
402} \ No newline at end of file 433}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2PairwiseNeighbourhoodRepresentation.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2PairwiseNeighbourhoodRepresentation.xtend
new file mode 100644
index 00000000..c10457b0
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/neighbourhood/PartialInterpretation2PairwiseNeighbourhoodRepresentation.xtend
@@ -0,0 +1,68 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood
2
3import com.google.common.collect.Maps
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
6import java.util.HashMap
7import java.util.Map
8import org.eclipse.xtend.lib.annotations.Data
9import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
10
11@Data
12class PairwiseNeighbourhoodRepresentation<BasicNodeRepresentation> {
13 val Map<?, Integer> modelRepresentation
14 val Map<DefinedElement, BasicNodeRepresentation> basicNodeRepresentations
15 val Map<DefinedElement, ? extends Map<DefinedElement, ? extends BasicNodeRepresentation>> pairwiseNodeRepresentations
16
17 def getBasicRepresentation(DefinedElement a) {
18 basicNodeRepresentations.get(a)
19 }
20
21 def getPairwiseRepresentation(DefinedElement a, DefinedElement b) {
22 pairwiseNodeRepresentations.get(a).get(b)
23 }
24}
25
26@FinalFieldsConstructor
27class PartialInterpretation2PairwiseNeighbourhoodRepresentation<BasicNodeRepresentation> {
28 val PartialInterpretation2NeighbourhoodRepresentation<? extends Map<? extends BasicNodeRepresentation, Integer>, BasicNodeRepresentation> basicNeighbourhoodRepresenter
29
30 def createRepresentation(PartialInterpretation model, NeighbourhoodOptions options) {
31 val basicRepresentation = basicNeighbourhoodRepresenter.createRepresentation(model, options)
32 val basicModelRepresentation = basicRepresentation.modelRepresentation
33 val basicNodeRepresentations = basicRepresentation.nodeRepresentations
34 val pairwiseNodeRepresentations = Maps.newHashMapWithExpectedSize(basicNodeRepresentations.size)
35 val modelRepresentation = new HashMap<Object, Integer>
36 for (nodeWithBasicRepresentation : basicNodeRepresentations.entrySet) {
37 val node = nodeWithBasicRepresentation.key
38 val basicNodeRepresentation = nodeWithBasicRepresentation.value
39 val count = basicModelRepresentation.get(basicNodeRepresentation)
40 if (count == 1) {
41 pairwiseNodeRepresentations.put(node, basicNodeRepresentations)
42 modelRepresentation.put(basicNodeRepresentation, count)
43 } else {
44 val neighbourhoodRepresentation = basicNeighbourhoodRepresenter.
45 createRepresentationWithFocus(model, options, node)
46 pairwiseNodeRepresentations.put(node, neighbourhoodRepresentation.nodeRepresentations)
47 modelRepresentation.compute(neighbourhoodRepresentation.modelRepresentation) [ key, value |
48 if (value === null) {
49 if (1 > options.maxNumber) {
50 Integer.MAX_VALUE
51 } else {
52 1
53 }
54 } else {
55 addOne(value, options.maxNumber)
56 }
57 ]
58 }
59 }
60 new PairwiseNeighbourhoodRepresentation(modelRepresentation, basicNodeRepresentations,
61 pairwiseNodeRepresentations)
62 }
63
64 def private addOne(int original, int max) {
65 if(original == Integer.MAX_VALUE) return Integer.MAX_VALUE
66 if(original + 1 > max) return Integer.MAX_VALUE else return original + 1
67 }
68}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/AbstractNeighborhoodBasedStateCoderFactory.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/AbstractNeighborhoodBasedStateCoderFactory.xtend
new file mode 100644
index 00000000..089880b1
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/AbstractNeighborhoodBasedStateCoderFactory.xtend
@@ -0,0 +1,137 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder
2
3import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodOptions
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage
10import java.util.LinkedList
11import java.util.List
12import org.eclipse.emf.common.notify.Notifier
13import org.eclipse.emf.ecore.EClass
14import org.eclipse.emf.ecore.EObject
15import org.eclipse.emf.ecore.EStructuralFeature
16import org.eclipse.viatra.dse.statecode.IStateCoder
17import org.eclipse.viatra.dse.statecode.IStateCoderFactory
18import org.eclipse.viatra.query.runtime.api.IPatternMatch
19import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
20import org.eclipse.viatra.query.runtime.base.api.FeatureListener
21import org.eclipse.viatra.query.runtime.base.api.IndexingLevel
22import org.eclipse.viatra.query.runtime.base.api.InstanceListener
23import org.eclipse.viatra.query.runtime.emf.EMFBaseIndexWrapper
24import org.eclipse.viatra.query.runtime.emf.EMFScope
25import org.eclipse.xtend.lib.annotations.Accessors
26
27abstract class AbstractNeighbourhoodBasedStateCoderFactory implements IStateCoderFactory {
28 val List<AbstractNeighbourhoodBasedPartialInterpretationStateCoder> statecoders = new LinkedList
29
30 val NeighbourhoodOptions options
31
32 protected new() {
33 this(NeighbourhoodOptions.DEFAULT)
34 }
35
36 protected new(NeighbourhoodOptions options) {
37 this.options = options
38 }
39
40 synchronized override createStateCoder() {
41 val res = doCreateStateCoder(options)
42 statecoders += res
43 return res
44 }
45
46 protected def AbstractNeighbourhoodBasedPartialInterpretationStateCoder doCreateStateCoder(
47 NeighbourhoodOptions options)
48
49 def getSumStatecoderRuntime() {
50 statecoders.map[statecoderRuntime].reduce[p1, p2|p1 + p2]
51 }
52}
53
54abstract class AbstractNeighbourhoodBasedPartialInterpretationStateCoder implements IStateCoder {
55 val NeighbourhoodOptions options
56
57 var PartialInterpretation target
58
59 protected new(NeighbourhoodOptions options) {
60 this.options = options
61 }
62
63 @Accessors(PUBLIC_GETTER) var long statecoderRuntime = 0
64
65 synchronized private def refreshStateCodes() {
66 if (refreshNeeded) {
67 val startTime = System.nanoTime
68 doRefreshStateCodes(target, options)
69 statecoderRuntime += (System.nanoTime - startTime)
70 }
71 }
72
73 protected def boolean isRefreshNeeded()
74
75 protected def void doRefreshStateCodes(PartialInterpretation target, NeighbourhoodOptions options)
76
77 synchronized override createActivationCode(IPatternMatch match) {
78 refreshStateCodes
79 val startTime = System.nanoTime
80 val code = doCreateActivationCode(match)
81 statecoderRuntime += (System.nanoTime - startTime)
82 code
83 }
84
85 protected def Object doCreateActivationCode(IPatternMatch match)
86
87 synchronized override createStateCode() {
88 refreshStateCodes
89 doCreateStateCode
90 }
91
92 protected def Object doCreateStateCode()
93
94 override init(Notifier notifier) {
95 this.target = notifier as PartialInterpretation
96 val queryEngine = ViatraQueryEngine.on(new EMFScope(notifier))
97 val baseIndex = queryEngine.getBaseIndex() as EMFBaseIndexWrapper
98 val navigationHelper = baseIndex.getNavigationHelper();
99
100 val classes = PartialinterpretationPackage.eINSTANCE.EClassifiers.filter(EClass).toSet
101 val features = classes.map[it.EAllStructuralFeatures].flatten.toSet
102 navigationHelper.registerObservedTypes(classes, null, features, IndexingLevel.FULL);
103
104 navigationHelper.addFeatureListener(features, new FeatureListener() {
105 override void featureInserted(EObject host, EStructuralFeature feature, Object value) { invalidate }
106
107 override void featureDeleted(EObject host, EStructuralFeature feature, Object value) { invalidate }
108 })
109 navigationHelper.addInstanceListener(classes, new InstanceListener() {
110 override void instanceInserted(EClass clazz, EObject instance) { invalidate }
111
112 override void instanceDeleted(EClass clazz, EObject instance) { invalidate }
113 })
114 }
115
116 synchronized def invalidate() {
117 doInvalidate
118 }
119
120 protected def void doInvalidate()
121
122 def protected getFallbackCode(Object o) {
123 switch (o) {
124 PartialInterpretation,
125 LogicProblem:
126 null
127 PartialRelationInterpretation:
128 o.interpretationOf.name
129 PartialPrimitiveInterpretation:
130 o.class.simpleName.hashCode
131 PartialComplexTypeInterpretation:
132 o.interpretationOf.name.hashCode
133 default:
134 throw new UnsupportedOperationException('''Unsupported type: «o.class.simpleName»''')
135 }
136 }
137}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/IdentifierBasedStateCoderFactory.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/IdentifierBasedStateCoderFactory.xtend
index f55a501a..c7b8ee37 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/IdentifierBasedStateCoderFactory.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/IdentifierBasedStateCoderFactory.xtend
@@ -62,13 +62,13 @@ class IdentifierBasedStateCode {
62 int numberOfNewElement 62 int numberOfNewElement
63 SortedSet<RelationStatecoder> relationStatecoders 63 SortedSet<RelationStatecoder> relationStatecoders
64 64
65 private static val comparator = new Comparator<RelationStatecoder>() { 65 static val comparator = new Comparator<RelationStatecoder>() {
66 override compare(RelationStatecoder o1, RelationStatecoder o2) { 66 override compare(RelationStatecoder o1, RelationStatecoder o2) {
67 o1.relationName.compareTo(o2.relationName) 67 o1.relationName.compareTo(o2.relationName)
68 } 68 }
69 } 69 }
70 70
71 public new(int numberOfNewElements) { 71 new(int numberOfNewElements) {
72 this.numberOfNewElement = numberOfNewElements 72 this.numberOfNewElement = numberOfNewElements
73 this.relationStatecoders = new TreeSet(comparator) 73 this.relationStatecoders = new TreeSet(comparator)
74 } 74 }
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/NeighbourhoodBasedStateCoderFactory.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/NeighbourhoodBasedStateCoderFactory.xtend
index a86bcd1f..04c49506 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/NeighbourhoodBasedStateCoderFactory.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/NeighbourhoodBasedStateCoderFactory.xtend
@@ -1,223 +1,109 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder 1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder
2 2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor 3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodOptions
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2Hash
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice 6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2NeighbourhoodRepresentation
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage
7import java.util.ArrayList 9import java.util.ArrayList
8import java.util.LinkedList
9import java.util.List
10import java.util.Map 10import java.util.Map
11import org.eclipse.emf.common.notify.Notifier
12import org.eclipse.emf.ecore.EClass
13import org.eclipse.emf.ecore.EObject
14import org.eclipse.emf.ecore.EStructuralFeature
15import org.eclipse.viatra.dse.statecode.IStateCoder
16import org.eclipse.viatra.dse.statecode.IStateCoderFactory
17import org.eclipse.viatra.query.runtime.api.IPatternMatch 11import org.eclipse.viatra.query.runtime.api.IPatternMatch
18import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine 12import org.eclipse.viatra.query.runtime.api.IQuerySpecification
19import org.eclipse.viatra.query.runtime.base.api.FeatureListener
20import org.eclipse.viatra.query.runtime.base.api.IndexingLevel
21import org.eclipse.viatra.query.runtime.base.api.InstanceListener
22import org.eclipse.viatra.query.runtime.emf.EMFBaseIndexWrapper
23import org.eclipse.viatra.query.runtime.emf.EMFScope
24import org.eclipse.xtend.lib.annotations.Accessors
25import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement
26import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
27import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation
28import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation
29import java.util.Set
30import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration
31import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
32import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2NeighbourhoodRepresentation
33import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
34import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation
35 13
36class NeighbourhoodBasedStateCoderFactory implements IStateCoderFactory { 14class NeighbourhoodBasedStateCoderFactory extends AbstractNeighbourhoodBasedStateCoderFactory {
37 val List<NeighbourhoodBasedPartialInterpretationStateCoder> statecoders = new LinkedList 15 new() {
38
39 val int range
40 val int parallels
41 val int maxNumber
42 val Set<TypeDeclaration> relevantTypes
43 val Set<RelationDeclaration> relevantRelations
44
45 public new() {
46 this.range = PartialInterpretation2NeighbourhoodRepresentation::GraphWidthRange
47 this.parallels = PartialInterpretation2NeighbourhoodRepresentation::FullParallels
48 this.maxNumber = PartialInterpretation2NeighbourhoodRepresentation::MaxNumbers
49 this.relevantTypes = null
50 this.relevantRelations = null
51 } 16 }
52 17
53 public new(int range, int parallels, int maxNumber, Set<TypeDeclaration> relevantTypes, Set<RelationDeclaration> relevantRelations) { 18 new(NeighbourhoodOptions options) {
54 this.range = range 19 super(options)
55 this.parallels = parallels 20 }
56 this.maxNumber = maxNumber 21
57 this.relevantTypes = relevantTypes 22 override protected doCreateStateCoder(NeighbourhoodOptions options) {
58 this.relevantRelations = relevantRelations 23 new NeighbourhoodBasedPartialInterpretationStateCoder(new PartialInterpretation2ImmutableTypeLattice, options)
59 } 24 }
60
61 synchronized override createStateCoder() {
62 val res = new NeighbourhoodBasedPartialInterpretationStateCoder(statecoders.size,
63 range,parallels,maxNumber,relevantTypes,relevantRelations)
64 statecoders += res
65 return res
66 }
67 def getSumStatecoderRuntime() {
68 statecoders.map[statecoderRuntime].reduce[p1, p2|p1+p2]
69 }
70} 25}
71 26
72class NeighbourhoodBasedPartialInterpretationStateCoder implements IStateCoder{ 27class NeighbourhoodBasedHashStateCoderFactory extends AbstractNeighbourhoodBasedStateCoderFactory {
73 val int id; 28 new() {
74 val int range 29 }
75 val int parallels 30
76 val int maxNumber 31 new(NeighbourhoodOptions options) {
77 val Set<TypeDeclaration> relevantTypes 32 super(options)
78 val Set<RelationDeclaration> relevantRelations 33 }
79 34
80 val calculator = 35 override protected doCreateStateCoder(NeighbourhoodOptions options) {
81 new PartialInterpretation2ImmutableTypeLattice 36 new NeighbourhoodBasedPartialInterpretationStateCoder(new PartialInterpretation2Hash, options)
82 var PartialInterpretation target 37 }
83 38}
84 private var Map<DefinedElement, ? extends AbstractNodeDescriptor> nodeRepresentations = null 39
85 private var Map<? extends AbstractNodeDescriptor, Integer> modelRepresentation = null 40class NeighbourhoodBasedPartialInterpretationStateCoder<ModelRep, NodeRep> extends AbstractNeighbourhoodBasedPartialInterpretationStateCoder {
86 41 val PartialInterpretation2NeighbourhoodRepresentation<ModelRep, NodeRep> calculator
87 /*public new(int id) { 42 val Map<IQuerySpecification<?>, String> fullyQualifiedNames = newHashMap
88 this.id = id 43 var Map<DefinedElement, ? extends NodeRep> nodeRepresentations = null
89 this.range = PartialInterpretation2NeighbourhoodRepresentation::FixPointRage 44 var ModelRep modelRepresentation = null
90 this.parallels = PartialInterpretation2NeighbourhoodRepresentation::FullParallels 45
91 this.maxNumber = maxNumber = PartialInterpretation2NeighbourhoodRepresentation::MaxNumbers 46 new(PartialInterpretation2NeighbourhoodRepresentation<ModelRep, NodeRep> calculator, NeighbourhoodOptions options) {
92 this.relevantTypes = relevantTypes 47 super(options)
93 this.relevantRelations = relevantRelations 48 this.calculator = calculator
94 }*/ 49 }
50
51 override protected isRefreshNeeded() {
52 nodeRepresentations === null || modelRepresentation === null
53 }
54
55 override doRefreshStateCodes(PartialInterpretation target, NeighbourhoodOptions options) {
56 val code = calculator.createRepresentation(target, options)
57 modelRepresentation = code.modelRepresentation
58 nodeRepresentations = code.nodeRepresentations
59 }
95 60
96 public new(int id, int range, int parallels, int maxNumber, Set<TypeDeclaration> relevantTypes, Set<RelationDeclaration> relevantRelations) { 61 private def getFullyQualifiedNameCached(IQuerySpecification<?> specification) {
97 this.id = id 62 fullyQualifiedNames.computeIfAbsent(specification, [fullyQualifiedName])
98 this.range = range
99 this.parallels = parallels
100 this.maxNumber = maxNumber
101 this.relevantTypes = relevantTypes
102 this.relevantRelations = relevantRelations
103 } 63 }
104 64
105 @Accessors(PUBLIC_GETTER) var long statecoderRuntime = 0 65 override doCreateActivationCode(IPatternMatch match) {
106 66 val size = match.specification.parameters.size
107// val range = -1 67 var int hash = 0
108// val par = Integer.MAX_VALUE 68 val prime = 31
109 //val deeprepresentation = false 69
110 70 for (var int index = 0; index < size; index++) {
111 ///////// 71 val matchArgument = match.get(index)
112 // Caching version 72 val code = getCode(matchArgument)
113 ///////// 73 val codeNumber = if (code === null) {
114 synchronized private def refreshStateCodes() { 74 0
115 if(this.nodeRepresentations === null || this.modelRepresentation === null) {
116 val startTime = System.nanoTime
117 //relevantObjects.forEach[println(it)]
118 val code = calculator.createRepresentation(target,range,parallels,maxNumber,relevantTypes,relevantRelations)
119 this.modelRepresentation = code.modelRepresentation
120 this.nodeRepresentations = code.nodeRepresentations
121 statecoderRuntime += (System.nanoTime - startTime)
122 }
123 }
124 synchronized override createActivationCode(IPatternMatch match) {
125 refreshStateCodes
126
127 val startTime = System.nanoTime
128 val size = match.specification.parameters.size
129 val res = new ArrayList(size)
130 var int index = 0
131 var int equivalenceHash = 0
132 val prime = 31
133
134 while(index < size) {
135 res.add(getCode(match.get(index)))
136 index++
137 for(var i = 0; i<index; i++) {
138 val number = if(match.get(index) === match.get(i)){1}else{0}
139 equivalenceHash = prime * equivalenceHash + number
140 }
141 }
142
143 statecoderRuntime += (System.nanoTime - startTime)
144 return match.specification.fullyQualifiedName->(res->equivalenceHash).hashCode
145 }
146
147
148 def private getCode(Object o) {
149 if(o instanceof DefinedElement) {
150 this.nodeRepresentations.get(o)
151 } else if(o instanceof PartialInterpretation || o instanceof LogicProblem) {
152 return null
153 } else if(o instanceof PartialRelationInterpretation) {
154 return o.interpretationOf.name
155 } else if(o instanceof PartialTypeInterpratation) {
156 if(o instanceof PartialPrimitiveInterpretation) {
157 o.class.simpleName.hashCode
158 } else if (o instanceof PartialComplexTypeInterpretation){
159 return o.interpretationOf.name.hashCode
160 } else { 75 } else {
161 throw new UnsupportedOperationException('''Unsupported type: «o.class.simpleName»''') 76 code.hashCode
77 }
78 hash = prime * hash + codeNumber
79 for (var i = 0; i < index; i++) {
80 val number = if (matchArgument === match.get(i)) {
81 1
82 } else {
83 0
84 }
85 hash = prime * hash + number
162 } 86 }
163 } else {
164 throw new UnsupportedOperationException('''Unsupported type: «o.class.simpleName»''')
165 } 87 }
166 } 88
167 89 match.specification.fullyQualifiedNameCached -> hash
168 synchronized override createStateCode() { 90 }
169 refreshStateCodes 91
170 return this.modelRepresentation.hashCode 92 def private getCode(Object o) {
171 } 93 switch (o) {
172 ///////// 94 DefinedElement:
173 // Caching version 95 nodeRepresentations.get(o)
174 ///////// 96 default:
175 97 getFallbackCode(o)
176 ///////// 98 }
177 // Recalculating version 99 }
178 ///////// 100
179// synchronized override createActivationCode(IPatternMatch match) { 101 override doCreateStateCode() {
180// val nodes = calculator.createRepresentation(getRelevantObjects().toList,range,par).nodeRepresentations 102 modelRepresentation.hashCode
181// val res = match.toArray.map[objectInMatch | 103 }
182// nodes.get(objectInMatch) 104
183// ] 105 override doInvalidate() {
184// return res 106 nodeRepresentations = null
185// } 107 modelRepresentation = null
186//
187// override createStateCode() {
188// return this.calculator.createRepresentation(getRelevantObjects().toList,range,par).modelRepresentation
189// }
190 /////////
191 // Recalculating version
192 /////////
193
194 override init(Notifier notifier) {
195 this.target = notifier as PartialInterpretation
196 val queryEngine = ViatraQueryEngine.on(new EMFScope(notifier))
197 val baseIndex = queryEngine.getBaseIndex() as EMFBaseIndexWrapper
198 val navigationHelper = baseIndex.getNavigationHelper();
199
200 val classes = PartialinterpretationPackage.eINSTANCE.EClassifiers.filter(EClass).toSet
201 val features = classes.map[it.EAllStructuralFeatures].flatten.toSet
202 navigationHelper.registerObservedTypes(
203 classes,
204 null,
205 features,
206 IndexingLevel.FULL);
207
208
209 navigationHelper.addFeatureListener(features, new FeatureListener() {
210 override public void featureInserted(EObject host, EStructuralFeature feature, Object value) { invalidate }
211 override public void featureDeleted(EObject host, EStructuralFeature feature, Object value) { invalidate }
212 });
213 navigationHelper.addInstanceListener(classes, new InstanceListener() {
214 override public void instanceInserted(EClass clazz, EObject instance) { invalidate }
215 override public void instanceDeleted(EClass clazz, EObject instance) { invalidate }
216 });
217 }
218
219 synchronized def public invalidate() {
220 this.nodeRepresentations = null
221 this.modelRepresentation = null
222 } 108 }
223} 109}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/PairwiseNeighbourhoodBasedStateCoderFactory.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/PairwiseNeighbourhoodBasedStateCoderFactory.xtend
new file mode 100644
index 00000000..84e798f2
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/PairwiseNeighbourhoodBasedStateCoderFactory.xtend
@@ -0,0 +1,75 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder
2
3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodOptions
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PairwiseNeighbourhoodRepresentation
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2PairwiseNeighbourhoodRepresentation
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
10import java.util.ArrayList
11import org.eclipse.viatra.query.runtime.api.IPatternMatch
12
13class PairwiseNeighbourhoodBasedStateCoderFactory extends AbstractNeighbourhoodBasedStateCoderFactory {
14 new() {
15 }
16
17 new(NeighbourhoodOptions options) {
18 super(options)
19 }
20
21 override protected doCreateStateCoder(NeighbourhoodOptions options) {
22 new PairwiseNeighbourhoodBasedPartialInterpretationStateCoder(options)
23 }
24}
25
26class PairwiseNeighbourhoodBasedPartialInterpretationStateCoder extends AbstractNeighbourhoodBasedPartialInterpretationStateCoder {
27 val calculator = new PartialInterpretation2PairwiseNeighbourhoodRepresentation(
28 new PartialInterpretation2ImmutableTypeLattice)
29 var PairwiseNeighbourhoodRepresentation<? extends AbstractNodeDescriptor> representation
30
31 new(NeighbourhoodOptions options) {
32 super(options)
33 }
34
35 override protected isRefreshNeeded() {
36 representation === null
37 }
38
39 override protected doRefreshStateCodes(PartialInterpretation target, NeighbourhoodOptions options) {
40 representation = calculator.createRepresentation(target, options)
41 }
42
43 override protected doCreateActivationCode(IPatternMatch match) {
44 val size = match.specification.parameters.size
45 val res = new ArrayList(size * size)
46 for (var int i = 0; i < size; i++) {
47 val a = match.get(i)
48 for (var int j = 0; j < size; j++) {
49 val b = match.get(j)
50 res.add(getPairwiseRepresentation(a, b))
51 }
52 }
53 match.specification.fullyQualifiedName -> res.hashCode
54 }
55
56 private def getPairwiseRepresentation(Object a, Object b) {
57 if (b instanceof DefinedElement) {
58 if (a instanceof DefinedElement) {
59 representation.getPairwiseRepresentation(a, b)
60 } else {
61 representation.getBasicRepresentation(b)
62 }
63 } else {
64 getFallbackCode(b)
65 }
66 }
67
68 override protected doCreateStateCode() {
69 representation.modelRepresentation.hashCode
70 }
71
72 override protected doInvalidate() {
73 representation = null
74 }
75}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/visualisation/PartialInterpretation2Gml.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/visualisation/PartialInterpretation2Gml.xtend
index 2b42a8b1..bdf402f3 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/visualisation/PartialInterpretation2Gml.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/visualisation/PartialInterpretation2Gml.xtend
@@ -5,9 +5,13 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type 5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDefinition 6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDefinition
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink 7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BooleanElement
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.IntegerElement
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation 10import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 11import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
10import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation 12import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation
13import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.RealElement
14import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.StringElement
11import java.util.HashMap 15import java.util.HashMap
12import java.util.Map 16import java.util.Map
13import java.util.Set 17import java.util.Set
@@ -106,10 +110,38 @@ class PartialInterpretation2Gml {
106 ''' 110 '''
107 } 111 }
108 112
109 def protected transormTitle(DefinedElement object) { 113 def protected dispatch transormTitle(DefinedElement object) {
110 if(object.name!= null)object.name 114 if(object.name !== null) object.name.replace("\"", "")
111 else "null" 115 else "null"
112 } 116 }
117 def protected dispatch transormTitle(BooleanElement object) {
118 if(object.valueSet) {
119 object.value.toString
120 } else {
121 "?"
122 }
123 }
124 def protected dispatch transormTitle(IntegerElement object) {
125 if(object.valueSet) {
126 object.value.toString
127 } else {
128 "?"
129 }
130 }
131 def protected dispatch transormTitle(RealElement object) {
132 if(object.valueSet) {
133 object.value.toString
134 } else {
135 "?"
136 }
137 }
138 def protected dispatch transormTitle(StringElement object) {
139 if(object.valueSet) {
140 object.value.toString
141 } else {
142 "?"
143 }
144 }
113 145
114 def protected transformLink( 146 def protected transformLink(
115 PartialRelationInterpretation reference, 147 PartialRelationInterpretation reference,
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/META-INF/MANIFEST.MF b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/META-INF/MANIFEST.MF
index 7077ae34..185dac40 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/META-INF/MANIFEST.MF
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/META-INF/MANIFEST.MF
@@ -3,7 +3,9 @@ Bundle-ManifestVersion: 2
3Bundle-Name: Reasoner 3Bundle-Name: Reasoner
4Bundle-SymbolicName: hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner 4Bundle-SymbolicName: hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner
5Bundle-Version: 1.0.0.qualifier 5Bundle-Version: 1.0.0.qualifier
6Export-Package: hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner 6Export-Package: hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner,
7 hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse,
8 hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
7Require-Bundle: hu.bme.mit.inf.dslreasoner.ecore2logic;bundle-version="1.0.0", 9Require-Bundle: hu.bme.mit.inf.dslreasoner.ecore2logic;bundle-version="1.0.0",
8 hu.bme.mit.inf.dslreasoner.logic.model;bundle-version="1.0.0", 10 hu.bme.mit.inf.dslreasoner.logic.model;bundle-version="1.0.0",
9 hu.bme.mit.inf.dslreasoner.viatra2logic;bundle-version="1.0.0", 11 hu.bme.mit.inf.dslreasoner.viatra2logic;bundle-version="1.0.0",
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodBasedGlobalConstraint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodBasedGlobalConstraint.xtend
index 28cf986d..691e0645 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodBasedGlobalConstraint.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodBasedGlobalConstraint.xtend
@@ -1,11 +1,10 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner
2 2
3import org.eclipse.viatra.dse.objectives.IGlobalConstraint 3import org.eclipse.viatra.dse.objectives.IGlobalConstraint
4import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod 4
5 5abstract class ModelGenerationMethodBasedGlobalConstraint implements IGlobalConstraint {
6abstract class ModelGenerationMethodBasedGlobalConstraint implements IGlobalConstraint { 6 val protected ModelGenerationMethod method
7 val protected ModelGenerationMethod method 7 new(ModelGenerationMethod method) {
8 new(ModelGenerationMethod method) { 8 this.method = method
9 this.method = method 9 }
10 } 10}
11} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodProvider.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodProvider.xtend
new file mode 100644
index 00000000..25137eba
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ModelGenerationMethodProvider.xtend
@@ -0,0 +1,201 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner
2
3import com.google.common.collect.ImmutableMap
4import com.google.common.collect.ImmutableSet
5import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel
6import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
7import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.TransfomedViatraQuery
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics
9import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.CachingSimplePolyhedronScopePropagatorStrategy
10import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.CbcPolyhedronSolver
11import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeConstraintHint
12import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.MultiplicityGoalConstraintCalculator
13import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedronExtensionOperator
14import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedronScopePropagator
15import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.RelationConstraintCalculator
16import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagator
17import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy
18import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.TypeHierarchyScopePropagator
19import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.Z3PolyhedronSolver
20import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns
21import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.ModalPatternQueries
22import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.PatternProvider
23import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules.GoalConstraintProvider
24import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules.RefinementRuleProvider
25import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
26import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityChecker
27import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ViatraReasonerSolutionSaver
28import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ThreeValuedCostObjectiveProvider
29import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace
30import java.util.Collection
31import java.util.List
32import java.util.Map
33import java.util.Set
34import org.eclipse.viatra.dse.objectives.IObjective
35import org.eclipse.viatra.query.runtime.api.GenericQueryGroup
36import org.eclipse.viatra.query.runtime.api.IPatternMatch
37import org.eclipse.viatra.query.runtime.api.IQuerySpecification
38import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
39import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
40import org.eclipse.viatra.query.runtime.emf.EMFScope
41import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint
42import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
43import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule
44import org.eclipse.xtend.lib.annotations.Data
45import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ExtendedPolyhedronScopePropagatorStrategy
46
47@Data class ModelGenerationMethod {
48 ModelGenerationStatistics statistics
49
50 Collection<? extends BatchTransformationRule<?, ?>> objectRefinementRules
51 Collection<? extends BatchTransformationRule<?, ?>> relationRefinementRules
52
53 List<MultiplicityGoalConstraintCalculator> unfinishedMultiplicities
54
55 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWF
56
57 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidWF
58
59 Map<PConstraint, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> mustUnitPropagationPreconditions
60 Map<PConstraint, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> currentUnitPropagationPreconditions
61
62 Map<String, ModalPatternQueries> modalRelationQueries
63
64 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> allPatterns
65
66 Collection<IObjective> costObjectives
67 boolean optimizationProblem
68 ViatraReasonerSolutionSaver solutionSaver
69}
70
71class ModelGenerationMethodProvider {
72 val PatternProvider patternProvider = new PatternProvider
73 val RefinementRuleProvider refinementRuleProvider = new RefinementRuleProvider
74 val GoalConstraintProvider goalConstraintProvider = new GoalConstraintProvider
75 val relationConstraintCalculator = new RelationConstraintCalculator
76
77 def ModelGenerationMethod createModelGenerationMethod(
78 LogicProblem logicProblem,
79 PartialInterpretation emptySolution,
80 ReasonerWorkspace workspace,
81 ViatraReasonerConfiguration config
82 ) {
83 val statistics = new ModelGenerationStatistics
84 val debugLevel = config.documentationLevel
85 val writeFiles = (debugLevel === DocumentationLevel.NORMAL || debugLevel === DocumentationLevel.FULL)
86
87 val Set<PQuery> existingQueries = logicProblem.relations.map[annotations].flatten.filter(TransfomedViatraQuery).
88 map[it.patternPQuery as PQuery].toSet
89
90 val relationConstraints = relationConstraintCalculator.calculateRelationConstraints(logicProblem)
91 val queries = patternProvider.generateQueries(logicProblem, emptySolution, statistics, existingQueries,
92 workspace, config.typeInferenceMethod, config.scopePropagatorStrategy, relationConstraints, config.hints,
93 config.unitPropagationPatternGenerators, writeFiles)
94
95 val unfinishedMultiplicities = goalConstraintProvider.getUnfinishedMultiplicityQueries(logicProblem, queries,
96 config.calculateObjectCreationCosts)
97 val unfinishedWF = queries.getUnfinishedWFQueries.values
98 val modalRelationQueriesBuilder = ImmutableMap.builder
99 for (entry : queries.modalRelationQueries.entrySet) {
100 val annotation = entry.key.annotations.filter(TransfomedViatraQuery).head
101 if (annotation !== null) {
102 modalRelationQueriesBuilder.put(annotation.patternFullyQualifiedName, entry.value)
103 }
104 }
105 val modalRelationQueries = modalRelationQueriesBuilder.build
106 val invalidWF = queries.getInvalidWFQueries.values
107 val mustUnitPropagationPreconditions = queries.getMustUnitPropagationPreconditionPatterns
108 val currentUnitPropagationPreconditions = queries.getCurrentUnitPropagationPreconditionPatterns
109 val queriesToPrepare = ImmutableSet.builder.addAll(queries.refineObjectQueries.values).addAll(
110 queries.refineTypeQueries.values).addAll(queries.refineRelationQueries.values).addAll(
111 queries.mustRelationPropagationQueries.values).addAll(queries.multiplicityConstraintQueries.values.flatMap [
112 allQueries
113 ]).addAll(queries.unfinishedWFQueries.values).addAll(queries.invalidWFQueries.values).addAll(
114 queries.mustUnitPropagationPreconditionPatterns.values).addAll(
115 queries.currentUnitPropagationPreconditionPatterns.values).add(queries.hasElementInContainmentQuery).build
116 val queryEngine = ViatraQueryEngine.on(new EMFScope(emptySolution))
117 GenericQueryGroup.of(queriesToPrepare).prepare(queryEngine)
118
119 val objectiveProvider = new ThreeValuedCostObjectiveProvider(queryEngine, emptySolution, modalRelationQueries)
120 val transformedObjectives = objectiveProvider.getCostObjectives(config.costObjectives)
121
122 val solutionSaver = new ViatraReasonerSolutionSaver(transformedObjectives.leveledExtremalObjectives,
123 config.solutionScope.numberOfRequiredSolutions, DiversityChecker.of(config.diversityRequirement))
124
125 val allHints = ImmutableSet.builder
126 allHints.addAll(config.hints)
127 for (hint : transformedObjectives.hints) {
128 hint.boundsProvider = solutionSaver
129 allHints.add(hint)
130 }
131
132 val scopePropagator = createScopePropagator(config.scopePropagatorStrategy, emptySolution, allHints.build,
133 transformedObjectives.extensionOperators, queries, statistics)
134 scopePropagator.propagateAllScopeConstraints
135 val unitRulePropagator = refinementRuleProvider.createUnitPrulePropagator(logicProblem, emptySolution, queries,
136 scopePropagator, statistics)
137 val objectRefinementRules = refinementRuleProvider.createObjectRefinementRules(logicProblem, emptySolution,
138 queries, unitRulePropagator, config.nameNewElements, statistics)
139 val relationRefinementRules = refinementRuleProvider.createRelationRefinementRules(queries, unitRulePropagator,
140 statistics)
141
142 return new ModelGenerationMethod(
143 statistics,
144 objectRefinementRules.values,
145 relationRefinementRules.values,
146 unfinishedMultiplicities,
147 unfinishedWF,
148 invalidWF,
149 mustUnitPropagationPreconditions,
150 currentUnitPropagationPreconditions,
151 modalRelationQueries,
152 queries.allQueries,
153 transformedObjectives.objectives,
154 transformedObjectives.optimizationProblem,
155 solutionSaver
156 )
157 }
158
159 private def createScopePropagator(ScopePropagatorStrategy scopePropagatorStrategy,
160 PartialInterpretation emptySolution, Collection<LinearTypeConstraintHint> hints,
161 Collection<PolyhedronExtensionOperator> extensionOperators, GeneratedPatterns queries,
162 ModelGenerationStatistics statistics) {
163 if (!hints.empty && !(scopePropagatorStrategy instanceof ScopePropagatorStrategy.Polyhedral)) {
164 throw new IllegalArgumentException("Only the Polyhedral scope propagator strategy can use hints.")
165 }
166 switch (scopePropagatorStrategy) {
167 case ScopePropagatorStrategy.None,
168 case ScopePropagatorStrategy.Basic:
169 new ScopePropagator(emptySolution, statistics)
170 case ScopePropagatorStrategy.BasicTypeHierarchy:
171 new TypeHierarchyScopePropagator(emptySolution, statistics)
172 ScopePropagatorStrategy.Polyhedral: {
173 val types = queries.refineObjectQueries.keySet.map[newType].toSet
174 val allPatternsByName = queries.allQueries.toMap[fullyQualifiedName]
175 val solver = switch (scopePropagatorStrategy.solver) {
176 case Z3Integer:
177 new Z3PolyhedronSolver(false, scopePropagatorStrategy.timeoutSeconds)
178 case Z3Real:
179 new Z3PolyhedronSolver(true, scopePropagatorStrategy.timeoutSeconds)
180 case Cbc:
181 new CbcPolyhedronSolver(false, scopePropagatorStrategy.timeoutSeconds, true)
182 case Clp:
183 new CbcPolyhedronSolver(true, scopePropagatorStrategy.timeoutSeconds, true)
184 default:
185 throw new IllegalArgumentException("Unknown polyhedron solver: " +
186 scopePropagatorStrategy.solver)
187 }
188 val strategy = if (extensionOperators.empty) {
189 new CachingSimplePolyhedronScopePropagatorStrategy(solver, statistics)
190 } else {
191 new ExtendedPolyhedronScopePropagatorStrategy(solver, extensionOperators, statistics)
192 }
193 new PolyhedronScopePropagator(emptySolution, statistics, types, queries.multiplicityConstraintQueries,
194 queries.hasElementInContainmentQuery, allPatternsByName, hints, strategy,
195 scopePropagatorStrategy.requiresUpperBoundIndexing, scopePropagatorStrategy.updateHeuristic)
196 }
197 default:
198 throw new IllegalArgumentException("Unknown scope propagator strategy: " + scopePropagatorStrategy)
199 }
200 }
201}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend
index 4331420d..4d2fd741 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend
@@ -10,20 +10,28 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
10import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicproblemPackage 10import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicproblemPackage
11import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicresultFactory 11import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicresultFactory
12import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult 12import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult
13import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethodProvider
14import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator 13import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator
14import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy
15import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser 15import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser
16import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 16import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
17import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage 17import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage
18import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.AbstractNeighbourhoodBasedStateCoderFactory
18import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory 19import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory
19import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedStateCoderFactory 20import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedHashStateCoderFactory
21import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.PairwiseNeighbourhoodBasedStateCoderFactory
22import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BasicScopeGlobalConstraint
20import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.HillClimbingOnRealisticMetricStrategyForModelGeneration 23import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.HillClimbingOnRealisticMetricStrategyForModelGeneration
24import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.InconsistentScopeGlobalConstraint
25import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.LoggerSolutionFoundHandler
21import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ModelGenerationCompositeObjective 26import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ModelGenerationCompositeObjective
27import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.NumericSolver
22import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PartialModelAsLogicInterpretation 28import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PartialModelAsLogicInterpretation
29import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PunishSizeObjective
23import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ScopeObjective 30import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ScopeObjective
31import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.SurelyViolatedObjectiveGlobalConstraint
24import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.UnfinishedMultiplicityObjective 32import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.UnfinishedMultiplicityObjective
25import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.UnfinishedWFObjective
26import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.WF2ObjectiveConverter 33import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.WF2ObjectiveConverter
34import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveKind
27import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace 35import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace
28import java.util.List 36import java.util.List
29import java.util.Map 37import java.util.Map
@@ -34,193 +42,320 @@ import org.eclipse.viatra.dse.api.DesignSpaceExplorer.DseLoggingLevel
34import org.eclipse.viatra.dse.solutionstore.SolutionStore 42import org.eclipse.viatra.dse.solutionstore.SolutionStore
35import org.eclipse.viatra.dse.statecode.IStateCoderFactory 43import org.eclipse.viatra.dse.statecode.IStateCoderFactory
36 44
37class ViatraReasoner extends LogicReasoner{ 45class ViatraReasoner extends LogicReasoner {
38 val PartialInterpretationInitialiser initialiser = new PartialInterpretationInitialiser() 46 val PartialInterpretationInitialiser initialiser = new PartialInterpretationInitialiser()
39 val ModelGenerationMethodProvider modelGenerationMethodProvider = new ModelGenerationMethodProvider 47 val ModelGenerationMethodProvider modelGenerationMethodProvider = new ModelGenerationMethodProvider
40 val extension LogicresultFactory factory = LogicresultFactory.eINSTANCE 48 val extension LogicresultFactory factory = LogicresultFactory.eINSTANCE
41 val WF2ObjectiveConverter wf2ObjectiveConverter = new WF2ObjectiveConverter 49 val WF2ObjectiveConverter wf2ObjectiveConverter = new WF2ObjectiveConverter
42 50
43 51 override solve(LogicProblem problem, LogicSolverConfiguration configuration,
44 override solve(LogicProblem problem, LogicSolverConfiguration configuration, ReasonerWorkspace workspace) throws LogicReasonerException { 52 ReasonerWorkspace workspace) throws LogicReasonerException {
45 val viatraConfig = configuration.asConfig 53 val viatraConfig = configuration.asConfig
46 54
47 if(viatraConfig.debugCongiguration.logging) { 55 if (viatraConfig.documentationLevel == DocumentationLevel.FULL) {
48 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.VERBOSE_FULL) 56 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.VERBOSE_FULL)
49 } else { 57 } else {
50 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.WARN) 58 DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.WARN)
51 } 59 }
52 60
53 val DesignSpaceExplorer dse = new DesignSpaceExplorer(); 61 val DesignSpaceExplorer dse = new DesignSpaceExplorer();
54 62
55 dse.addMetaModelPackage(LogiclanguagePackage.eINSTANCE) 63 dse.addMetaModelPackage(LogiclanguagePackage.eINSTANCE)
56 dse.addMetaModelPackage(LogicproblemPackage.eINSTANCE) 64 dse.addMetaModelPackage(LogicproblemPackage.eINSTANCE)
57 dse.addMetaModelPackage(PartialinterpretationPackage.eINSTANCE) 65 dse.addMetaModelPackage(PartialinterpretationPackage.eINSTANCE)
58 66
59 val transformationStartTime = System.nanoTime 67 val transformationStartTime = System.nanoTime
60 68 val emptySolution = initialiser.initialisePartialInterpretation(problem, viatraConfig.typeScopes).output
61 69 if ((viatraConfig.documentationLevel == DocumentationLevel::FULL ||
62 70 viatraConfig.documentationLevel == DocumentationLevel::NORMAL) && workspace !== null) {
63 val emptySolution = initialiser.initialisePartialInterpretation(problem,viatraConfig.typeScopes).output 71 workspace.writeModel(emptySolution, "init.partialmodel")
64 72 }
65 if((viatraConfig.documentationLevel == DocumentationLevel::FULL || viatraConfig.documentationLevel == DocumentationLevel::NORMAL) && workspace !== null) { 73
66 workspace.writeModel(emptySolution,"init.partialmodel")
67 }
68 emptySolution.problemConainer = problem 74 emptySolution.problemConainer = problem
69 val emptySolutionCopy = EcoreUtil.copy(emptySolution) 75 val emptySolutionCopy = EcoreUtil.copy(emptySolution)
76
70 val ScopePropagator scopePropagator = new ScopePropagator(emptySolution) 77 val ScopePropagator scopePropagator = new ScopePropagator(emptySolution)
71 scopePropagator.propagateAllScopeConstraints 78 scopePropagator.propagateAllScopeConstraints
72 79
80 var BasicScopeGlobalConstraint basicScopeGlobalConstraint = null
81 if (viatraConfig.scopePropagatorStrategy == ScopePropagatorStrategy.None) {
82 basicScopeGlobalConstraint = new BasicScopeGlobalConstraint(emptySolution)
83 emptySolution.scopes.clear
84 }
85
73 val method = modelGenerationMethodProvider.createModelGenerationMethod( 86 val method = modelGenerationMethodProvider.createModelGenerationMethod(
74 problem, 87 problem,
75 emptySolution, 88 emptySolution,
76 workspace, 89 workspace,
77 viatraConfig.nameNewElements, 90 viatraConfig
78 viatraConfig.typeInferenceMethod,
79 scopePropagator,
80 viatraConfig.documentationLevel
81 ) 91 )
82 92
83 dse.addObjective(new ModelGenerationCompositeObjective( 93 val compositeObjective = new ModelGenerationCompositeObjective(
84 new ScopeObjective, 94 basicScopeGlobalConstraint ?: new ScopeObjective,
85 method.unfinishedMultiplicities.map[new UnfinishedMultiplicityObjective(it)], 95 method.unfinishedMultiplicities.map[new UnfinishedMultiplicityObjective(it)],
86 new UnfinishedWFObjective(method.unfinishedWF), 96 wf2ObjectiveConverter.createCompletenessObjective(method.unfinishedWF),
87 viatraConfig.isWFOptional 97 viatraConfig
88 )) 98 )
99 dse.addObjective(compositeObjective)
100 if (viatraConfig.punishSize != PunishSizeStrategy.NONE) {
101 val punishSizeStrategy = switch (viatraConfig.punishSize) {
102 case SMALLER_IS_BETTER: ObjectiveKind.LOWER_IS_BETTER
103 case LARGER_IS_BETTER: ObjectiveKind.HIGHER_IS_BETTER
104 default: throw new IllegalArgumentException("Unknown PunishSizeStrategy: " + viatraConfig.punishSize)
105 }
106 val punishObjective = new PunishSizeObjective(punishSizeStrategy, compositeObjective.level + 1)
107 dse.addObjective(punishObjective)
108 }
89 109
90 dse.addGlobalConstraint(wf2ObjectiveConverter.createInvalidationObjective(method.invalidWF)) 110 for (costObjective : method.costObjectives) {
91 for(additionalConstraint : viatraConfig.searchSpaceConstraints.additionalGlobalConstraints) { 111 dse.addObjective(costObjective)
112 }
113 val numberOfRequiredSolutions = configuration.solutionScope.numberOfRequiredSolutions
114 val solutionStore = if (method.optimizationProblem) {
115 new SolutionStore()
116 } else {
117 new SolutionStore(numberOfRequiredSolutions)
118 }
119 solutionStore.registerSolutionFoundHandler(new LoggerSolutionFoundHandler(viatraConfig))
120 val numericSolver = new NumericSolver(method, viatraConfig.runIntermediateNumericalConsistencyChecks, false)
121 val solutionSaver = method.solutionSaver
122 solutionSaver.numericSolver = numericSolver
123 val solutionCopier = solutionSaver.solutionCopier
124 val diversityChecker = solutionSaver.diversityChecker
125 solutionStore.withSolutionSaver(solutionSaver)
126 dse.solutionStore = solutionStore
127
128 dse.addGlobalConstraint(wf2ObjectiveConverter.createInvalidationGlobalConstraint(method.invalidWF))
129 dse.addGlobalConstraint(new SurelyViolatedObjectiveGlobalConstraint(solutionSaver))
130 dse.addGlobalConstraint(new InconsistentScopeGlobalConstraint)
131 if (basicScopeGlobalConstraint !== null) {
132 dse.addGlobalConstraint(basicScopeGlobalConstraint)
133 }
134 for (additionalConstraint : viatraConfig.searchSpaceConstraints.additionalGlobalConstraints) {
92 dse.addGlobalConstraint(additionalConstraint.apply(method)) 135 dse.addGlobalConstraint(additionalConstraint.apply(method))
93 } 136 }
94 137
95 dse.setInitialModel(emptySolution,false) 138 dse.setInitialModel(emptySolution, false)
96 139
97 val IStateCoderFactory statecoder = if(viatraConfig.stateCoderStrategy == StateCoderStrategy.Neighbourhood) { 140 val IStateCoderFactory statecoder = switch (viatraConfig.stateCoderStrategy) {
98 new NeighbourhoodBasedStateCoderFactory 141 case Neighbourhood:
99 } else { 142 new NeighbourhoodBasedHashStateCoderFactory
100 new IdentifierBasedStateCoderFactory 143 case PairwiseNeighbourhood:
144 new PairwiseNeighbourhoodBasedStateCoderFactory
145 default:
146 new IdentifierBasedStateCoderFactory
101 } 147 }
102 dse.stateCoderFactory = statecoder 148 dse.stateCoderFactory = statecoder
103 149
104 dse.maxNumberOfThreads = 1 150 dse.maxNumberOfThreads = 1
105 151
106 val solutionStore = new SolutionStore(configuration.solutionScope.numberOfRequiredSolution) 152 for (rule : method.relationRefinementRules) {
107 dse.solutionStore = solutionStore
108
109 for(rule : method.relationRefinementRules) {
110 dse.addTransformationRule(rule) 153 dse.addTransformationRule(rule)
111 } 154 }
112 for(rule : method.objectRefinementRules) { 155 for (rule : method.objectRefinementRules) {
113 dse.addTransformationRule(rule) 156 dse.addTransformationRule(rule)
114 } 157 }
115 158
116 val strategy = new HillClimbingOnRealisticMetricStrategyForModelGeneration(workspace,viatraConfig,method) 159 val strategy = new HillClimbingOnRealisticMetricStrategyForModelGeneration(workspace,viatraConfig,method)
117 viatraConfig.progressMonitor.workedForwardTransformation 160 viatraConfig.progressMonitor.workedForwardTransformation
118 161 val transformationFinished = System.nanoTime
119 val transformationTime = System.nanoTime - transformationStartTime 162 val transformationTime = transformationFinished - transformationStartTime
120 val solverStartTime = System.nanoTime 163 val solverStartTime = System.nanoTime
121 164
122 var boolean stoppedByTimeout 165 var boolean stoppedByTimeout
123 var boolean stoppedByException 166 try {
124 try{ 167 stoppedByTimeout = dse.startExplorationWithTimeout(strategy, configuration.runtimeLimit * 1000);
125 stoppedByTimeout = dse.startExplorationWithTimeout(strategy,configuration.runtimeLimit*1000);
126 stoppedByException = false
127 } catch (NullPointerException npe) { 168 } catch (NullPointerException npe) {
128 stoppedByTimeout = false 169 stoppedByTimeout = false
129 stoppedByException = true
130 } 170 }
131 val solverTime = System.nanoTime - solverStartTime 171 val solverTime = System.nanoTime - solverStartTime
132 viatraConfig.progressMonitor.workedSearchFinished 172 viatraConfig.progressMonitor.workedSearchFinished
133 173
134 //find trajectory to each solution 174 // additionalMatches = strategy.solutionStoreWithCopy.additionalMatches
135 if(viatraConfig.documentationLevel == DocumentationLevel.NONE){
136 PartialInterpretationMetric.initPaths();
137 //PartialInterpretationMetric.outputTrajectories(emptySolutionCopy, dse.solutions.toList());
138 }
139
140 //additionalMatches = strategy.solutionStoreWithCopy.additionalMatches
141 val statistics = createStatistics => [ 175 val statistics = createStatistics => [
142 //it.solverTime = viatraConfig.runtimeLimit 176 // it.solverTime = viatraConfig.runtimeLimit
143 it.solverTime = (solverTime/1000000) as int 177 it.solverTime = (solverTime / 1000000) as int
144 it.transformationTime = (transformationTime/1000000) as int 178 it.transformationTime = (transformationTime / 1000000) as int
145 for(x : 0..<strategy.solutionStoreWithCopy.allRuntimes.size) { 179 for (pair : solutionCopier.getAllCopierRuntimes(true).indexed) {
146 it.entries += createIntStatisticEntry => [ 180 it.entries += createIntStatisticEntry => [
147 it.name = '''_Solution«x»FoundAt''' 181 it.name = '''Solution«pair.key»FoundAt'''
148 it.value = (strategy.solutionStoreWithCopy.allRuntimes.get(x)/1000000) as int 182 it.value = (pair.value / 1000000) as int
149 ] 183 ]
150 } 184 }
185 for (x : 0 ..< strategy.times.size) {
186 it.entries += createStringStatisticEntry => [
187 it.name = '''Solution«x+1»DetailedStatistics'''
188 it.value = strategy.times.get(x)
189 ]
190 }
191 it.entries += createIntStatisticEntry => [
192 it.name = "ExplorationInitializationTime"
193 it.value = ((strategy.explorationStarted - transformationFinished) / 1000000) as int
194 ]
195 it.entries += createIntStatisticEntry => [
196 it.name = "TransformationExecutionTime"
197 it.value = (method.statistics.transformationExecutionTime / 1000000) as int
198 ]
199 it.entries += createIntStatisticEntry => [
200 it.name = "ScopePropagationTime"
201 it.value = (method.statistics.scopePropagationTime / 1000000) as int
202 ]
203 it.entries += createIntStatisticEntry => [
204 it.name = "MustRelationPropagationTime"
205 it.value = (method.statistics.mustRelationPropagationTime / 1000000) as int
206 ]
207 it.entries += createIntStatisticEntry => [
208 it.name = "TypeAnalysisTime"
209 it.value = (method.statistics.preliminaryTypeAnalisisTime / 1000000) as int
210 ]
211 it.entries += createIntStatisticEntry => [
212 it.name = "StateCoderTime"
213 it.value = (statecoder.runtime / 1000000) as int
214 ]
215 it.entries += createIntStatisticEntry => [
216 it.name = "StateCoderFailCount"
217 it.value = strategy.numberOfStatecoderFail
218 ]
151 it.entries += createIntStatisticEntry => [ 219 it.entries += createIntStatisticEntry => [
152 it.name = "TransformationExecutionTime" it.value = (method.statistics.transformationExecutionTime/1000000) as int 220 it.name = "SolutionCopyTime"
221 it.value = (solutionCopier.getTotalCopierRuntime / 1000000) as int
153 ] 222 ]
154 it.entries += createIntStatisticEntry => [ 223 it.entries += createIntStatisticEntry => [
155 it.name = "TypeAnalysisTime" it.value = (method.statistics.PreliminaryTypeAnalisisTime/1000000) as int 224 it.name = "States"
225 it.value = dse.numberOfStates as int
226 ]
227 it.entries += createIntStatisticEntry => [
228 it.name = "ForwardTime"
229 it.value = (strategy.forwardTime / 1000000) as int
230 ]
231 it.entries += createIntStatisticEntry => [
232 it.name = "BacktrackingTime"
233 it.value = (strategy.backtrackingTime / 1000000) as int
234 ]
235 it.entries += createIntStatisticEntry => [
236 it.name = "GlobalConstraintEvaluationTime"
237 it.value = (strategy.globalConstraintEvaluationTime / 1000000) as int
238 ]
239 it.entries += createIntStatisticEntry => [
240 it.name = "FitnessCalculationTime"
241 it.value = (strategy.fitnessCalculationTime / 1000000) as int
242 ]
243 it.entries += createIntStatisticEntry => [
244 it.name = "SolutionCopyTime"
245 it.value = (solutionSaver.totalCopierRuntime / 1000000) as int
246 ]
247 it.entries += createIntStatisticEntry => [
248 it.name = "ActivationSelectionTime"
249 it.value = (strategy.activationSelector.runtime / 1000000) as int
250 ]
251 it.entries += createIntStatisticEntry => [
252 it.name = "Decisions"
253 it.value = method.statistics.decisionsTried
156 ] 254 ]
157 it.entries += createIntStatisticEntry =>[ 255 it.entries += createIntStatisticEntry =>[
158 it.name = "MetricCalculationTime" it.value = (method.statistics.metricCalculationTime/1000000) as int 256 it.name = "MetricCalculationTime" it.value = (method.statistics.metricCalculationTime/1000000) as int
159 ] 257 ]
160 it.entries += createIntStatisticEntry => [ 258 it.entries += createIntStatisticEntry => [
161 it.name = "StateCoderTime" it.value = (statecoder.runtime/1000000) as int 259 it.name = "Transformations"
260 it.value = method.statistics.transformationInvocations
162 ] 261 ]
163 it.entries += createIntStatisticEntry => [ 262 it.entries += createIntStatisticEntry => [
164 it.name = "StateCoderFailCount" it.value = strategy.numberOfStatecoderFail 263 it.name = "ScopePropagations"
264 it.value = method.statistics.scopePropagatorInvocations
165 ] 265 ]
166 it.entries += createIntStatisticEntry => [ 266 it.entries += createIntStatisticEntry => [
167 it.name = "SolutionCopyTime" it.value = (strategy.solutionStoreWithCopy.sumRuntime/1000000) as int 267 it.name = "ScopePropagationsSolverCalls"
268 it.value = method.statistics.scopePropagatorSolverInvocations
168 ] 269 ]
169 if(strategy.solutionStoreWithDiversityDescriptor.isActive) { 270// it.entries += createIntStatisticEntry => [
271// it.name = "NumericalSolverSumTime"
272// it.value = (strategy.numericSolver.runtime / 1000000) as int
273// ]
274// it.entries += createIntStatisticEntry => [
275// it.name = "NumericalSolverProblemFormingTime"
276// it.value = (strategy.numericSolver.solverFormingProblem / 1000000) as int
277// ]
278// it.entries += createIntStatisticEntry => [
279// it.name = "NumericalSolverSolvingTime"
280// it.value = (strategy.numericSolver.solverSolvingProblem / 1000000) as int
281// ]
282// it.entries += createIntStatisticEntry => [
283// it.name = "NumericalSolverInterpretingSolution"
284// it.value = (strategy.numericSolver.solverSolution / 1000000) as int
285// ]
286// it.entries += createIntStatisticEntry => [
287// it.name = "NumericalSolverCachingTime"
288// it.value = (strategy.numericSolver.cachingTime / 1000000) as int
289// ]
290// it.entries += createIntStatisticEntry => [
291// it.name = "NumericalSolverCallNumber"
292// it.value = strategy.numericSolver.numberOfSolverCalls
293// ]
294// it.entries += createIntStatisticEntry => [
295// it.name = "NumericalSolverCachedAnswerNumber"
296// it.value = strategy.numericSolver.numberOfCachedSolverCalls
297// ]
298 if (diversityChecker.active) {
170 it.entries += createIntStatisticEntry => [ 299 it.entries += createIntStatisticEntry => [
171 it.name = "SolutionDiversityCheckTime" it.value = (strategy.solutionStoreWithDiversityDescriptor.sumRuntime/1000000) as int 300 it.name = "SolutionDiversityCheckTime"
301 it.value = (diversityChecker.totalRuntime / 1000000) as int
172 ] 302 ]
173 it.entries += createRealStatisticEntry => [ 303 it.entries += createRealStatisticEntry => [
174 it.name = "SolutionDiversitySuccessRate" it.value = strategy.solutionStoreWithDiversityDescriptor.successRate 304 it.name = "SolutionDiversitySuccessRate"
305 it.value = diversityChecker.successRate
175 ] 306 ]
176 } 307 }
177 ] 308 ]
178 309
179 viatraConfig.progressMonitor.workedBackwardTransformationFinished 310 viatraConfig.progressMonitor.workedBackwardTransformationFinished
180 311
181 if(stoppedByTimeout) { 312 if (stoppedByTimeout) {
182 return createInsuficientResourcesResult=>[ 313 return createInsuficientResourcesResult => [
183 it.problem = problem 314 it.problem = problem
184 it.resourceName="time" 315 it.resourceName = "time"
185 it.representation += strategy.solutionStoreWithCopy.solutions 316 it.representation += solutionCopier.getPartialInterpretations(true)
186 it.statistics = statistics 317 it.statistics = statistics
187 ] 318 ]
188 } else { 319 } else {
189 if(solutionStore.solutions.empty) { 320 if (solutionStore.solutions.empty) {
190 return createInconsistencyResult => [ 321 return createInconsistencyResult => [
191 it.problem = problem 322 it.problem = problem
192 it.representation += strategy.solutionStoreWithCopy.solutions 323 it.representation += solutionCopier.getPartialInterpretations(true)
193 it.statistics = statistics 324 it.statistics = statistics
194 ] 325 ]
195 } else { 326 } else {
196 return createModelResult => [ 327 return createModelResult => [
197 it.problem = problem 328 it.problem = problem
198 it.trace = strategy.solutionStoreWithCopy.copyTraces 329 it.trace = solutionCopier.getTraces(true)
199 it.representation += strategy.solutionStoreWithCopy.solutions 330 it.representation += solutionCopier.getPartialInterpretations(true)
200 it.statistics = statistics 331 it.statistics = statistics
201 ] 332 ]
202 } 333 }
203 } 334 }
204 } 335 }
205 336
206 private def dispatch long runtime(NeighbourhoodBasedStateCoderFactory sc) { 337 private def dispatch long runtime(AbstractNeighbourhoodBasedStateCoderFactory sc) {
207 sc.sumStatecoderRuntime 338 sc.sumStatecoderRuntime
208 } 339 }
209 340
210 private def dispatch long runtime(IdentifierBasedStateCoderFactory sc) { 341 private def dispatch long runtime(IdentifierBasedStateCoderFactory sc) {
211 sc.sumStatecoderRuntime 342 sc.sumStatecoderRuntime
212 } 343 }
213 344
214 override getInterpretations(ModelResult modelResult) { 345 override getInterpretations(ModelResult modelResult) {
215 val indexes = 0..<modelResult.representation.size 346 val indexes = 0 ..< modelResult.representation.size
216 val traces = modelResult.trace as List<Map<EObject, EObject>>; 347 val traces = modelResult.trace as List<Map<EObject, EObject>>;
217 val res = indexes.map[i | new PartialModelAsLogicInterpretation(modelResult.representation.get(i) as PartialInterpretation,traces.get(i))].toList 348 val res = indexes.map [ i |
349 new PartialModelAsLogicInterpretation(modelResult.representation.get(i) as PartialInterpretation,
350 traces.get(i))
351 ].toList
218 return res 352 return res
219 } 353 }
220 354
221 private def ViatraReasonerConfiguration asConfig(LogicSolverConfiguration configuration) { 355 private def ViatraReasonerConfiguration asConfig(LogicSolverConfiguration configuration) {
222 if(configuration instanceof ViatraReasonerConfiguration) { 356 if (configuration instanceof ViatraReasonerConfiguration) {
223 return configuration 357 return configuration
224 } else throw new IllegalArgumentException('''Wrong configuration. Expected: «ViatraReasonerConfiguration.name», but got: «configuration.class.name»"''') 358 } else
359 throw new IllegalArgumentException('''Wrong configuration. Expected: «ViatraReasonerConfiguration.name», but got: «configuration.class.name»"''')
225 } 360 }
226} 361}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend
index 10734859..628844de 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend
@@ -5,21 +5,37 @@ import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner
5import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicSolverConfiguration 5import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicSolverConfiguration
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration 6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration 7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod
9import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeInferenceMethod 8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeInferenceMethod
9import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeConstraintHint
10import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedralScopePropagatorConstraints
11import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedralScopePropagatorSolver
12import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy
13import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.UnitPropagationPatternGenerator
10import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser 14import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser
15import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostObjectiveHint
16import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveKind
17import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold
11import java.util.LinkedList 18import java.util.LinkedList
12import java.util.List 19import java.util.List
13import java.util.Set 20import java.util.Set
14import org.eclipse.xtext.xbase.lib.Functions.Function1 21import org.eclipse.xtext.xbase.lib.Functions.Function1
15 22
16public enum StateCoderStrategy { 23enum StateCoderStrategy {
17 Neighbourhood, NeighbourhoodWithEquivalence, IDBased, DefinedByDiversity 24 Neighbourhood,
25 PairwiseNeighbourhood,
26 NeighbourhoodWithEquivalence,
27 IDBased,
28 DefinedByDiversity
18} 29}
19 30
20class ViatraReasonerConfiguration extends LogicSolverConfiguration{ 31enum PunishSizeStrategy {
21 //public var Iterable<PQuery> existingQueries 32 NONE,
22 33 SMALLER_IS_BETTER,
34 LARGER_IS_BETTER
35}
36
37class ViatraReasonerConfiguration extends LogicSolverConfiguration {
38 // public var Iterable<PQuery> existingQueries
23 public var nameNewElements = false 39 public var nameNewElements = false
24 public var StateCoderStrategy stateCoderStrategy = StateCoderStrategy.Neighbourhood 40 public var StateCoderStrategy stateCoderStrategy = StateCoderStrategy.Neighbourhood
25 public var TypeInferenceMethod typeInferenceMethod = TypeInferenceMethod.PreliminaryAnalysis 41 public var TypeInferenceMethod typeInferenceMethod = TypeInferenceMethod.PreliminaryAnalysis
@@ -27,7 +43,7 @@ class ViatraReasonerConfiguration extends LogicSolverConfiguration{
27 * Once per 1/randomBacktrackChance the search selects a random state. 43 * Once per 1/randomBacktrackChance the search selects a random state.
28 */ 44 */
29 public var int randomBacktrackChance = 20; 45 public var int randomBacktrackChance = 20;
30 46
31 /** 47 /**
32 * Describes the required diversity between the solutions. 48 * Describes the required diversity between the solutions.
33 * Null means that the solutions have to have different state codes only. 49 * Null means that the solutions have to have different state codes only.
@@ -41,22 +57,40 @@ class ViatraReasonerConfiguration extends LogicSolverConfiguration{
41 /** 57 /**
42 * Configuration for debugging support. 58 * Configuration for debugging support.
43 */ 59 */
44 public var DebugConfiguration debugCongiguration = new DebugConfiguration 60 public var DebugConfiguration debugConfiguration = new DebugConfiguration
45 /** 61 /**
46 * Configuration for cutting search space. 62 * Configuration for cutting search space.
47 */ 63 */
48 public var SearchSpaceConstraint searchSpaceConstraints = new SearchSpaceConstraint 64 public var SearchSpaceConstraint searchSpaceConstraints = new SearchSpaceConstraint
49 65
50 public var RealisticGuidance realisticGuidance = RealisticGuidance.Composite; 66 public var runIntermediateNumericalConsistencyChecks = true
67
68 public var punishSize = PunishSizeStrategy.NONE
69 public var scopeWeight = 1
70 public var conaintmentWeight = 2
71 public var nonContainmentWeight = 1
72 public var unfinishedWFWeight = 1
73 public var calculateObjectCreationCosts = false
74
75 public var RealisticGuidance realisticGuidance = RealisticGuidance.Composite;
51 76
52 public var isWFOptional = false; 77 public var isWFOptional = false;
53 78
54 public var allowMustViolations = false; 79 public var allowMustViolations = false;
55 80
56 public var String domain = ''; 81 public var String domain = '';
82 public var ScopePropagatorStrategy scopePropagatorStrategy = new ScopePropagatorStrategy.Polyhedral(
83 PolyhedralScopePropagatorConstraints.Relational, PolyhedralScopePropagatorSolver.Clp)
84// public var ScopePropagatorStrategy scopePropagatorStrategy = ScopePropagatorStrategy.BasicTypeHierarchy
85
86 public var List<LinearTypeConstraintHint> hints = newArrayList
87
88 public var List<CostObjectiveConfiguration> costObjectives = newArrayList
89
90 public var List<UnitPropagationPatternGenerator> unitPropagationPatternGenerators = newArrayList
57} 91}
58 92
59public class DiversityDescriptor { 93class DiversityDescriptor {
60 public var ensureDiversity = false 94 public var ensureDiversity = false
61 public static val FixPointRange = -1 95 public static val FixPointRange = -1
62 public var int range = FixPointRange 96 public var int range = FixPointRange
@@ -66,6 +100,23 @@ public class DiversityDescriptor {
66 public var Set<RelationDeclaration> relevantRelations = null 100 public var Set<RelationDeclaration> relevantRelations = null
67} 101}
68 102
103class DebugConfiguration {
104 public var PartialInterpretationVisualiser partialInterpretatioVisualiser = null
105 public var partalInterpretationVisualisationFrequency = 1
106}
107
108class InternalConsistencyCheckerConfiguration {
109 public var LogicReasoner internalIncosnsitencyDetector = null
110 public var LogicSolverConfiguration internalInconsistencDetectorConfiguration = null
111 public var incternalConsistencyCheckingFrequency = 1
112}
113
114class SearchSpaceConstraint {
115 public static val UNLIMITED_MAXDEPTH = Integer.MAX_VALUE
116 public var int maxDepth = UNLIMITED_MAXDEPTH
117 public var List<Function1<ModelGenerationMethod, ModelGenerationMethodBasedGlobalConstraint>> additionalGlobalConstraints = new LinkedList
118}
119
69public enum RealisticGuidance{ 120public enum RealisticGuidance{
70 MPC, 121 MPC,
71 NodeActivity, 122 NodeActivity,
@@ -75,21 +126,16 @@ public enum RealisticGuidance{
75 Composite_Without_Violations, 126 Composite_Without_Violations,
76 Violations 127 Violations
77} 128}
78 129class CostObjectiveConfiguration {
79public class DebugConfiguration { 130 public var List<CostObjectiveElementConfiguration> elements = newArrayList
80 public var logging = false 131 public var ObjectiveKind kind
81 public var PartialInterpretationVisualiser partialInterpretatioVisualiser = null; 132 public var ObjectiveThreshold threshold
82 public var partalInterpretationVisualisationFrequency = 1 133 public var boolean findExtremum
134 public var CostObjectiveHint hint
83} 135}
84 136
85public class InternalConsistencyCheckerConfiguration { 137class CostObjectiveElementConfiguration {
86 public var LogicReasoner internalIncosnsitencyDetector = null 138 public var String patternQualifiedName
87 public var LogicSolverConfiguration internalInconsistencDetectorConfiguration = null 139 public var int weight
88 public var incternalConsistencyCheckingFrequency = 1
89} 140}
90 141
91public class SearchSpaceConstraint {
92 public static val UNLIMITED_MAXDEPTH = Integer.MAX_VALUE
93 public var int maxDepth = UNLIMITED_MAXDEPTH
94 public var List<Function1<ModelGenerationMethod, ModelGenerationMethodBasedGlobalConstraint>> additionalGlobalConstraints = new LinkedList
95} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ActivationSelector.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ActivationSelector.xtend
new file mode 100644
index 00000000..65f9814c
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ActivationSelector.xtend
@@ -0,0 +1,24 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import java.util.ArrayList
4import java.util.Collection
5import java.util.Random
6
7abstract class ActivationSelector {
8 long runtime = 0
9 protected val Random r
10 new(Random r) {
11 this.r = r
12 }
13
14 def randomizeActivationIDs(Collection<Object> activationIDs) {
15 val startTime = System.nanoTime
16 val res = internalRandomizationOfActivationIDs(activationIDs)
17 runtime+= System.nanoTime-startTime
18 return res
19 }
20 def protected ArrayList<Object> internalRandomizationOfActivationIDs(Collection<Object> activationIDs);
21 def getRuntime(){
22 return runtime
23 }
24} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BalancedActivationSelector.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BalancedActivationSelector.xtend
new file mode 100644
index 00000000..2df9957b
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BalancedActivationSelector.xtend
@@ -0,0 +1,51 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import java.util.Collection
4import java.util.HashMap
5import java.util.Map
6import java.util.List
7import java.util.Random
8import java.util.ArrayList
9import java.util.LinkedList
10import java.util.Collections
11
12class BalancedActivationSelector extends ActivationSelector{
13 val Random r = new Random
14
15 new(Random r) {
16 super(r)
17 }
18
19 override protected internalRandomizationOfActivationIDs(Collection<Object> activationIDs) {
20 val Map<String,List<Object>> urns = new HashMap
21 val res = new ArrayList(activationIDs.size)
22 for(activationID : activationIDs) {
23 val pair = activationID as Pair<String,? extends Object>
24 val name = pair.key
25 val selectedUrn = urns.get(name)
26 if(selectedUrn!==null) {
27 selectedUrn.add(activationID)
28 } else {
29 val collection = new LinkedList
30 collection.add(activationID)
31 urns.put(name,collection)
32 }
33 }
34
35 for(list:urns.values) {
36 Collections.shuffle(list,r)
37 }
38
39 while(!urns.empty) {
40 val randomEntry = urns.entrySet.get(r.nextInt(urns.size))
41 val list = randomEntry.value
42 val removedLast = list.remove(list.size-1)
43 res.add(removedLast)
44 if(list.empty) {
45 urns.remove(randomEntry.key)
46 }
47 }
48 return res
49 }
50
51} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BasicScopeGlobalConstraint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BasicScopeGlobalConstraint.xtend
new file mode 100644
index 00000000..67f447ed
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BasicScopeGlobalConstraint.xtend
@@ -0,0 +1,103 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import com.google.common.collect.ImmutableList
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation
6import java.util.Comparator
7import java.util.List
8import org.eclipse.viatra.dse.base.ThreadContext
9import org.eclipse.viatra.dse.objectives.Comparators
10import org.eclipse.viatra.dse.objectives.IGlobalConstraint
11import org.eclipse.viatra.dse.objectives.IObjective
12import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
13
14class BasicScopeGlobalConstraint implements IGlobalConstraint, IObjective {
15 val PartialInterpretation p
16 val List<ScopeAssertion> assertions
17
18 new(PartialInterpretation p) {
19 this.p = p
20 assertions = ImmutableList.copyOf(p.scopes.map [
21 val currentSize = targetTypeInterpretation.elements.size
22 val minElements = minNewElements + currentSize
23 val maxElements = if (maxNewElements < 0) {
24 -1
25 } else {
26 maxNewElements + currentSize
27 }
28 new ScopeAssertion(minElements, maxElements, targetTypeInterpretation)
29 ])
30 }
31
32 override init(ThreadContext context) {
33 if (context.model != p) {
34 throw new IllegalArgumentException(
35 "Partial model must be passed to the constructor of BasicScopeGlobalConstraint")
36 }
37 }
38
39 override checkGlobalConstraint(ThreadContext context) {
40 assertions.forall[upperBoundSatisfied]
41 }
42
43 override getFitness(ThreadContext context) {
44 var double fitness = p.minNewElements
45 for (assertion : assertions) {
46 if (!assertion.lowerBoundSatisfied) {
47 fitness += 1
48 }
49 }
50 fitness
51 }
52
53 override satisifiesHardObjective(Double fitness) {
54 fitness <= 0.01
55 }
56
57 override BasicScopeGlobalConstraint createNew() {
58 this
59 }
60
61 override getName() {
62 class.name
63 }
64
65 override getComparator() {
66 Comparators.LOWER_IS_BETTER
67 }
68
69 override getLevel() {
70 2
71 }
72
73 override isHardObjective() {
74 true
75 }
76
77 override setComparator(Comparator<Double> comparator) {
78 throw new UnsupportedOperationException
79 }
80
81 override setLevel(int level) {
82 throw new UnsupportedOperationException
83 }
84
85 @FinalFieldsConstructor
86 private static class ScopeAssertion {
87 val int lowerBound
88 val int upperBound
89 val PartialTypeInterpratation typeDefinitions
90
91 private def getCount() {
92 typeDefinitions.elements.size
93 }
94
95 private def isLowerBoundSatisfied() {
96 count >= lowerBound
97 }
98
99 private def isUpperBoundSatisfied() {
100 upperBound < 0 || count <= upperBound
101 }
102 }
103}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java
index d9a1e54c..2940d12d 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java
@@ -9,9 +9,7 @@
9 *******************************************************************************/ 9 *******************************************************************************/
10package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse; 10package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse;
11 11
12import java.util.ArrayList;
13import java.util.Arrays; 12import java.util.Arrays;
14import java.util.Collection;
15import java.util.Collections; 13import java.util.Collections;
16import java.util.Comparator; 14import java.util.Comparator;
17import java.util.Iterator; 15import java.util.Iterator;
@@ -22,17 +20,16 @@ import java.util.Random;
22 20
23import org.apache.log4j.Level; 21import org.apache.log4j.Level;
24import org.apache.log4j.Logger; 22import org.apache.log4j.Logger;
23import org.eclipse.emf.ecore.EObject;
25import org.eclipse.emf.ecore.util.EcoreUtil; 24import org.eclipse.emf.ecore.util.EcoreUtil;
25import org.eclipse.viatra.dse.api.SolutionTrajectory;
26import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; 26import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
27import org.eclipse.viatra.dse.base.ThreadContext; 27import org.eclipse.viatra.dse.base.ThreadContext;
28import org.eclipse.viatra.dse.objectives.Fitness; 28import org.eclipse.viatra.dse.objectives.Fitness;
29import org.eclipse.viatra.dse.objectives.IObjective; 29import org.eclipse.viatra.dse.objectives.IObjective;
30import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper; 30import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
31import org.eclipse.viatra.dse.solutionstore.ISolutionFoundHandler;
31import org.eclipse.viatra.dse.solutionstore.SolutionStore; 32import org.eclipse.viatra.dse.solutionstore.SolutionStore;
32import org.eclipse.viatra.query.runtime.api.IPatternMatch;
33import org.eclipse.viatra.query.runtime.api.IQuerySpecification;
34import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
35import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher;
36 33
37import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel; 34import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel;
38import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner; 35import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner;
@@ -40,11 +37,11 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem;
40import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult; 37import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult;
41import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult; 38import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult;
42import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult; 39import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult;
43import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod;
44import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic; 40import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic;
45import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation; 41import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation;
46import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation; 42import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation;
47import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser; 43import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser;
44import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ModelGenerationMethod;
48import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration; 45import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration;
49import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace; 46import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace;
50 47
@@ -77,54 +74,72 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
77 // Running 74 // Running
78 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore; 75 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore;
79 private SolutionStore solutionStore; 76 private SolutionStore solutionStore;
80 private SolutionStoreWithCopy solutionStoreWithCopy;
81 private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor;
82 private volatile boolean isInterrupted = false; 77 private volatile boolean isInterrupted = false;
83 private ModelResult modelResultByInternalSolver = null; 78 private ModelResult modelResultByInternalSolver = null;
84 private Random random = new Random(); 79 private Random random = new Random();
85 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers; 80// private Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers;
86 81 public ActivationSelector activationSelector = new EvenActivationSelector(random);
82 public ViatraReasonerSolutionSaver solutionSaver;
83 public NumericSolver numericSolver;
87 // Statistics 84 // Statistics
88 private int numberOfStatecoderFail = 0; 85 private int numberOfStatecoderFail = 0;
89 private int numberOfPrintedModel = 0; 86 private int numberOfPrintedModel = 0;
90 private int numberOfSolverCalls = 0; 87 private int numberOfSolverCalls = 0;
88 public long globalConstraintEvaluationTime = 0;
89 public long fitnessCalculationTime = 0;
90
91 public long explorationStarted = 0;
91 92
92 public BestFirstStrategyForModelGeneration( 93 public BestFirstStrategyForModelGeneration(
93 ReasonerWorkspace workspace, 94 ReasonerWorkspace workspace,
94 ViatraReasonerConfiguration configuration, 95 ViatraReasonerConfiguration configuration,
95 ModelGenerationMethod method) 96 ModelGenerationMethod method,
96 { 97 ViatraReasonerSolutionSaver solutionSaver,
98 NumericSolver numericSolver) {
97 this.workspace = workspace; 99 this.workspace = workspace;
98 this.configuration = configuration; 100 this.configuration = configuration;
99 this.method = method; 101 this.method = method;
102 this.solutionSaver = solutionSaver;
103 this.numericSolver = numericSolver;
104// logger.setLevel(Level.DEBUG);
100 } 105 }
101 106
102 public SolutionStoreWithCopy getSolutionStoreWithCopy() {
103 return solutionStoreWithCopy;
104 }
105 public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() {
106 return solutionStoreWithDiversityDescriptor;
107 }
108 public int getNumberOfStatecoderFail() { 107 public int getNumberOfStatecoderFail() {
109 return numberOfStatecoderFail; 108 return numberOfStatecoderFail;
110 } 109 }
110 public long getForwardTime() {
111 return context.getDesignSpaceManager().getForwardTime();
112 }
113 public long getBacktrackingTime() {
114 return context.getDesignSpaceManager().getBacktrackingTime();
115 }
111 116
112 @Override 117 @Override
113 public void initStrategy(ThreadContext context) { 118 public void initStrategy(ThreadContext context) {
114 this.context = context; 119 this.context = context;
115 this.solutionStore = context.getGlobalContext().getSolutionStore(); 120 this.solutionStore = context.getGlobalContext().getSolutionStore();
116 ViatraQueryEngine engine = context.getQueryEngine(); 121 solutionStore.registerSolutionFoundHandler(new ISolutionFoundHandler() {
117// // TODO: visualisation 122
118 matchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>(); 123 @Override
119 for(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> p : this.method.getAllPatterns()) { 124 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
120 //System.out.println(p.getSimpleName()); 125 // Ignore.
121 ViatraQueryMatcher<? extends IPatternMatch> matcher = p.getMatcher(engine); 126 }
122 matchers.add(matcher); 127
123 } 128 @Override
129 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
130 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolutions);
131 saveTimes();
132 logger.debug("Found a solution.");
133 }
134 });
135 numericSolver.init(context);
124 136
125 this.solutionStoreWithCopy = new SolutionStoreWithCopy(); 137// ViatraQueryEngine engine = context.getQueryEngine();
126 this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement); 138// matchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
127 139// for(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> p : this.method.getAllPatterns()) {
140// ViatraQueryMatcher<? extends IPatternMatch> matcher = p.getMatcher(engine);
141// }
142//
128 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 143 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
129 this.comparator = new Comparator<TrajectoryWithFitness>() { 144 this.comparator = new Comparator<TrajectoryWithFitness>() {
130 @Override 145 @Override
@@ -138,23 +153,26 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
138 153
139 @Override 154 @Override
140 public void explore() { 155 public void explore() {
141 if (!context.checkGlobalConstraints()) { 156 this.explorationStarted=System.nanoTime();
157 if (!checkGlobalConstraints()) {
142 logger.info("Global contraint is not satisifed in the first state. Terminate."); 158 logger.info("Global contraint is not satisifed in the first state. Terminate.");
143 return; 159 return;
160 } else if(!numericSolver.maySatisfiable()) {
161 logger.info("Numeric contraints are not satisifed in the first state. Terminate.");
162 return;
144 } 163 }
145 if (configuration.searchSpaceConstraints.maxDepth == 0) { 164 if (configuration.searchSpaceConstraints.maxDepth == 0) {
146 logger.info("Maximal depth is reached in the initial solution. Terminate."); 165 logger.info("Maximal depth is reached in the initial solution. Terminate.");
147 return; 166 return;
148 } 167 }
149 168
150 final Fitness firstFittness = context.calculateFitness(); 169 final Fitness firstFitness = calculateFitness();
151 checkForSolution(firstFittness); 170 checkForSolution(firstFitness);
152 171
153 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 172 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
154 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]); 173 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]);
155 TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness); 174 TrajectoryWithFitness currentTrajectoryWithFitness = new TrajectoryWithFitness(firstTrajectory, firstFitness);
156 trajectoiresToExplore.add(currentTrajectoryWithFittness); 175 trajectoiresToExplore.add(currentTrajectoryWithFitness);
157
158 //if(configuration) 176 //if(configuration)
159 visualiseCurrentState(); 177 visualiseCurrentState();
160// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) { 178// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) {
@@ -168,22 +186,22 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
168 186
169 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) { 187 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) {
170 188
171 if (currentTrajectoryWithFittness == null) { 189 if (currentTrajectoryWithFitness == null) {
172 if (trajectoiresToExplore.isEmpty()) { 190 if (trajectoiresToExplore.isEmpty()) {
173 logger.debug("State space is fully traversed."); 191 logger.debug("State space is fully traversed.");
174 return; 192 return;
175 } else { 193 } else {
176 currentTrajectoryWithFittness = selectState(); 194 currentTrajectoryWithFitness = selectState();
177 if (logger.isDebugEnabled()) { 195 if (logger.isDebugEnabled()) {
178 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray())); 196 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray()));
179 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness); 197 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFitness);
180 } 198 }
181 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory); 199 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFitness.trajectory);
182 } 200 }
183 } 201 }
184 202
185// visualiseCurrentState(); 203// visualiseCurrentState();
186// boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness); 204// boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithfitness);
187// if(consistencyCheckResult == true) { 205// if(consistencyCheckResult == true) {
188// continue mainLoop; 206// continue mainLoop;
189// } 207// }
@@ -193,32 +211,30 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
193 211
194 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && iterator.hasNext()) { 212 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && iterator.hasNext()) {
195 final Object nextActivation = iterator.next(); 213 final Object nextActivation = iterator.next();
196// if (!iterator.hasNext()) {
197// logger.debug("Last untraversed activation of the state.");
198// trajectoiresToExplore.remove(currentTrajectoryWithFittness);
199// }
200 logger.debug("Executing new activation: " + nextActivation); 214 logger.debug("Executing new activation: " + nextActivation);
201 context.executeAcitvationId(nextActivation); 215 context.executeAcitvationId(nextActivation);
216 method.getStatistics().incrementDecisionCount();
202 217
203 visualiseCurrentState(); 218 visualiseCurrentState();
204// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) { 219// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) {
205// System.out.println(matcher.getPatternName()); 220// int c = matcher.countMatches();
206// System.out.println("---------"); 221// if(c>=1) {
207// for(IPatternMatch m : matcher.getAllMatches()) { 222// System.out.println(c+ " " +matcher.getPatternName());
208// System.out.println(m); 223// }
209// }
210// System.out.println("---------");
211// } 224// }
212 225
213 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness); 226 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFitness);
214 if(consistencyCheckResult == true) { continue mainLoop; } 227 if(consistencyCheckResult == true) { continue mainLoop; }
215 228
216 if (context.isCurrentStateAlreadyTraversed()) { 229 if (context.isCurrentStateAlreadyTraversed()) {
217 logger.info("The new state is already visited."); 230 logger.info("The new state is already visited.");
218 context.backtrack(); 231 context.backtrack();
219 } else if (!context.checkGlobalConstraints()) { 232 } else if (!checkGlobalConstraints()) {
220 logger.debug("Global contraint is not satisifed."); 233 logger.debug("Global contraint is not satisifed.");
221 context.backtrack(); 234 context.backtrack();
235 } else if (!numericSolver.maySatisfiable()) {
236 logger.debug("Numeric constraints are not satisifed.");
237 context.backtrack();
222 } else { 238 } else {
223 final Fitness nextFitness = context.calculateFitness(); 239 final Fitness nextFitness = context.calculateFitness();
224 checkForSolution(nextFitness); 240 checkForSolution(nextFitness);
@@ -228,59 +244,89 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
228 continue; 244 continue;
229 } 245 }
230 246
231 TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness( 247 TrajectoryWithFitness nextTrajectoryWithfitness = new TrajectoryWithFitness(
232 context.getTrajectory().toArray(), nextFitness); 248 context.getTrajectory().toArray(), nextFitness);
233 trajectoiresToExplore.add(nextTrajectoryWithFittness); 249 trajectoiresToExplore.add(nextTrajectoryWithfitness);
234 250
235 int compare = objectiveComparatorHelper.compare(currentTrajectoryWithFittness.fitness, 251 int compare = objectiveComparatorHelper.compare(currentTrajectoryWithFitness.fitness,
236 nextTrajectoryWithFittness.fitness); 252 nextTrajectoryWithfitness.fitness);
237 if (compare < 0) { 253 if (compare < 0) {
238 logger.debug("Better fitness, moving on: " + nextFitness); 254 logger.debug("Better fitness, moving on: " + nextFitness);
239 currentTrajectoryWithFittness = nextTrajectoryWithFittness; 255 currentTrajectoryWithFitness = nextTrajectoryWithfitness;
240 continue mainLoop; 256 continue mainLoop;
241 } else if (compare == 0) { 257 } else if (compare == 0) {
242 logger.debug("Equally good fitness, moving on: " + nextFitness); 258 logger.debug("Equally good fitness, moving on: " + nextFitness);
243 currentTrajectoryWithFittness = nextTrajectoryWithFittness; 259 currentTrajectoryWithFitness = nextTrajectoryWithfitness;
244 continue mainLoop; 260 continue mainLoop;
245 } else { 261 } else {
246 logger.debug("Worse fitness."); 262 logger.debug("Worse fitness.");
247 currentTrajectoryWithFittness = null; 263 currentTrajectoryWithFitness = null;
248 continue mainLoop; 264 continue mainLoop;
249 } 265 }
250 } 266 }
251 } 267 }
252 268
253 logger.debug("State is fully traversed."); 269 logger.debug("State is fully traversed.");
254 trajectoiresToExplore.remove(currentTrajectoryWithFittness); 270 trajectoiresToExplore.remove(currentTrajectoryWithFitness);
255 currentTrajectoryWithFittness = null; 271 currentTrajectoryWithFitness = null;
256 272
257 } 273 }
258 logger.info("Interrupted."); 274 logger.info("Interrupted.");
259 } 275 }
260 276
277 private boolean checkGlobalConstraints() {
278 long start = System.nanoTime();
279 boolean result = context.checkGlobalConstraints();
280 globalConstraintEvaluationTime += System.nanoTime() - start;
281 return result;
282 }
283
284 private Fitness calculateFitness() {
285 long start = System.nanoTime();
286 Fitness fitness = context.calculateFitness();
287 fitnessCalculationTime += System.nanoTime() - start;
288 return fitness;
289 }
290
261 private List<Object> selectActivation() { 291 private List<Object> selectActivation() {
262 List<Object> activationIds; 292 List<Object> activationIds;
263 try { 293 try {
264 activationIds = new ArrayList<Object>(context.getUntraversedActivationIds()); 294 activationIds = this.activationSelector.randomizeActivationIDs(context.getUntraversedActivationIds());
265 Collections.shuffle(activationIds);
266 } catch (NullPointerException e) { 295 } catch (NullPointerException e) {
296// logger.warn("Unexpected state code: " + context.getDesignSpaceManager().getCurrentState());
267 numberOfStatecoderFail++; 297 numberOfStatecoderFail++;
268 activationIds = Collections.emptyList(); 298 activationIds = Collections.emptyList();
269 } 299 }
270 return activationIds; 300 return activationIds;
271 } 301 }
272 302
273 private void checkForSolution(final Fitness fittness) { 303 private void checkForSolution(final Fitness fitness) {
274 if (fittness.isSatisifiesHardObjectives()) { 304 solutionStore.newSolution(context);
275 if (solutionStoreWithDiversityDescriptor.isDifferent(context)) { 305 }
276 solutionStoreWithCopy.newSolution(context); 306
277 solutionStoreWithDiversityDescriptor.newSolution(context); 307 public List<String> times = new LinkedList<String>();
278 solutionStore.newSolution(context); 308 private void saveTimes() {
279 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolution); 309 long forwardTime = context.getDesignSpaceManager().getForwardTime()/1000000;
280 310 long backtrackingTime = context.getDesignSpaceManager().getBacktrackingTime()/1000000;
281 logger.debug("Found a solution."); 311 long activationSelection = this.activationSelector.getRuntime()/1000000;
282 } 312 long solutionCopierTime = this.solutionSaver.getTotalCopierRuntime()/1000000;
283 } 313 long numericalSolverSumTime = this.numericSolver.getRuntime()/1000000;
314 long numericalSolverProblemForming = this.numericSolver.getSolverSolvingProblem()/1000000;
315 long numericalSolverSolving = this.numericSolver.getSolverSolvingProblem()/1000000;
316 long numericalSolverInterpreting = this.numericSolver.getSolverSolution()/1000000;
317 this.times.add(
318 "(TransformationExecutionTime"+method.getStatistics().transformationExecutionTime/1000000+
319 "|ForwardTime:"+forwardTime+
320 "|Backtrackingtime:"+backtrackingTime+
321 "|GlobalConstraintEvaluationTime:"+(globalConstraintEvaluationTime/1000000)+
322 "|FitnessCalculationTime:"+(fitnessCalculationTime/1000000)+
323 "|ActivationSelectionTime:"+activationSelection+
324 "|SolutionCopyTime:"+solutionCopierTime+
325 "|NumericalSolverSumTime:"+numericalSolverSumTime+
326 "|NumericalSolverProblemFormingTime:"+numericalSolverProblemForming+
327 "|NumericalSolverSolvingTime:"+numericalSolverSolving+
328 "|NumericalSolverInterpretingSolution:"+numericalSolverInterpreting+")");
329
284 } 330 }
285 331
286 @Override 332 @Override
@@ -309,7 +355,7 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
309 } else { 355 } else {
310 return trajectoiresToExplore.element(); 356 return trajectoiresToExplore.element();
311 } 357 }
312 } 358 }
313 359
314// private void logCurrentStateMetric() { 360// private void logCurrentStateMetric() {
315// if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) { 361// if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) {
@@ -322,13 +368,16 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
322 368
323 369
324 public void visualiseCurrentState() { 370 public void visualiseCurrentState() {
325 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugCongiguration.partialInterpretatioVisualiser; 371 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugConfiguration.partialInterpretatioVisualiser;
326 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) { 372 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) {
327 PartialInterpretation p = (PartialInterpretation) (context.getModel()); 373 PartialInterpretation p = (PartialInterpretation) (context.getModel());
328 int id = ++numberOfPrintedModel; 374 int id = ++numberOfPrintedModel;
329 if (id % configuration.debugCongiguration.partalInterpretationVisualisationFrequency == 0) { 375 if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) {
330 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); 376 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p);
331 visualisation.writeToFile(workspace, String.format("state%09d.png", id)); 377 logger.debug("Visualizing state: " + id + " (" + context.getDesignSpaceManager().getCurrentState() + ")");
378 String name = String.format("state%09d", id);
379 visualisation.writeToFile(workspace, name + ".png");
380 workspace.writeModel((EObject) context.getModel(), name + ".xmi");
332 } 381 }
333 } 382 }
334 } 383 }
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend
new file mode 100644
index 00000000..fb1b2066
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend
@@ -0,0 +1,184 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import com.google.common.collect.HashMultiset
4import com.google.common.collect.ImmutableSet
5import com.google.common.collect.Multiset
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodWithTraces
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
10import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.DiversityDescriptor
11import java.util.Collection
12import java.util.HashSet
13import java.util.Map
14import java.util.Set
15import org.eclipse.viatra.dse.base.ThreadContext
16import org.eclipse.xtend.lib.annotations.Accessors
17
18interface DiversityChecker {
19 public static val NO_DIVERSITY_CHECKER = new DiversityChecker {
20 override isActive() {
21 false
22 }
23
24 override getTotalRuntime() {
25 0
26 }
27
28 override getSuccessRate() {
29 1.0
30 }
31
32 override newSolution(ThreadContext threadContext, Object solutionId, Collection<Object> dominatedSolutionIds) {
33 true
34 }
35 }
36
37 def boolean isActive()
38
39 def long getTotalRuntime()
40
41 def double getSuccessRate()
42
43 def boolean newSolution(ThreadContext threadContext, Object solutionId, Collection<Object> dominatedSolutionIds)
44
45 static def of(DiversityDescriptor descriptor) {
46 if (descriptor.ensureDiversity) {
47 new NodewiseDiversityChecker(descriptor)
48 } else {
49 NO_DIVERSITY_CHECKER
50 }
51 }
52}
53
54abstract class AbstractDiversityChecker implements DiversityChecker {
55 val DiversityDescriptor descriptor
56 val PartialInterpretation2ImmutableTypeLattice solutionCoder = new PartialInterpretation2ImmutableTypeLattice
57
58 @Accessors(PUBLIC_GETTER) var long totalRuntime = 0
59 var int allCheckCount = 0
60 var int successfulCheckCount = 0
61
62 protected new(DiversityDescriptor descriptor) {
63 if (!descriptor.ensureDiversity) {
64 throw new IllegalArgumentException(
65 "Diversity description should enforce diversity or NO_DIVERSITY_CHECKER should be used instead.")
66 }
67 this.descriptor = descriptor
68 }
69
70 override isActive() {
71 true
72 }
73
74 override getTotalRuntime() {
75 throw new UnsupportedOperationException("TODO: auto-generated method stub")
76 }
77
78 override getSuccessRate() {
79 (allCheckCount as double) / (successfulCheckCount as double)
80 }
81
82 override newSolution(ThreadContext threadContext, Object solutionId, Collection<Object> dominatedSolutionIds) {
83 val start = System.nanoTime
84 val model = threadContext.model as PartialInterpretation
85 val representation = solutionCoder.createRepresentation(model, descriptor.range, descriptor.parallels,
86 descriptor.maxNumber, descriptor.relevantTypes, descriptor.relevantRelations)
87 val isDifferent = internalNewSolution(representation, solutionId, dominatedSolutionIds)
88 totalRuntime += System.nanoTime - start
89 allCheckCount++
90 if (isDifferent) {
91 successfulCheckCount++
92 }
93 isDifferent
94 }
95
96 protected abstract def boolean internalNewSolution(
97 NeighbourhoodWithTraces<Map<? extends AbstractNodeDescriptor, Integer>, AbstractNodeDescriptor> representation,
98 Object solutionId, Collection<Object> dominatedSolutionIds)
99}
100
101class NodewiseDiversityChecker extends AbstractDiversityChecker {
102 var Multiset<Integer> nodeCodes = HashMultiset.create
103 val Map<Object, Set<Integer>> tracedNodeCodes = newHashMap
104
105 new(DiversityDescriptor descriptor) {
106 super(descriptor)
107 }
108
109 override protected internalNewSolution(
110 NeighbourhoodWithTraces<Map<? extends AbstractNodeDescriptor, Integer>, AbstractNodeDescriptor> representation,
111 Object solutionId, Collection<Object> dominatedSolutionIds) {
112 val nodeCodesInSolution = ImmutableSet.copyOf(representation.modelRepresentation.keySet.map[hashCode])
113 val remainingNodeCodes = if (dominatedSolutionIds.empty) {
114 nodeCodes
115 } else {
116 getRemainingNodeCodes(dominatedSolutionIds)
117 }
118 val hasNewCode = nodeCodesInSolution.exists[!remainingNodeCodes.contains(it)]
119 if (hasNewCode) {
120 nodeCodes = remainingNodeCodes
121 nodeCodes.addAll(nodeCodesInSolution)
122 for (dominatedSolutionId : dominatedSolutionIds) {
123 tracedNodeCodes.remove(dominatedSolutionId)
124 }
125 tracedNodeCodes.put(solutionId, nodeCodesInSolution)
126 }
127 hasNewCode
128 }
129
130 private def getRemainingNodeCodes(Collection<Object> dominatedSolutionIds) {
131 // TODO Optimize multiset operations.
132 val copyOfNodeCodes = HashMultiset.create(nodeCodes)
133 for (dominatedSolutionId : dominatedSolutionIds) {
134 val dominatedModelCode = tracedNodeCodes.get(dominatedSolutionId)
135 if (dominatedModelCode === null) {
136 throw new IllegalArgumentException("Unknown dominated solution: " + dominatedSolutionId)
137 }
138 copyOfNodeCodes.removeAll(dominatedModelCode)
139 }
140 copyOfNodeCodes
141 }
142}
143
144class GraphwiseDiversityChecker extends AbstractDiversityChecker {
145 var Set<Integer> modelCodes = newHashSet
146 val Map<Object, Integer> tracedModelCodes = newHashMap
147
148 new(DiversityDescriptor descriptor) {
149 super(descriptor)
150 }
151
152 override protected internalNewSolution(
153 NeighbourhoodWithTraces<Map<? extends AbstractNodeDescriptor, Integer>, AbstractNodeDescriptor> representation,
154 Object solutionId, Collection<Object> dominatedSolutionIds) {
155 val modelCodeOfSolution = representation.modelRepresentation.hashCode
156 val remainingModelCodes = if (dominatedSolutionIds.empty) {
157 modelCodes
158 } else {
159 getRemainingModelCodes(dominatedSolutionIds)
160 }
161 val isNewCode = !remainingModelCodes.contains(modelCodeOfSolution)
162 if (isNewCode) {
163 modelCodes = remainingModelCodes
164 modelCodes += modelCodeOfSolution
165 for (dominatedSolutionId : dominatedSolutionIds) {
166 tracedModelCodes.remove(dominatedSolutionId)
167 }
168 tracedModelCodes.put(solutionId, modelCodeOfSolution)
169 }
170 isNewCode
171 }
172
173 private def getRemainingModelCodes(Collection<Object> dominatedSolutionIds) {
174 val copyOfModelCodes = new HashSet(modelCodes)
175 for (dominatedSolutionId : dominatedSolutionIds) {
176 val dominatedModelCode = tracedModelCodes.get(dominatedSolutionId)
177 if (dominatedModelCode === null) {
178 throw new IllegalArgumentException("Unknown dominated solution: " + dominatedSolutionId)
179 }
180 copyOfModelCodes -= dominatedModelCode
181 }
182 copyOfModelCodes
183 }
184}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DseUtils.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DseUtils.xtend
new file mode 100644
index 00000000..3c2e3319
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DseUtils.xtend
@@ -0,0 +1,66 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.IThreeValuedObjective
4import org.eclipse.viatra.dse.base.ThreadContext
5import org.eclipse.viatra.dse.objectives.Comparators
6import org.eclipse.viatra.dse.objectives.Fitness
7import org.eclipse.viatra.dse.objectives.IObjective
8
9final class DseUtils {
10 private new() {
11 throw new IllegalStateException("This is a static utility class and should not be instantiated directly.")
12 }
13
14 static def calculateFitness(ThreadContext it, (IObjective)=>Double getFitness) {
15 val result = new Fitness
16 var boolean satisifiesHardObjectives = true
17 for (objective : objectives) {
18 val fitness = getFitness.apply(objective)
19 result.put(objective.name, fitness)
20 if (objective.isHardObjective() && !objective.satisifiesHardObjective(fitness)) {
21 satisifiesHardObjectives = false
22 }
23 }
24 result.satisifiesHardObjectives = satisifiesHardObjectives
25 result
26 }
27
28 static def caclulateBestPossibleFitness(ThreadContext threadContext) {
29 threadContext.calculateFitness [ objective |
30 if (objective instanceof IThreeValuedObjective) {
31 objective.getBestPossibleFitness(threadContext)
32 } else {
33 switch (objective.comparator) {
34 case Comparators.LOWER_IS_BETTER:
35 Double.NEGATIVE_INFINITY
36 case Comparators.HIGHER_IS_BETTER:
37 Double.POSITIVE_INFINITY
38 case Comparators.DIFFERENCE_TO_ZERO_IS_BETTER:
39 0.0
40 default:
41 throw new IllegalArgumentException("Unknown comparator for non-three-valued objective: " +
42 objective.name)
43 }
44 }
45 ]
46 }
47
48 static def caclulateWorstPossibleFitness(ThreadContext threadContext) {
49 threadContext.calculateFitness [ objective |
50 if (objective instanceof IThreeValuedObjective) {
51 objective.getWorstPossibleFitness(threadContext)
52 } else {
53 switch (objective.comparator) {
54 case Comparators.LOWER_IS_BETTER,
55 case Comparators.DIFFERENCE_TO_ZERO_IS_BETTER:
56 Double.POSITIVE_INFINITY
57 case Comparators.HIGHER_IS_BETTER:
58 Double.NEGATIVE_INFINITY
59 default:
60 throw new IllegalArgumentException("Unknown comparator for non-three-valued objective: " +
61 objective.name)
62 }
63 }
64 ]
65 }
66}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/EvenActivationSelector.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/EvenActivationSelector.xtend
new file mode 100644
index 00000000..82a5f32d
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/EvenActivationSelector.xtend
@@ -0,0 +1,20 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import java.util.Random
4import java.util.Collection
5import java.util.Collections
6import java.util.ArrayList
7
8class EvenActivationSelector extends ActivationSelector {
9
10 new(Random r) {
11 super(r)
12 }
13
14 override protected internalRandomizationOfActivationIDs(Collection<Object> activationIDs) {
15 val toShuffle = new ArrayList<Object>(activationIDs);
16 Collections.shuffle(toShuffle);
17 return toShuffle
18 }
19
20} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java
index eb7df089..d9f84b36 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java
@@ -16,6 +16,7 @@ import java.util.Random;
16import java.util.Set; 16import java.util.Set;
17 17
18import org.apache.log4j.Logger; 18import org.apache.log4j.Logger;
19import org.eclipse.emf.ecore.EObject;
19import org.eclipse.emf.ecore.util.EcoreUtil; 20import org.eclipse.emf.ecore.util.EcoreUtil;
20import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; 21import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
21import org.eclipse.viatra.dse.base.ThreadContext; 22import org.eclipse.viatra.dse.base.ThreadContext;
@@ -35,480 +36,540 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem;
35import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult; 36import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult;
36import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult; 37import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult;
37import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult; 38import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult;
38import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod;
39import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic; 39import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic;
40import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation; 40import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation;
41import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedPartialInterpretationStateCoder;
41import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation; 42import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation;
42import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser; 43import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser;
44import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ModelGenerationMethod;
43import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.RealisticGuidance; 45import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.RealisticGuidance;
44import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration; 46import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration;
45import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace; 47import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace;
46 48
47public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements IStrategy { 49public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements IStrategy {
48 // Services and Configuration 50 // Services and Configuration
49 private ThreadContext context; 51 private ThreadContext context;
50 private ReasonerWorkspace workspace; 52 private ReasonerWorkspace workspace;
51 private ViatraReasonerConfiguration configuration; 53 private ViatraReasonerConfiguration configuration;
52 private ModelGenerationMethod method; 54 private ModelGenerationMethod method;
53 private PartialInterpretation2Logic partialInterpretation2Logic = new PartialInterpretation2Logic(); 55 private PartialInterpretation2Logic partialInterpretation2Logic = new PartialInterpretation2Logic();
54 private Comparator<TrajectoryWithFitness> comparator; 56 private Comparator<TrajectoryWithFitness> comparator;
55 private Logger logger = Logger.getLogger(IStrategy.class); 57 private Logger logger = Logger.getLogger(IStrategy.class);
58 public NumericSolver numericSolver = null;
59
60 // Running
61 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore;
62 private SolutionStore solutionStore;
63 private SolutionStoreWithCopy solutionStoreWithCopy;
64 private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor;
65 private volatile boolean isInterrupted = false;
66 private ModelResult modelResultByInternalSolver = null;
67 private Random random = new Random();
68
69 // matchers for detecting the number of violations
70 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mustMatchers;
71 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mayMatchers;
72
73 // Encode the used activations of a particular state
74 private Map<Object, List<Object>> stateAndActivations;
75 private boolean allowMustViolation;
76 private Domain domain;
77 int targetSize;
78 public ActivationSelector activationSelector = new EvenActivationSelector(random);
79 // Statistics
80 private int numberOfStatecoderFail = 0;
81 private int numberOfPrintedModel = 0;
82 private int numberOfSolverCalls = 0;
83 private PartialInterpretationMetricDistance metricDistance;
84 private double currentStateValue = Double.MAX_VALUE;
85 private double currentNodeTypeDistance = 1;
86 private int numNodesToGenerate = 0;
87 public long explorationStarted = 0;
88 public long globalConstraintEvaluationTime = 0;
89 public long fitnessCalculationTime = 0;
90
91 public HillClimbingOnRealisticMetricStrategyForModelGeneration(
92 ReasonerWorkspace workspace,
93 ViatraReasonerConfiguration configuration,
94 ModelGenerationMethod method)
95 {
96 this.workspace = workspace;
97 this.configuration = configuration;
98 this.method = method;
99 }
100
101 public SolutionStoreWithCopy getSolutionStoreWithCopy() {
102 return solutionStoreWithCopy;
103 }
104 public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() {
105 return solutionStoreWithDiversityDescriptor;
106 }
107 public int getNumberOfStatecoderFail() {
108 return numberOfStatecoderFail;
109 }
110
111 public long getForwardTime() {
112 return context.getDesignSpaceManager().getForwardTime();
113 }
114 public long getBacktrackingTime() {
115 return context.getDesignSpaceManager().getBacktrackingTime();
116 }
117
118 @Override
119 public void initStrategy(ThreadContext context) {
120 this.context = context;
121 this.solutionStore = context.getGlobalContext().getSolutionStore();
122 domain = Domain.valueOf(configuration.domain);
123
124 ViatraQueryEngine engine = context.getQueryEngine();
125// // TODO: visualisation
126 mustMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
127 mayMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
56 128
57 // Running 129 // manully restict the number of super types of one class
58 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore; 130 this.method.getInvalidWF().forEach(a ->{
59 private SolutionStore solutionStore; 131 ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine);
60 private SolutionStoreWithCopy solutionStoreWithCopy; 132 mustMatchers.add(matcher);
61 private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor; 133 });
62 private volatile boolean isInterrupted = false;
63 private ModelResult modelResultByInternalSolver = null;
64 private Random random = new Random();
65 134
66 // matchers for detecting the number of violations 135 this.method.getUnfinishedWF().forEach(a ->{
67 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mustMatchers; 136 ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine);
68 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mayMatchers; 137 mayMatchers.add(matcher);
138 });
69 139
70 // Encode the used activations of a particular state
71 private Map<Object, List<Object>> stateAndActivations;
72 private boolean allowMustViolation;
73 private Domain domain;
74 int targetSize;
75
76 // Statistics
77 private int numberOfStatecoderFail = 0;
78 private int numberOfPrintedModel = 0;
79 private int numberOfSolverCalls = 0;
80 private PartialInterpretationMetricDistance metricDistance;
81 private double currentStateValue = Double.MAX_VALUE;
82 private double currentNodeTypeDistance = 1;
83 private int numNodesToGenerate = 0;
84 140
85 public HillClimbingOnRealisticMetricStrategyForModelGeneration( 141 //set up comparator
86 ReasonerWorkspace workspace, 142 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
87 ViatraReasonerConfiguration configuration, 143 this.comparator = new Comparator<TrajectoryWithFitness>() {
88 ModelGenerationMethod method) 144 @Override
89 { 145 public int compare(TrajectoryWithFitness o1, TrajectoryWithFitness o2) {
90 this.workspace = workspace; 146 return objectiveComparatorHelper.compare(o2.fitness, o1.fitness);
91 this.configuration = configuration; 147 }
92 this.method = method; 148 };
93 }
94 149
95 public SolutionStoreWithCopy getSolutionStoreWithCopy() { 150 this.solutionStoreWithCopy = new SolutionStoreWithCopy();
96 return solutionStoreWithCopy; 151 this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement);
97 } 152
98 public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() { 153 trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11, comparator);
99 return solutionStoreWithDiversityDescriptor; 154 stateAndActivations = new HashMap<Object, List<Object>>();
155 metricDistance = new PartialInterpretationMetricDistance(domain);
156
157 //set whether allows must violations during the realistic generation
158 allowMustViolation = configuration.allowMustViolations;
159 targetSize = configuration.typeScopes.maxNewElements + 2;
160 //this.numericSolver = new NumericSolver(method, this.configuration.runIntermediateNumericalConsistencyChecks, false);
161 }
162
163 @Override
164 public void explore() {
165 this.explorationStarted=System.nanoTime();
166 if (!checkGlobalConstraints()) {
167 logger.info("Global contraint is not satisifed in the first state. Terminate.");
168 return;
100 } 169 }
101 public int getNumberOfStatecoderFail() { 170 if (configuration.searchSpaceConstraints.maxDepth == 0) {
102 return numberOfStatecoderFail; 171 logger.info("Maximal depth is reached in the initial solution. Terminate.");
172 return;
103 } 173 }
104
105 @Override
106 public void initStrategy(ThreadContext context) {
107 this.context = context;
108 this.solutionStore = context.getGlobalContext().getSolutionStore();
109 domain = Domain.valueOf(configuration.domain);
110
111 ViatraQueryEngine engine = context.getQueryEngine();
112// // TODO: visualisation
113 mustMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
114 mayMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
115
116 // manully restict the number of super types of one class
117 this.method.getInvalidWF().forEach(a ->{
118 ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine);
119 mustMatchers.add(matcher);
120 });
121
122 this.method.getUnfinishedWF().forEach(a ->{
123 ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine);
124 mayMatchers.add(matcher);
125 });
126 174
127 175 final Fitness firstFittness = context.calculateFitness();
128 //set up comparator 176
129 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 177 //final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
130 this.comparator = new Comparator<TrajectoryWithFitness>() { 178 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]);
131 @Override 179 TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness);
132 public int compare(TrajectoryWithFitness o1, TrajectoryWithFitness o2) { 180 trajectoiresToExplore.add(currentTrajectoryWithFittness);
133 return objectiveComparatorHelper.compare(o2.fitness, o1.fitness); 181 Object lastState = null;
182
183 //if(configuration)
184 visualiseCurrentState();
185 // the two is the True and False node generated at the beginning of the generation
186 int count = 0;
187 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) {
188
189 if (currentTrajectoryWithFittness == null) {
190 if (trajectoiresToExplore.isEmpty()) {
191 logger.debug("State space is fully traversed.");
192 return;
193 } else {
194 currentTrajectoryWithFittness = selectState();
195 if (logger.isDebugEnabled()) {
196 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray()));
197 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness);
198 }
199 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory);
200
201 // reset the regression for this trajectory
202 metricDistance.getLinearModel().resetRegression(context.getCurrentStateId());
134 } 203 }
135 }; 204 }
136 205
137 this.solutionStoreWithCopy = new SolutionStoreWithCopy(); 206 List<Object> activationIds = selectActivation();
138 this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement); 207 PartialInterpretation model = (PartialInterpretation) context.getModel();
208 System.out.println(model.getNewElements().size());
209 System.out.println("# violations: " + getNumberOfViolations(mayMatchers));
139 210
140 trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11, comparator); 211 Map<Object, Double> valueMap = new HashMap<Object,Double>();
141 stateAndActivations = new HashMap<Object, List<Object>>();
142 metricDistance = new PartialInterpretationMetricDistance(domain);
143 212
144 //set whether allows must violations during the realistic generation 213 //init epsilon and draw
145 allowMustViolation = configuration.allowMustViolations; 214 MetricDistanceGroup heuristics = metricDistance.calculateMetricDistanceKS(model);
146 targetSize = configuration.typeScopes.maxNewElements + 2;
147 }
148 215
149 @Override 216 if(!stateAndActivations.containsKey(context.getCurrentStateId())) {
150 public void explore() { 217 stateAndActivations.put(context.getCurrentStateId(), new ArrayList<Object>());
151 if (!context.checkGlobalConstraints()) {
152 logger.info("Global contraint is not satisifed in the first state. Terminate.");
153 return;
154 }
155 if (configuration.searchSpaceConstraints.maxDepth == 0) {
156 logger.info("Maximal depth is reached in the initial solution. Terminate.");
157 return;
158 } 218 }
159 219
160 final Fitness firstFittness = context.calculateFitness(); 220 // calculate values for epsilon greedy
161 221 double epsilon = 1.0/count;
162 //final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 222 double draw = Math.random();
163 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]); 223 count++;
164 TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness); 224 this.currentNodeTypeDistance = heuristics.getNodeTypeDistance();
165 trajectoiresToExplore.add(currentTrajectoryWithFittness); 225 numNodesToGenerate = model.getMaxNewElements();
166 Object lastState = null; 226 System.out.println("NA distance: " + heuristics.getNADistance());
167 227 System.out.println("MPC distance: " + heuristics.getMPCDistance());
168 //if(configuration) 228 System.out.println("Out degree distance:" + heuristics.getOutDegreeDistance());
169 visualiseCurrentState(); 229 System.out.println("NodeType :" + currentNodeTypeDistance);
170 // the two is the True and False node generated at the beginning of the generation
171 int count = 0;
172 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) {
173 230
174 if (currentTrajectoryWithFittness == null) {
175 if (trajectoiresToExplore.isEmpty()) {
176 logger.debug("State space is fully traversed.");
177 return;
178 } else {
179 currentTrajectoryWithFittness = selectState();
180 if (logger.isDebugEnabled()) {
181 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray()));
182 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness);
183 }
184 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory);
185
186 // reset the regression for this trajectory
187 metricDistance.getLinearModel().resetRegression(context.getCurrentStateId());
188 }
189 }
190
191 List<Object> activationIds = selectActivation();
192 PartialInterpretation model = (PartialInterpretation) context.getModel();
193// System.out.println(model.getNewElements().size());
194// System.out.println("# violations: " + getNumberOfViolations(mayMatchers));
195
196 Map<Object, Double> valueMap = new HashMap<Object,Double>();
197
198 //init epsilon and draw
199 MetricDistanceGroup heuristics = metricDistance.calculateMetricDistanceKS(model);
200 231
201 if(!stateAndActivations.containsKey(context.getCurrentStateId())) { 232 //TODO: the number of activations to be checked should be configurasble
202 stateAndActivations.put(context.getCurrentStateId(), new ArrayList<Object>()); 233 if(activationIds.size() > 50) {
203 } 234 activationIds = activationIds.subList(0, 50);
235 }
236
237 valueMap = sortWithWeight(activationIds);
238 lastState = context.getCurrentStateId();
239 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && activationIds.size() > 0) {
240 final Object nextActivation = drawWithEpsilonProbabilty(activationIds, valueMap, epsilon, draw);
241
242 stateAndActivations.get(context.getCurrentStateId()).add(nextActivation);
243 logger.debug("Executing new activation: " + nextActivation);
244 context.executeAcitvationId(nextActivation);
245 visualiseCurrentState();
246 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness);
247 if(consistencyCheckResult == true) { continue mainLoop; }
204 248
205 // calculate values for epsilon greedy 249// if (context.isCurrentStateAlreadyTraversed()) {
206 double epsilon = 1.0/count; 250// logger.info("The new state is already visited.");
207 double draw = Math.random(); 251// context.backtrack();
208 count++; 252// } else if (!checkGlobalConstraints()) {
209 this.currentNodeTypeDistance = heuristics.getNodeTypeDistance(); 253// logger.debug("Global contraint is not satisifed.");
210 numNodesToGenerate = model.getMaxNewElements(); 254// context.backtrack();
211// System.out.println("NA distance: " + heuristics.getNADistance()); 255// }
212// System.out.println("MPC distance: " + heuristics.getMPCDistance());
213// System.out.println("Out degree distance:" + heuristics.getOutDegreeDistance());
214// System.out.println("NodeType :" + currentNodeTypeDistance);
215
216
217 //TODO: the number of activations to be checked should be configurasble
218 if(activationIds.size() > 50) {
219 activationIds = activationIds.subList(0, 50);
220 }
221 256
222 valueMap = sortWithWeight(activationIds); 257 int currentSize = model.getNewElements().size();
223 lastState = context.getCurrentStateId(); 258 int targetDiff = targetSize - currentSize;
224 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && activationIds.size() > 0) { 259 boolean shouldFinish = currentSize >= targetSize;
225 final Object nextActivation = drawWithEpsilonProbabilty(activationIds, valueMap, epsilon, draw); 260
226 261 // does not allow must violations
227 stateAndActivations.get(context.getCurrentStateId()).add(nextActivation); 262 if((getNumberOfViolations(mustMatchers) > 0|| getNumberOfViolations(mayMatchers) > targetDiff) && !allowMustViolation && !shouldFinish) {
228 logger.debug("Executing new activation: " + nextActivation); 263 context.backtrack();
229 context.executeAcitvationId(nextActivation); 264 }else {
230 visualiseCurrentState(); 265 final Fitness nextFitness = context.calculateFitness();
231 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness);
232 if(consistencyCheckResult == true) { continue mainLoop; }
233
234 int currentSize = model.getNewElements().size();
235 int targetDiff = targetSize - currentSize;
236 boolean shouldFinish = currentSize >= targetSize;
237 266
238 // does not allow must violations 267 // the only hard objectives are configured in the config file
239 if((getNumberOfViolations(mustMatchers) > 0|| getNumberOfViolations(mayMatchers) > targetDiff) && !allowMustViolation && !shouldFinish) { 268 checkForSolution(nextFitness);
269
270 if (context.getDepth() > configuration.searchSpaceConstraints.maxDepth) {
271 logger.debug("Reached max depth.");
240 context.backtrack(); 272 context.backtrack();
241 }else { 273 continue;
242 final Fitness nextFitness = context.calculateFitness();
243
244 // the only hard objectives are configured in the config file
245 checkForSolution(nextFitness);
246
247 if (context.getDepth() > configuration.searchSpaceConstraints.maxDepth) {
248 logger.debug("Reached max depth.");
249 context.backtrack();
250 continue;
251 }
252
253 //Record value for current trajectory
254 TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness(
255 context.getTrajectory().toArray(), nextFitness);
256 int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size();
257 int violation = getNumberOfViolations(mayMatchers);
258 double currentValue = calculateCurrentStateValue(nodeSize, violation);
259 metricDistance.getLinearModel().feedData(context.getCurrentStateId(), metricDistance.calculateFeature(nodeSize, violation), currentValue, lastState);
260 trajectoiresToExplore.add(nextTrajectoryWithFittness);
261 currentStateValue = currentValue;
262 //Currently, just go to the next state without considering the value of trajectory
263 currentTrajectoryWithFittness = nextTrajectoryWithFittness;
264 continue mainLoop;
265
266 } 274 }
275
276 //Record value for current trajectory
277 TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness(
278 context.getTrajectory().toArray(), nextFitness);
279 int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size();
280 int violation = getNumberOfViolations(mayMatchers);
281 double currentValue = calculateCurrentStateValue(nodeSize, violation);
282 metricDistance.getLinearModel().feedData(context.getCurrentStateId(), metricDistance.calculateFeature(nodeSize, violation), currentValue, lastState);
283 trajectoiresToExplore.add(nextTrajectoryWithFittness);
284 currentStateValue = currentValue;
285 //Currently, just go to the next state without considering the value of trajectory
286 currentTrajectoryWithFittness = nextTrajectoryWithFittness;
287 continue mainLoop;
288
267 } 289 }
268 logger.debug("State is fully traversed.");
269 trajectoiresToExplore.remove(currentTrajectoryWithFittness);
270 currentTrajectoryWithFittness = null;
271 context.backtrack();
272 } 290 }
273 logger.info("Interrupted."); 291 logger.debug("State is fully traversed.");
292 trajectoiresToExplore.remove(currentTrajectoryWithFittness);
293 currentTrajectoryWithFittness = null;
294 context.backtrack();
274 } 295 }
296 logger.info("Interrupted.");
297 }
275 298
276 /** 299 private boolean checkGlobalConstraints() {
277 * 300 long start = System.nanoTime();
278 * @param activationIds 301 boolean result = context.checkGlobalConstraints();
279 * @return: activation to value map 302 globalConstraintEvaluationTime += System.nanoTime() - start;
280 */ 303 return result;
281 private Map<Object, Double> sortWithWeight(List<Object> activationIds){ 304 }
282 Map<Object, Double> valueMap = new HashMap<Object, Double>(); 305
283 Object currentId = context.getCurrentStateId(); 306 private Fitness calculateFitness() {
284 // check for next states 307 long start = System.nanoTime();
285 for(Object id : activationIds) { 308 Fitness fitness = context.calculateFitness();
286 context.executeAcitvationId(id); 309 fitnessCalculationTime += System.nanoTime() - start;
287 int violation = getNumberOfViolations(mayMatchers); 310 return fitness;
311 }
312
313 /**
314 *
315 * @param activationIds
316 * @return: activation to value map
317 */
318 private Map<Object, Double> sortWithWeight(List<Object> activationIds){
319 Map<Object, Double> valueMap = new HashMap<Object, Double>();
320 Object currentId = context.getCurrentStateId();
321 // check for next states
322 for(Object id : activationIds) {
323 context.executeAcitvationId(id);
324 int violation = getNumberOfViolations(mayMatchers);
288 325
289 if(!allowMustViolation && getNumberOfViolations(mustMatchers) > 0) { 326 if(!allowMustViolation && getNumberOfViolations(mustMatchers) > 0) {
290 valueMap.put(id, Double.MAX_VALUE); 327 valueMap.put(id, Double.MAX_VALUE);
291 stateAndActivations.get(currentId).add(id); 328 stateAndActivations.get(currentId).add(id);
292 }else { 329 }else {
293 valueMap.put(id, calculateFutureStateValue(violation)); 330 valueMap.put(id, calculateFutureStateValue(violation));
294 }
295
296
297
298 context.backtrack();
299 } 331 }
332
333
300 334
301 //remove all the elements having large distance 335 context.backtrack();
302 Collections.sort(activationIds, Comparator.comparing(li -> valueMap.get(li)));
303 return valueMap;
304 } 336 }
305 337
306 private double calculateFutureStateValue(int violation) { 338 //remove all the elements having large distance
307 long start = System.nanoTime(); 339 Collections.sort(activationIds, Comparator.comparing(li -> valueMap.get(li)));
308 int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size(); 340 return valueMap;
309 double currentValue = calculateCurrentStateValue(nodeSize,violation); 341 }
310 double[] toPredict = metricDistance.calculateFeature(100, violation); 342
311 if(Math.abs(currentValue - currentStateValue) < 0.001) { 343 private double calculateFutureStateValue(int violation) {
312 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); 344 long start = System.nanoTime();
313 return Double.MAX_VALUE; 345 int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size();
314 } 346 double currentValue = calculateCurrentStateValue(nodeSize,violation);
315 try { 347 double[] toPredict = metricDistance.calculateFeature(100, violation);
316 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); 348 if(Math.abs(currentValue - currentStateValue) < 0.001) {
317 return metricDistance.getLinearModel().getPredictionForNextDataSample(metricDistance.calculateFeature(nodeSize, violation), currentValue, toPredict); 349 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start);
318 }catch(IllegalArgumentException e) { 350 return Double.MAX_VALUE;
319 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); 351 }
320 return currentValue; 352 try {
321 } 353 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start);
322 354 return metricDistance.getLinearModel().getPredictionForNextDataSample(metricDistance.calculateFeature(nodeSize, violation), currentValue, toPredict);
355 }catch(IllegalArgumentException e) {
356 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start);
357 return currentValue;
323 } 358 }
324 private double calculateCurrentStateValue(int factor, int violation) {
325 PartialInterpretation model = (PartialInterpretation) context.getModel();
326 MetricDistanceGroup g = metricDistance.calculateMetricDistanceKS(model);
327 if(configuration.realisticGuidance == RealisticGuidance.MPC) {
328 return g.getMPCDistance();
329 }else if(configuration.realisticGuidance == RealisticGuidance.NodeActivity) {
330 return g.getNADistance();
331 }else if(configuration.realisticGuidance == RealisticGuidance.OutDegree) {
332 return g.getOutDegreeDistance();
333 }else if(configuration.realisticGuidance == RealisticGuidance.NodeType) {
334 return g.getNodeTypeDistance();
335 }else if(configuration.realisticGuidance == RealisticGuidance.Composite) {
336 double consistenceWeights = 5 * factor / (configuration.typeScopes.maxNewElements + 2) * (1- 1.0/(1+violation));
337 if(domain == Domain.Yakindumm) {
338 double unfinishFactor = 50 * (1 - (double)factor / targetSize);
339 double nodeTypeFactor = g.getNodeTypeDistance();
340 double normalFactor = 5;
341 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
342 nodeTypeFactor = 0;
343 normalFactor = 100;
344 unfinishFactor = 0;
345 }
346
347 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
348 }else if (domain == Domain.Ecore) {
349 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
350 double nodeTypeFactor = g.getNodeTypeDistance();
351 double normalFactor = 5;
352 if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) {
353 nodeTypeFactor = 0;
354 normalFactor = 100;
355 unfinishFactor *= 0.5;
356 }
357
358 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
359 }else {
360 double unfinishFactor = context.calculateFitness().get("CompositeUnfinishednessObjective");
361 double nodeTypeFactor = g.getNodeTypeDistance();
362 double normalFactor = 5;
363 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
364 nodeTypeFactor = 0;
365 normalFactor = 100;
366 //unfinishFactor *= 0.5;
367 }
368
369 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + 2*g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
370 }
371 359
372 }else if(configuration.realisticGuidance == RealisticGuidance.Composite_Without_Violations) { 360 }
373 if(domain == Domain.Yakindumm) { 361 private double calculateCurrentStateValue(int factor, int violation) {
374 double unfinishFactor = 50 * (1 - (double)factor / targetSize); 362 PartialInterpretation model = (PartialInterpretation) context.getModel();
375 double nodeTypeFactor = g.getNodeTypeDistance(); 363 MetricDistanceGroup g = metricDistance.calculateMetricDistanceKS(model);
376 double normalFactor = 5; 364 if(configuration.realisticGuidance == RealisticGuidance.MPC) {
377 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) { 365 return g.getMPCDistance();
378 nodeTypeFactor = 0; 366 }else if(configuration.realisticGuidance == RealisticGuidance.NodeActivity) {
379 normalFactor = 100; 367 return g.getNADistance();
380 unfinishFactor = 0; 368 }else if(configuration.realisticGuidance == RealisticGuidance.OutDegree) {
381 } 369 return g.getOutDegreeDistance();
382 370 }else if(configuration.realisticGuidance == RealisticGuidance.NodeType) {
383 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor; 371 return g.getNodeTypeDistance();
384 }else if (domain == Domain.Github) { 372 }else if(configuration.realisticGuidance == RealisticGuidance.Composite) {
385 double unfinishFactor = 100 * (1 - (double)factor / targetSize); 373 double consistenceWeights = 5 * factor / (configuration.typeScopes.maxNewElements + 2) * (1- 1.0/(1+violation));
386 double nodeTypeFactor = g.getNodeTypeDistance(); 374 if(domain == Domain.Yakindumm) {
387 double normalFactor = 5; 375 double unfinishFactor = 50 * (1 - (double)factor / targetSize);
388 if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) { 376 double nodeTypeFactor = g.getNodeTypeDistance();
389 nodeTypeFactor = 0; 377 double normalFactor = 5;
390 normalFactor = 100; 378 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
391 unfinishFactor *= 0.5; 379 nodeTypeFactor = 0;
392 } 380 normalFactor = 100;
393 381 unfinishFactor = 0;
394 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
395 } else {
396 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
397 double nodeTypeFactor = g.getNodeTypeDistance();
398 double normalFactor = 5;
399 if(currentNodeTypeDistance <= 0.20 || numNodesToGenerate == 1) {
400 nodeTypeFactor = 0;
401 normalFactor = 100;
402 unfinishFactor *= 0.5;
403 }
404
405 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
406 } 382 }
383
384 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
385 }else if (domain == Domain.Ecore) {
386 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
387 double nodeTypeFactor = g.getNodeTypeDistance();
388 double normalFactor = 5;
389 if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) {
390 nodeTypeFactor = 0;
391 normalFactor = 100;
392 unfinishFactor *= 0.5;
393 }
394
395 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
407 }else { 396 }else {
408 return violation; 397 double unfinishFactor = context.calculateFitness().get("CompositeUnfinishednessObjective");
409 } 398 double nodeTypeFactor = g.getNodeTypeDistance();
410 } 399 double normalFactor = 5;
411 400 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
412 private int getNumberOfViolations(Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers) { 401 nodeTypeFactor = 0;
413 int violations = matchers.stream().mapToInt(m -> m.countMatches()).sum(); 402 normalFactor = 100;
414 403 //unfinishFactor *= 0.5;
415 return violations; 404 }
416 } 405
417 406 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + 2*g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
418 // Modified epsilon greedy choose for action based on value function
419 // with probability epsilon, choose the state with probability based on the weight
420 // with probability 1 - epsilon, choose the best state
421 // epsilon should decay w.r.t. time
422 private Object drawWithEpsilonProbabilty(List<Object> activationIds, Map<Object, Double> valueMap, double epsilon, double currentDraw) {
423 if(activationIds.size() <= 0) {
424 return null;
425 } 407 }
426 408
427 // if epsilon is smaller than current draw, return greedy choice 409 }else if(configuration.realisticGuidance == RealisticGuidance.Composite_Without_Violations) {
428 if(epsilon < currentDraw) { 410 if(domain == Domain.Yakindumm) {
429 return activationIds.remove(0); 411 double unfinishFactor = 50 * (1 - (double)factor / targetSize);
430 }else { 412 double nodeTypeFactor = g.getNodeTypeDistance();
431 //else return draw with probability of the weights 413 double normalFactor = 5;
432 //find the sum of all 1-weights: the smaller the better 414 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
433 double sum = valueMap.values().stream().mapToDouble(d->1).sum(); 415 nodeTypeFactor = 0;
434 double rand = Math.random() * sum; 416 normalFactor = 100;
435 double iterator = 0.0; 417 unfinishFactor = 0;
436 Object idToReturn = null; 418 }
437 419
438 // draw an item with probability 420 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
439 for(Object o : valueMap.keySet()) { 421 }else if (domain == Domain.Github) {
440 iterator += (1); 422 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
441 if(rand < iterator) { 423 double nodeTypeFactor = g.getNodeTypeDistance();
442 idToReturn = o; 424 double normalFactor = 5;
443 break; 425 if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) {
444 } 426 nodeTypeFactor = 0;
427 normalFactor = 100;
428 unfinishFactor *= 0.5;
429 }
430
431 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
432 } else {
433 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
434 double nodeTypeFactor = g.getNodeTypeDistance();
435 double normalFactor = 5;
436 if(currentNodeTypeDistance <= 0.20 || numNodesToGenerate == 1) {
437 nodeTypeFactor = 0;
438 normalFactor = 100;
439 unfinishFactor *= 0.5;
445 } 440 }
446 441
447 //delete the item from the list 442 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
448 activationIds.remove(idToReturn);
449 valueMap.remove(idToReturn);
450 return idToReturn;
451 } 443 }
444 }else {
445 return violation;
452 } 446 }
447 }
448
449 private int getNumberOfViolations(Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers) {
450 int violations = matchers.stream().mapToInt(m -> m.countMatches()).sum();
453 451
454 private List<Object> selectActivation() { 452 return violations;
455 List<Object> activationIds; 453 }
456 try { 454
457 activationIds = new ArrayList<Object>(context.getCurrentActivationIds()); 455 // Modified epsilon greedy choose for action based on value function
458 if(stateAndActivations.containsKey(context.getCurrentStateId())) { 456 // with probability epsilon, choose the state with probability based on the weight
459 activationIds.removeAll(stateAndActivations.get(context.getCurrentStateId())); 457 // with probability 1 - epsilon, choose the best state
458 // epsilon should decay w.r.t. time
459 private Object drawWithEpsilonProbabilty(List<Object> activationIds, Map<Object, Double> valueMap, double epsilon, double currentDraw) {
460 if(activationIds.size() <= 0) {
461 return null;
462 }
463
464 // if epsilon is smaller than current draw, return greedy choice
465 if(epsilon < currentDraw) {
466 return activationIds.remove(0);
467 }else {
468 //else return draw with probability of the weights
469 //find the sum of all 1-weights: the smaller the better
470 double sum = valueMap.values().stream().mapToDouble(d->1).sum();
471 double rand = Math.random() * sum;
472 double iterator = 0.0;
473 Object idToReturn = null;
474
475 // draw an item with probability
476 for(Object o : valueMap.keySet()) {
477 iterator += (1);
478 if(rand < iterator) {
479 idToReturn = o;
480 break;
460 } 481 }
461 Collections.shuffle(activationIds);
462 } catch (NullPointerException e) {
463 numberOfStatecoderFail++;
464 activationIds = Collections.emptyList();
465 } 482 }
466 return activationIds; 483
484 //delete the item from the list
485 activationIds.remove(idToReturn);
486 valueMap.remove(idToReturn);
487 return idToReturn;
467 } 488 }
489 }
490
491 private List<Object> selectActivation() {
492 List<Object> activationIds;
493 try {
494 activationIds = this.activationSelector.randomizeActivationIDs(context.getUntraversedActivationIds());
495 } catch (NullPointerException e) {
496 numberOfStatecoderFail++;
497 activationIds = Collections.emptyList();
498 }
499 return activationIds;
500 }
468 501
469 private void checkForSolution(final Fitness fittness) { 502 private void checkForSolution(final Fitness fittness) {
470 if (fittness.isSatisifiesHardObjectives()) { 503 if (fittness.isSatisifiesHardObjectives()) {
471 logger.debug("Solution Found!!"); 504 logger.debug("Solution Found!!");
472 logger.debug("# violations: " + (getNumberOfViolations(mustMatchers))); 505 logger.debug("# violations: " + (getNumberOfViolations(mustMatchers)));
473 if (solutionStoreWithDiversityDescriptor.isDifferent(context)) { 506 if (solutionStoreWithDiversityDescriptor.isDifferent(context)) {
474 solutionStoreWithCopy.newSolution(context); 507 solutionStoreWithCopy.newSolution(context);
475 solutionStoreWithDiversityDescriptor.newSolution(context); 508 solutionStoreWithDiversityDescriptor.newSolution(context);
476 solutionStore.newSolution(context); 509 solutionStore.newSolution(context);
477 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolution); 510 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolutions);
478 511
479 logger.debug("Found a solution."); 512 logger.debug("Found a solution.");
480 }
481 } 513 }
482 } 514 }
515 }
516
517 public List<String> times = new LinkedList<String>();
518 private void saveTimes() {
519 long forwardTime = context.getDesignSpaceManager().getForwardTime()/1000000;
520 long backtrackingTime = context.getDesignSpaceManager().getBacktrackingTime()/1000000;
521 long statecoderTime = ((NeighbourhoodBasedPartialInterpretationStateCoder)this.context.getStateCoder()).getStatecoderRuntime()/1000000;
522 long solutionCopy = solutionStoreWithCopy.getSumRuntime()/1000000;
523 long activationSelection = this.activationSelector.getRuntime()/1000000;
524// long numericalSolverSumTime = this.numericSolver.getRuntime()/1000000;
525// long numericalSolverProblemForming = this.numericSolver.getSolverSolvingProblem()/1000000;
526// long numericalSolverSolving = this.numericSolver.getSolverSolvingProblem()/1000000;
527// long numericalSolverInterpreting = this.numericSolver.getSolverSolution()/1000000;
528 long metricCalculationTime = this.method.getStatistics().metricCalculationTime / 1000000;
529 this.times.add(
530 "(TransformationExecutionTime"+method.getStatistics().transformationExecutionTime/1000000+
531 "|ForwardTime:"+forwardTime+
532 "|Backtrackingtime:"+backtrackingTime+
533 "|StateCoderTime:"+statecoderTime+
534 "|SolutionCopyTime:"+solutionCopy+
535 "|ActivationSelectionTime:"+activationSelection+
536 //"|NumericalSolverSumTime:"+numericalSolverSumTime+
537 //"|NumericalSolverProblemFormingTime:"+numericalSolverProblemForming+
538 //"|NumericalSolverSolvingTime:"+numericalSolverSolving+
539 //"|NumericalSolverInterpretingSolution:"+numericalSolverInterpreting+
540 "|MetricCalculationTime:"+metricCalculationTime + ")"
541 );
542
543 }
483 544
484 @Override 545 @Override
485 public void interruptStrategy() { 546 public void interruptStrategy() {
486 isInterrupted = true; 547 isInterrupted = true;
487 } 548 }
488 549
489 550
490 private TrajectoryWithFitness selectState() { 551 private TrajectoryWithFitness selectState() {
491 int randomNumber = random.nextInt(configuration.randomBacktrackChance); 552 int randomNumber = random.nextInt(configuration.randomBacktrackChance);
492 if (randomNumber == 0) { 553 if (randomNumber == 0) {
493 int elements = trajectoiresToExplore.size(); 554 int elements = trajectoiresToExplore.size();
494 int randomElementIndex = random.nextInt(elements); 555 int randomElementIndex = random.nextInt(elements);
495 logger.debug("Randomly backtract to the " + randomElementIndex + " best solution..."); 556 logger.debug("Randomly backtract to the " + randomElementIndex + " best solution...");
496 Iterator<TrajectoryWithFitness> iterator = trajectoiresToExplore.iterator(); 557 Iterator<TrajectoryWithFitness> iterator = trajectoiresToExplore.iterator();
497 while (randomElementIndex != 0) { 558 while (randomElementIndex != 0) {
498 iterator.next(); 559 iterator.next();
499 randomElementIndex--; 560 randomElementIndex--;
500 } 561 }
501 TrajectoryWithFitness res = iterator.next(); 562 TrajectoryWithFitness res = iterator.next();
502 if (res == null) { 563 if (res == null) {
503 return trajectoiresToExplore.element();
504 } else {
505 return res;
506 }
507 } else {
508 return trajectoiresToExplore.element(); 564 return trajectoiresToExplore.element();
565 } else {
566 return res;
509 } 567 }
510 } 568 } else {
511 569 return trajectoiresToExplore.element();
570 }
571 }
572
512// private void logCurrentStateMetric() { 573// private void logCurrentStateMetric() {
513// if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) { 574// if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) {
514// return; 575// return;
@@ -518,77 +579,80 @@ public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements
518// PartialInterpretationMetric.calculateMetric(interpretation, "debug/metric/" + context.getModel().hashCode(), context.getCurrentStateId().toString()); 579// PartialInterpretationMetric.calculateMetric(interpretation, "debug/metric/" + context.getModel().hashCode(), context.getCurrentStateId().toString());
519// } 580// }
520 581
521 public void visualiseCurrentState() { 582 public void visualiseCurrentState() {
522 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugCongiguration.partialInterpretatioVisualiser; 583 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugConfiguration.partialInterpretatioVisualiser;
523 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) { 584 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) {
524 PartialInterpretation p = (PartialInterpretation) (context.getModel()); 585 PartialInterpretation p = (PartialInterpretation) (context.getModel());
525 int id = ++numberOfPrintedModel; 586 int id = ++numberOfPrintedModel;
526 if (id % configuration.debugCongiguration.partalInterpretationVisualisationFrequency == 0) { 587 if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) {
527 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); 588 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p);
528 visualisation.writeToFile(workspace, String.format("state%09d.png", id)); 589 logger.debug("Visualizing state: " + id + " (" + context.getDesignSpaceManager().getCurrentState() + ")");
529 } 590 String name = String.format("state%09d", id);
591 visualisation.writeToFile(workspace, name + ".png");
592 workspace.writeModel((EObject) context.getModel(), name + ".xmi");
530 } 593 }
531 } 594 }
595 }
532 596
533 protected boolean checkConsistency(TrajectoryWithFitness t) { 597 protected boolean checkConsistency(TrajectoryWithFitness t) {
534 LogicReasoner internalIncosnsitencyDetector = configuration.internalConsistencyCheckerConfiguration.internalIncosnsitencyDetector; 598 LogicReasoner internalIncosnsitencyDetector = configuration.internalConsistencyCheckerConfiguration.internalIncosnsitencyDetector;
535 if (internalIncosnsitencyDetector!= null) { 599 if (internalIncosnsitencyDetector!= null) {
536 int id = ++numberOfSolverCalls; 600 int id = ++numberOfSolverCalls;
537 if (id % configuration.internalConsistencyCheckerConfiguration.incternalConsistencyCheckingFrequency == 0) { 601 if (id % configuration.internalConsistencyCheckerConfiguration.incternalConsistencyCheckingFrequency == 0) {
538 try { 602 try {
539 PartialInterpretation interpretation = (PartialInterpretation) (context.getModel()); 603 PartialInterpretation interpretation = (PartialInterpretation) (context.getModel());
540 PartialInterpretation copied = EcoreUtil.copy(interpretation); 604 PartialInterpretation copied = EcoreUtil.copy(interpretation);
541 this.partialInterpretation2Logic.transformPartialIntepretation2Logic(copied.getProblem(), copied); 605 this.partialInterpretation2Logic.transformPartialIntepretation2Logic(copied.getProblem(), copied);
542 LogicProblem newProblem = copied.getProblem(); 606 LogicProblem newProblem = copied.getProblem();
543 607
544 this.configuration.typeScopes.maxNewElements = interpretation.getMaxNewElements(); 608 this.configuration.typeScopes.maxNewElements = interpretation.getMaxNewElements();
545 this.configuration.typeScopes.minNewElements = interpretation.getMinNewElements(); 609 this.configuration.typeScopes.minNewElements = interpretation.getMinNewElements();
546 LogicResult result = internalIncosnsitencyDetector.solve(newProblem, configuration, workspace); 610 LogicResult result = internalIncosnsitencyDetector.solve(newProblem, configuration, workspace);
547 if (result instanceof InconsistencyResult) { 611 if (result instanceof InconsistencyResult) {
548 logger.debug("Solver found an Inconsistency!"); 612 logger.debug("Solver found an Inconsistency!");
549 removeSubtreeFromQueue(t); 613 removeSubtreeFromQueue(t);
550 return true; 614 return true;
551 } else if (result instanceof ModelResult) { 615 } else if (result instanceof ModelResult) {
552 logger.debug("Solver found a model!"); 616 logger.debug("Solver found a model!");
553 solutionStore.newSolution(context); 617 solutionStore.newSolution(context);
554 618
555 this.modelResultByInternalSolver = (ModelResult) result; 619 this.modelResultByInternalSolver = (ModelResult) result;
556 return true; 620 return true;
557 } else { 621 } else {
558 logger.debug("Failed consistency check."); 622 logger.debug("Failed consistency check.");
559 return false;
560 }
561 } catch (Exception e) {
562 logger.debug("Problem with internal consistency checking: "+e.getMessage());
563 e.printStackTrace();
564 return false; 623 return false;
565 } 624 }
625 } catch (Exception e) {
626 logger.debug("Problem with internal consistency checking: "+e.getMessage());
627 e.printStackTrace();
628 return false;
566 } 629 }
567
568 } 630 }
569 return false;
570 }
571 631
572 protected void removeSubtreeFromQueue(TrajectoryWithFitness t) {
573 PriorityQueue<TrajectoryWithFitness> previous = this.trajectoiresToExplore;
574 this.trajectoiresToExplore = new PriorityQueue<>(this.comparator);
575 for (TrajectoryWithFitness trajectoryWithFitness : previous) {
576 if (!containsAsSubstring(trajectoryWithFitness.trajectory, t.trajectory)) {
577 this.trajectoiresToExplore.add(trajectoryWithFitness);
578 } else {
579 logger.debug("State has been excluded due to inherent inconsistency");
580 }
581 }
582 } 632 }
633 return false;
634 }
583 635
584 private boolean containsAsSubstring(Object[] full, Object[] substring) { 636 protected void removeSubtreeFromQueue(TrajectoryWithFitness t) {
585 if (substring.length > full.length) { 637 PriorityQueue<TrajectoryWithFitness> previous = this.trajectoiresToExplore;
586 return false; 638 this.trajectoiresToExplore = new PriorityQueue<>(this.comparator);
587 } else if (substring.length == full.length) { 639 for (TrajectoryWithFitness trajectoryWithFitness : previous) {
588 return Arrays.equals(full, substring); 640 if (!containsAsSubstring(trajectoryWithFitness.trajectory, t.trajectory)) {
641 this.trajectoiresToExplore.add(trajectoryWithFitness);
589 } else { 642 } else {
590 Object[] part = Arrays.copyOfRange(full, 0, substring.length); 643 logger.debug("State has been excluded due to inherent inconsistency");
591 return Arrays.equals(part, substring);
592 } 644 }
593 } 645 }
646 }
647
648 private boolean containsAsSubstring(Object[] full, Object[] substring) {
649 if (substring.length > full.length) {
650 return false;
651 } else if (substring.length == full.length) {
652 return Arrays.equals(full, substring);
653 } else {
654 Object[] part = Arrays.copyOfRange(full, 0, substring.length);
655 return Arrays.equals(part, substring);
656 }
657 }
594} 658}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/InconsistentScopeGlobalConstraint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/InconsistentScopeGlobalConstraint.xtend
new file mode 100644
index 00000000..2e039ca2
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/InconsistentScopeGlobalConstraint.xtend
@@ -0,0 +1,25 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import org.eclipse.viatra.dse.objectives.IGlobalConstraint
4import org.eclipse.viatra.dse.base.ThreadContext
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
6
7class InconsistentScopeGlobalConstraint implements IGlobalConstraint {
8
9 override init(ThreadContext context) {
10 // Nothing to initialize.
11 }
12
13 override createNew() {
14 this
15 }
16
17 override getName() {
18 class.name
19 }
20
21 override checkGlobalConstraint(ThreadContext context) {
22 val partialModel = context.model as PartialInterpretation
23 partialModel.minNewElements <= partialModel.maxNewElements || partialModel.maxNewElements < 0
24 }
25}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/LoggerSolutionFoundHandler.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/LoggerSolutionFoundHandler.xtend
new file mode 100644
index 00000000..39ef5f9a
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/LoggerSolutionFoundHandler.xtend
@@ -0,0 +1,24 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration
4import org.apache.log4j.Logger
5import org.eclipse.viatra.dse.api.SolutionTrajectory
6import org.eclipse.viatra.dse.base.ThreadContext
7import org.eclipse.viatra.dse.solutionstore.ISolutionFoundHandler
8import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
9
10@FinalFieldsConstructor
11class LoggerSolutionFoundHandler implements ISolutionFoundHandler {
12 val ViatraReasonerConfiguration configuration
13
14 val logger = Logger.getLogger(SolutionCopier)
15
16 override solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
17 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolutions)
18 logger.debug("Found a solution.")
19 }
20
21 override solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
22 // We are not interested in invalid solutions, ignore.
23 }
24}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend
index 9fc6853c..27208cf4 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend
@@ -1,99 +1,123 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import com.google.common.collect.ImmutableList
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration
6import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.IThreeValuedObjective
3import java.util.Comparator 7import java.util.Comparator
4import java.util.List 8import java.util.List
5import org.eclipse.viatra.dse.base.ThreadContext 9import org.eclipse.viatra.dse.base.ThreadContext
6import org.eclipse.viatra.dse.objectives.Comparators 10import org.eclipse.viatra.dse.objectives.Comparators
7import org.eclipse.viatra.dse.objectives.IObjective 11import org.eclipse.viatra.dse.objectives.IObjective
8import org.eclipse.viatra.dse.objectives.impl.BaseObjective 12import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PrimitiveElement
9 13
10//class ViatraReasonerNumbers { 14class ModelGenerationCompositeObjective implements IThreeValuedObjective {
11// public static val scopePriority = 2 15 val IObjective scopeObjective
12// public static val unfinishedMultiplicityPriority = 2
13// public static val unifinshedWFPriority = 2
14// //public static val complexityPriority = 4
15//
16// public static val scopeWeigth = 1.0
17// public static val unfinishedMultiplicityWeigth = 1.5
18// public static val unfinishedWFWeigth = 1.5
19// //public static val complexityWeigth = 0.1
20//
21// public static val useCompositeObjective = true
22// public static val compositePriority = 2
23//}
24
25class ModelGenerationCompositeObjective implements IObjective{
26 val ScopeObjective scopeObjective
27 val List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives 16 val List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives
28 val UnfinishedWFObjective unfinishedWFObjective 17 val UnfinishedWFObjective unfinishedWFObjective
29 var boolean isWFOptional = false; 18 var PartialInterpretation model = null
19 val int scopeWeight
20 val int conaintmentWeight
21 val int nonContainmentWeight
22 val int unfinishedWFWeight
30 23
31 public new( 24 new(
32 ScopeObjective scopeObjective, 25 IObjective scopeObjective,
26 List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives,
27 UnfinishedWFObjective unfinishedWFObjective,
28 ViatraReasonerConfiguration configuration)
29 {
30 this(
31 scopeObjective, unfinishedMultiplicityObjectives, unfinishedWFObjective,
32 configuration.scopeWeight, configuration.conaintmentWeight, configuration.nonContainmentWeight,
33 configuration.unfinishedWFWeight
34 )
35 }
36
37 new(
38 IObjective scopeObjective,
33 List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives, 39 List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives,
34 UnfinishedWFObjective unfinishedWFObjective, 40 UnfinishedWFObjective unfinishedWFObjective,
35 boolean isWFOptional) 41 int scopeWeight, int conaintmentWeight, int nonContainmentWeight, int unfinishedWFWeight)
36 { 42 {
37 this.scopeObjective = scopeObjective 43 this.scopeObjective = scopeObjective
38 this.unfinishedMultiplicityObjectives = unfinishedMultiplicityObjectives 44 this.unfinishedMultiplicityObjectives = unfinishedMultiplicityObjectives
39 this.unfinishedWFObjective = unfinishedWFObjective 45 this.unfinishedWFObjective = unfinishedWFObjective
40 this.isWFOptional = isWFOptional; 46
41 } 47 this.scopeWeight = scopeWeight
42 48 this.conaintmentWeight = conaintmentWeight
43 def getIsWFOptional(){ 49 this.nonContainmentWeight = nonContainmentWeight
44 return this.isWFOptional; 50 this.unfinishedWFWeight = unfinishedWFWeight
45 } 51 }
46 52
47 override init(ThreadContext context) { 53 override init(ThreadContext context) {
54 model = context.model as PartialInterpretation
48 this.scopeObjective.init(context) 55 this.scopeObjective.init(context)
49 this.unfinishedMultiplicityObjectives.forEach[it.init(context)] 56 this.unfinishedMultiplicityObjectives.forEach[it.init(context)]
50 this.unfinishedWFObjective.init(context) 57 this.unfinishedWFObjective.init(context)
51 } 58 }
52 59
53 override createNew() { 60 override createNew() {
54 return new ModelGenerationCompositeObjective( 61 return new ModelGenerationCompositeObjective(
55 this.scopeObjective, this.unfinishedMultiplicityObjectives, this.unfinishedWFObjective, this.isWFOptional) 62 scopeObjective.createNew,
63 ImmutableList.copyOf(unfinishedMultiplicityObjectives.map[createNew as UnfinishedMultiplicityObjective]),
64 unfinishedWFObjective.createNew as UnfinishedWFObjective,
65 scopeWeight, conaintmentWeight, nonContainmentWeight, unfinishedWFWeight
66 )
56 } 67 }
57 68
58 override getComparator() { Comparators.LOWER_IS_BETTER } 69 override getComparator() { Comparators.LOWER_IS_BETTER }
70
59 override getFitness(ThreadContext context) { 71 override getFitness(ThreadContext context) {
60 var sum = 0.0 72
61 val scopeFitnes = scopeObjective.getFitness(context) 73 val scopeFitnes = scopeObjective.getFitness(context)
62 //val unfinishedMultiplicitiesFitneses = unfinishedMultiplicityObjectives.map[x|x.getFitness(context)] 74 val unfinishedWFsFitness = unfinishedWFObjective.getFitness(context)
63 75
64 sum+=scopeFitnes 76 var containmentMultiplicity = 0.0
65 var multiplicity = 0.0 77 var nonContainmentMultiplicity = 0.0
66 for(multiplicityObjective : unfinishedMultiplicityObjectives) { 78 for(multiplicityObjective : unfinishedMultiplicityObjectives) {
67 multiplicity+=multiplicityObjective.getFitness(context)//*0.5 79 val multiplicity = multiplicityObjective.getFitness(context)
80// println(multiplicityObjective.name + "=" + multiplicity)
81 if(multiplicityObjective.containment) {
82 containmentMultiplicity+=multiplicity
83 } else {
84 nonContainmentMultiplicity+=multiplicity
85 }
86
68 } 87 }
69 sum+=multiplicity
70 88
71 // the WF can be optional when generating realistic models 89 var sum = 0.0
72 if(!isWFOptional){ 90 sum += scopeFitnes*scopeWeight
73 val unfinishedWFsFitness = unfinishedWFObjective.getFitness(context) 91 sum += containmentMultiplicity*conaintmentWeight
74 sum += unfinishedWFsFitness//*0.5 92 sum += nonContainmentMultiplicity*nonContainmentWeight
75 } 93 sum += unfinishedWFsFitness*unfinishedWFWeight
76 94
77 //println('''Sum=«sum»|Scope=«scopeFitnes»|Multiplicity=«multiplicity»|WFs=«unfinishedWFsFitness»''') 95// println('''scope=«scopeFitnes», containment=«containmentMultiplicity», nonContainment=«nonContainmentMultiplicity», wf=«unfinishedWFsFitness», sum=«sum»''')
78 96
79 return sum 97 return sum
80 } 98 }
81 99
82 override getLevel() { 2 } 100 override getWorstPossibleFitness(ThreadContext threadContext) {
83 override getName() { "CompositeUnfinishednessObjective"} 101 Double.POSITIVE_INFINITY
84 def getObjective(){
85 return this.unfinishedMultiplicityObjectives;
86 } 102 }
87 103
104 override getBestPossibleFitness(ThreadContext threadContext) {
105 0.0
106 }
107
108 override getLevel() { 2 }
109
110 override getName() { "CompositeUnfinishednessObjective" }
111
88 override isHardObjective() { true } 112 override isHardObjective() { true }
89 override satisifiesHardObjective(Double fitness) { fitness <= 0.001 } 113
90 114 override satisifiesHardObjective(Double fitness) { fitness < 0.01 }
91 115
92 override setComparator(Comparator<Double> comparator) { 116 override setComparator(Comparator<Double> comparator) {
93 throw new UnsupportedOperationException("TODO: auto-generated method stub") 117 throw new UnsupportedOperationException("Model generation objective comparator cannot be set.")
94 } 118 }
119
95 override setLevel(int level) { 120 override setLevel(int level) {
96 throw new UnsupportedOperationException("TODO: auto-generated method stub") 121 throw new UnsupportedOperationException("Model generation objective level cannot be set.")
97 } 122 }
98 123}
99} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend
new file mode 100644
index 00000000..70e8e9c2
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend
@@ -0,0 +1,192 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatra2logic.NumericTranslator
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BooleanElement
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.IntegerElement
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PrimitiveElement
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.RealElement
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.StringElement
10import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ModelGenerationMethod
11import java.math.BigDecimal
12import java.util.HashMap
13import java.util.LinkedHashMap
14import java.util.LinkedHashSet
15import java.util.List
16import java.util.Map
17import org.eclipse.emf.ecore.EObject
18import org.eclipse.viatra.dse.base.ThreadContext
19import org.eclipse.viatra.query.runtime.api.IPatternMatch
20import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
21import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint
22
23class NumericSolver {
24 val ModelGenerationMethod method
25 var ThreadContext threadContext
26 val constraint2MustUnitPropagationPrecondition = new HashMap<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>>
27 val constraint2CurrentUnitPropagationPrecondition = new HashMap<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>>
28 NumericTranslator t = new NumericTranslator
29
30 val boolean intermediateConsistencyCheck
31 val boolean caching;
32 Map<LinkedHashMap<PConstraint, Iterable<List<Integer>>>,Boolean> satisfiabilityCache = new HashMap
33
34 var long runtime = 0
35 var long cachingTime = 0
36 var int numberOfSolverCalls = 0
37 var int numberOfCachedSolverCalls = 0
38
39 new(ModelGenerationMethod method, boolean intermediateConsistencyCheck, boolean caching) {
40 this.method = method
41 this.intermediateConsistencyCheck = intermediateConsistencyCheck
42 this.caching = caching
43 }
44
45 def init(ThreadContext context) {
46 // This makes the NumericSolver single-threaded,
47 // but that's not a problem, because we only use the solver on a single thread anyways.
48 this.threadContext = context
49 val engine = threadContext.queryEngine
50 for(entry : method.mustUnitPropagationPreconditions.entrySet) {
51 val constraint = entry.key
52 val querySpec = entry.value
53 val matcher = querySpec.getMatcher(engine);
54 constraint2MustUnitPropagationPrecondition.put(constraint,matcher)
55 }
56 for(entry : method.currentUnitPropagationPreconditions.entrySet) {
57 val constraint = entry.key
58 val querySpec = entry.value
59 val matcher = querySpec.getMatcher(engine);
60 constraint2CurrentUnitPropagationPrecondition.put(constraint,matcher)
61 }
62 }
63
64 def getRuntime(){runtime}
65 def getCachingTime(){cachingTime}
66 def getNumberOfSolverCalls(){numberOfSolverCalls}
67 def getNumberOfCachedSolverCalls(){numberOfCachedSolverCalls}
68 def getSolverFormingProblem(){this.t.formingProblemTime}
69 def getSolverSolvingProblem(){this.t.solvingProblemTime}
70 def getSolverSolution(){this.t.formingSolutionTime}
71
72 def boolean maySatisfiable() {
73 if(intermediateConsistencyCheck) {
74 return isSatisfiable(this.constraint2MustUnitPropagationPrecondition)
75 } else {
76 return true
77 }
78 }
79 def boolean currentSatisfiable() {
80 isSatisfiable(this.constraint2CurrentUnitPropagationPrecondition)
81 }
82
83 private def boolean isSatisfiable(Map<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>> matches) {
84 val start = System.nanoTime
85 var boolean finalResult
86 if(matches.empty){
87 finalResult=true
88 } else {
89 val propagatedConstraints = new HashMap
90 for(entry : matches.entrySet) {
91 val constraint = entry.key
92 //println(constraint)
93 val allMatches = entry.value.allMatches.map[it.toArray]
94 //println(allMatches.toList)
95 propagatedConstraints.put(constraint,allMatches)
96 }
97 if(propagatedConstraints.values.forall[empty]) {
98 finalResult=true
99 } else {
100 if(caching) {
101 val code = getCode(propagatedConstraints)
102 val cachedResult = satisfiabilityCache.get(code)
103 if(cachedResult === null) {
104 // println('''new problem, call solver''')
105 // for(entry : code.entrySet) {
106 // println('''«entry.key» -> «entry.value»''')
107 // }
108 //println(code.hashCode)
109 this.numberOfSolverCalls++
110 val res = t.delegateIsSatisfiable(propagatedConstraints)
111 satisfiabilityCache.put(code,res)
112 finalResult=res
113 } else {
114 //println('''similar problem, answer from cache''')
115 finalResult=cachedResult
116 this.numberOfCachedSolverCalls++
117 }
118 } else {
119 finalResult= t.delegateIsSatisfiable(propagatedConstraints)
120 this.numberOfSolverCalls++
121 }
122 }
123 }
124 this.runtime+=System.nanoTime-start
125 return finalResult
126 }
127
128 def getCode(HashMap<PConstraint, Iterable<Object[]>> propagatedConstraints) {
129 val start = System.nanoTime
130 val involvedObjects = new LinkedHashSet(propagatedConstraints.values.flatten.map[toList].flatten.toList).toList
131 val res = new LinkedHashMap(propagatedConstraints.mapValues[matches | matches.map[objects | objects.map[object | involvedObjects.indexOf(object)].toList]])
132 this.cachingTime += System.nanoTime-start
133 return res
134 }
135
136 def fillSolutionCopy(Map<EObject, EObject> trace) {
137 val model = threadContext.getModel as PartialInterpretation
138 val dataObjects = model.newElements.filter(PrimitiveElement).filter[!model.openWorldElements.contains(it)].toList
139 if(constraint2CurrentUnitPropagationPrecondition.empty) {
140 fillWithDefaultValues(dataObjects,trace)
141 } else {
142 val propagatedConstraints = new HashMap
143 for(entry : constraint2CurrentUnitPropagationPrecondition.entrySet) {
144 val constraint = entry.key
145 val allMatches = entry.value.allMatches.map[it.toArray]
146 propagatedConstraints.put(constraint,allMatches)
147 }
148
149 if(propagatedConstraints.values.forall[empty]) {
150 fillWithDefaultValues(dataObjects,trace)
151 } else {
152 val solution = t.delegateGetSolution(dataObjects,propagatedConstraints)
153 fillWithSolutions(dataObjects,solution,trace)
154 }
155 }
156 }
157
158 def protected fillWithDefaultValues(List<PrimitiveElement> elements, Map<EObject, EObject> trace) {
159 for(element : elements) {
160 if(element.valueSet==false) {
161 val value = getDefaultValue(element)
162 val target = trace.get(element) as PrimitiveElement
163 target.fillWithValue(value)
164 }
165 }
166 }
167
168 def protected dispatch getDefaultValue(BooleanElement e) {false}
169 def protected dispatch getDefaultValue(IntegerElement e) {0}
170 def protected dispatch getDefaultValue(RealElement e) {0.0}
171 def protected dispatch getDefaultValue(StringElement e) {""}
172
173 def protected fillWithSolutions(List<PrimitiveElement> elements, Map<PrimitiveElement, Number> solution, Map<EObject, EObject> trace) {
174 for(element : elements) {
175 if(element.valueSet==false) {
176 if(solution.containsKey(element)) {
177 val value = solution.get(element)
178 val target = trace.get(element) as PrimitiveElement
179 target.fillWithValue(value)
180 } else {
181 val target = trace.get(element) as PrimitiveElement
182 target.fillWithValue(target.defaultValue)
183 }
184 }
185 }
186 }
187
188 def protected dispatch fillWithValue(BooleanElement e, Object value) {e.valueSet=true e.value=value as Boolean}
189 def protected dispatch fillWithValue(IntegerElement e, Object value) {e.valueSet=true e.value=value as Integer}
190 def protected dispatch fillWithValue(RealElement e, Object value) {e.valueSet=true e.value=BigDecimal.valueOf(value as Double) }
191 def protected dispatch fillWithValue(StringElement e, Object value) {e.valueSet=true e.value=value as String}
192} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend
index f61c7333..b48d0831 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend
@@ -22,12 +22,13 @@ import java.util.List
22import java.util.Map 22import java.util.Map
23import java.util.TreeSet 23import java.util.TreeSet
24import org.eclipse.emf.ecore.EObject 24import org.eclipse.emf.ecore.EObject
25import org.eclipse.xtend.lib.annotations.Accessors
25import org.eclipse.xtext.xbase.lib.Functions.Function1 26import org.eclipse.xtext.xbase.lib.Functions.Function1
26 27
27import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* 28import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
28 29
29class PartialModelAsLogicInterpretation implements LogicModelInterpretation{ 30class PartialModelAsLogicInterpretation implements LogicModelInterpretation{
30 val PartialInterpretation partialInterpretation 31 @Accessors val PartialInterpretation partialInterpretation
31 val Map<EObject, EObject> trace; 32 val Map<EObject, EObject> trace;
32 val Map<TypeDeclaration,PartialComplexTypeInterpretation> type2Interpretation 33 val Map<TypeDeclaration,PartialComplexTypeInterpretation> type2Interpretation
33 val Map<RelationDeclaration,PartialRelationInterpretation> relation2Interpretation 34 val Map<RelationDeclaration,PartialRelationInterpretation> relation2Interpretation
@@ -153,14 +154,70 @@ class PartialModelAsLogicInterpretation implements LogicModelInterpretation{
153 } 154 }
154 155
155 override getAllIntegersInStructure() { 156 override getAllIntegersInStructure() {
156 new TreeSet(this.integerForwardTrace.keySet) 157 new TreeSet(allIntegersWithInterpretation.values)
158 }
159
160 override getAllIntegersWithInterpretation() {
161 val builder = new HashMap
162 for (entry : integerForwardTrace.entrySet) {
163 builder.put(entry.value, entry.key)
164 }
165 for (element : partialInterpretation.newElements) {
166 if (element instanceof IntegerElement) {
167 builder.put(element, element.value)
168 }
169 }
170 builder
157 } 171 }
158 172
159 override getAllRealsInStructure() { 173 override getAllRealsInStructure() {
160 new TreeSet(this.realForwardTrace.keySet) 174 new TreeSet(allRealsWithInterpretation.values)
175 }
176
177 override getAllRealsWithInterpretation() {
178 val builder = new HashMap
179 for (entry : realForwardTrace.entrySet) {
180 builder.put(entry.value, entry.key)
181 }
182 for (element : partialInterpretation.newElements) {
183 if (element instanceof RealElement) {
184 builder.put(element, element.value)
185 }
186 }
187 builder
161 } 188 }
162 189
163 override getAllStringsInStructure() { 190 override getAllStringsInStructure() {
164 new TreeSet(this.stringForwardTrace.keySet) 191 new TreeSet(allStringsWithInterpretation.values)
192 }
193
194 override getAllStringsWithInterpretation() {
195 val builder = new HashMap
196 for (entry : stringForwardTrace.entrySet) {
197 builder.put(entry.value, entry.key)
198 }
199 for (element : partialInterpretation.newElements) {
200 if (element instanceof StringElement) {
201 builder.put(element, element.value)
202 }
203 }
204 builder
205 }
206
207 override getAllBooleansInStructure() {
208 new TreeSet(allBooleansWithInterpretation.values)
209 }
210
211 override getAllBooleansWithInterpretation() {
212 val builder = new HashMap
213 for (entry : booleanForwardTrace.entrySet) {
214 builder.put(entry.value, entry.key)
215 }
216 for (element : partialInterpretation.newElements) {
217 if (element instanceof BooleanElement) {
218 builder.put(element, element.value)
219 }
220 }
221 builder
165 } 222 }
166} \ No newline at end of file 223}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PunishSizeObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PunishSizeObjective.xtend
new file mode 100644
index 00000000..bad8e4d1
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PunishSizeObjective.xtend
@@ -0,0 +1,52 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PrimitiveElement
5import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.AbstractThreeValuedObjective
6import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveKind
7import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold
8import org.eclipse.viatra.dse.base.ThreadContext
9
10class PunishSizeObjective extends AbstractThreeValuedObjective {
11 static val NAME = typeof(PunishSizeObjective).name
12
13 new(ObjectiveKind kind, int level) {
14 super(NAME, kind, ObjectiveThreshold.NO_THRESHOLD, level)
15 }
16
17 override createNew() {
18 new PunishSizeObjective(kind, level)
19 }
20
21 override init(ThreadContext context) {
22 // Nothing to initialize.
23 }
24
25 override getRawFitness(ThreadContext threadContext) {
26 val model = threadContext.model
27 if (model instanceof PartialInterpretation) {
28 val size = model.newObjectCount
29// println('''size=«size»''')
30 size as double
31 } else {
32 throw new IllegalArgumentException("notifier must be a PartialInterpretation")
33 }
34 }
35
36 override getLowestPossibleFitness(ThreadContext threadContext) {
37 getRawFitness(threadContext)
38 }
39
40 override getHighestPossibleFitness(ThreadContext threadContext) {
41 val model = threadContext.model
42 if (model instanceof PartialInterpretation) {
43 (model.newObjectCount + model.maxNewElements) as double
44 } else {
45 throw new IllegalArgumentException("notifier must be a PartialInterpretation")
46 }
47 }
48
49 private def getNewObjectCount(PartialInterpretation interpretation) {
50 interpretation.newElements.reject[it instanceof PrimitiveElement].size
51 }
52} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend
index 69efe0d7..b61bd20b 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend
@@ -23,9 +23,9 @@ class ScopeObjective implements IObjective{
23 23
24 override getFitness(ThreadContext context) { 24 override getFitness(ThreadContext context) {
25 val interpretation = context.model as PartialInterpretation 25 val interpretation = context.model as PartialInterpretation
26 var res = interpretation.minNewElements.doubleValue 26 var res = interpretation.minNewElementsHeuristic.doubleValue
27 for(scope : interpretation.scopes) { 27 for(scope : interpretation.scopes) {
28 res += scope.minNewElements*2 28 res += scope.minNewElementsHeuristic * 2
29 } 29 }
30 return res 30 return res
31 } 31 }
@@ -41,4 +41,4 @@ class ScopeObjective implements IObjective{
41 throw new UnsupportedOperationException("TODO: auto-generated method stub") 41 throw new UnsupportedOperationException("TODO: auto-generated method stub")
42 } 42 }
43 override getLevel() { 2 } 43 override getLevel() { 2 }
44} \ No newline at end of file 44}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionCopier.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionCopier.xtend
new file mode 100644
index 00000000..888eda18
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionCopier.xtend
@@ -0,0 +1,82 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import com.google.common.collect.ImmutableList
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import java.util.LinkedHashMap
6import java.util.List
7import java.util.Map
8import org.eclipse.emf.ecore.EObject
9import org.eclipse.emf.ecore.util.EcoreUtil
10import org.eclipse.viatra.dse.base.ThreadContext
11import org.eclipse.xtend.lib.annotations.Accessors
12import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
13
14@FinalFieldsConstructor
15class CopiedSolution {
16 @Accessors val PartialInterpretation partialInterpretations
17 @Accessors val Map<EObject, EObject> trace
18 @Accessors val long copierRuntime
19 @Accessors var boolean current = true
20}
21
22/**
23 * Based on {@link SolutionStore.BestSolutionSaver}.
24 *
25 * Will also automatically fill any missing numerical values in the saved solutions
26 * using the supplied {@link NumericSolver}.
27 */
28class SolutionCopier {
29 val copiedSolutions = new LinkedHashMap<Object, CopiedSolution>
30
31 @Accessors NumericSolver numericSolver
32 long startTime = System.nanoTime
33 @Accessors(PUBLIC_GETTER) long totalCopierRuntime = 0
34
35 def void copySolution(ThreadContext context, Object solutionId) {
36 val existingCopy = copiedSolutions.get(solutionId)
37 if (existingCopy === null) {
38 val copyStart = System.nanoTime
39 val solution = context.model as PartialInterpretation
40 val copier = new EcoreUtil.Copier
41 val copiedPartialInterpretation = copier.copy(solution) as PartialInterpretation
42 copier.copyReferences
43 totalCopierRuntime += System.nanoTime - copyStart
44 val copierRuntime = System.nanoTime - startTime
45 val copiedSolution = new CopiedSolution(copiedPartialInterpretation, copier, copierRuntime)
46 //numericSolver?.fillSolutionCopy(copiedSolution.trace)
47 copiedSolutions.put(solutionId, copiedSolution)
48 } else {
49 existingCopy.current = true
50 }
51 }
52
53 def void markAsObsolete(Object solutionId) {
54 val copiedSolution = copiedSolutions.get(solutionId)
55 if (copiedSolution === null) {
56 throw new IllegalStateException("No solution to mark as obsolete for state code: " + solutionId)
57 }
58 copiedSolution.current = false
59 }
60
61 def List<PartialInterpretation> getPartialInterpretations(boolean currentOnly) {
62 getListOfCopiedSolutions(currentOnly).map[partialInterpretations]
63 }
64
65 def List<Map<EObject, EObject>> getTraces(boolean currentOnly) {
66 getListOfCopiedSolutions(currentOnly).map[trace]
67 }
68
69 def List<Long> getAllCopierRuntimes(boolean currentOnly) {
70 getListOfCopiedSolutions(currentOnly).map[copierRuntime]
71 }
72
73 def List<CopiedSolution> getListOfCopiedSolutions(boolean currentOnly) {
74 val values = copiedSolutions.values
75 val filteredSolutions = if (currentOnly) {
76 values.filter[current]
77 } else {
78 values
79 }
80 ImmutableList.copyOf(filteredSolutions)
81 }
82}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend
index a8b7301e..4bd2c349 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend
@@ -1,14 +1,12 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import java.util.List
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 3import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import java.util.LinkedList 4import java.util.LinkedList
6import org.eclipse.emf.ecore.EObject 5import java.util.List
7import java.util.Map 6import java.util.Map
7import org.eclipse.emf.ecore.EObject
8import org.eclipse.emf.ecore.util.EcoreUtil 8import org.eclipse.emf.ecore.util.EcoreUtil
9import org.eclipse.viatra.dse.base.ThreadContext 9import org.eclipse.viatra.dse.base.ThreadContext
10import java.util.TreeMap
11import java.util.SortedMap
12 10
13class SolutionStoreWithCopy { 11class SolutionStoreWithCopy {
14 12
@@ -25,7 +23,7 @@ class SolutionStoreWithCopy {
25 newSolution(context) 23 newSolution(context)
26 }*/ 24 }*/
27 25
28 def newSolution(ThreadContext context) { 26 def Map<EObject,EObject> newSolution(ThreadContext context) {
29 //print(System.nanoTime-initTime + ";") 27 //print(System.nanoTime-initTime + ";")
30 val copyStart = System.nanoTime 28 val copyStart = System.nanoTime
31 val solution = context.model as PartialInterpretation 29 val solution = context.model as PartialInterpretation
@@ -36,6 +34,7 @@ class SolutionStoreWithCopy {
36 copyTraces.add(copier) 34 copyTraces.add(copier)
37 runtime += System.nanoTime - copyStart 35 runtime += System.nanoTime - copyStart
38 solutionTimes.add(System.nanoTime-sartTime) 36 solutionTimes.add(System.nanoTime-sartTime)
37 return copier
39 } 38 }
40 def getSumRuntime() { 39 def getSumRuntime() {
41 return runtime 40 return runtime
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend
deleted file mode 100644
index 1e7f18a8..00000000
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend
+++ /dev/null
@@ -1,120 +0,0 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.DiversityDescriptor
6import java.util.LinkedList
7import java.util.List
8import org.eclipse.viatra.dse.base.ThreadContext
9import java.util.HashSet
10import java.util.Set
11
12enum DiversityGranularity {
13 Nodewise, Graphwise
14}
15
16class SolutionStoreWithDiversityDescriptor {
17 val DiversityDescriptor descriptor
18 DiversityGranularity granularity
19 val PartialInterpretation2ImmutableTypeLattice solutionCoder = new PartialInterpretation2ImmutableTypeLattice
20 val Set<Integer> solutionCodeList = new HashSet
21
22 var long runtime
23 var int allCheck
24 var int successfulCheck
25
26 new(DiversityDescriptor descriptor) {
27 if(descriptor.ensureDiversity) {
28 this.descriptor = descriptor
29 this.granularity = DiversityGranularity::Nodewise
30 } else {
31 this.descriptor = null
32 this.granularity = DiversityGranularity::Nodewise
33 }
34 }
35
36 def public isActive() {
37 descriptor!==null
38 }
39
40 def getSumRuntime() {
41 return runtime
42 }
43 def getSuccessRate() {
44 return successfulCheck as double / allCheck
45 }
46
47 def isDifferent(ThreadContext context) {
48 if(active) {
49 val start = System.nanoTime
50 val model = context.model as PartialInterpretation
51 var boolean isDifferent
52 if(this.granularity == DiversityGranularity::Graphwise) {
53 val code = solutionCoder.createRepresentation(model,
54 descriptor.range,
55 descriptor.parallels,
56 descriptor.maxNumber,
57 descriptor.relevantTypes,
58 descriptor.relevantRelations).modelRepresentation.hashCode
59
60 isDifferent = !solutionCodeList.contains(code)
61 } else if(this.granularity == DiversityGranularity::Nodewise){
62 val codes = solutionCoder.createRepresentation(model,
63 descriptor.range,
64 descriptor.parallels,
65 descriptor.maxNumber,
66 descriptor.relevantTypes,
67 descriptor.relevantRelations).modelRepresentation.keySet.map[hashCode].toList
68 val differentCodes = codes.filter[!solutionCodeList.contains(it)]
69 //println(differentCodes.size)
70
71 isDifferent = differentCodes.size>=1
72 } else {
73 throw new UnsupportedOperationException('''Unsupported diversity type: «this.granularity»''')
74 }
75
76 runtime += System.nanoTime - start
77 allCheck++
78 if(isDifferent) { successfulCheck++ }
79 return isDifferent
80 } else {
81 allCheck++
82 successfulCheck++
83 return true
84 }
85 }
86
87 def canBeDifferent(ThreadContext context) {
88 return true
89 }
90
91 def newSolution(ThreadContext context) {
92 if(active) {
93 val start = System.nanoTime
94 val model = context.model as PartialInterpretation
95 if(this.granularity == DiversityGranularity::Graphwise) {
96 val code = solutionCoder.createRepresentation(model,
97 descriptor.range,
98 descriptor.parallels,
99 descriptor.maxNumber,
100 descriptor.relevantTypes,
101 descriptor.relevantRelations).modelRepresentation.hashCode
102
103 solutionCodeList += code.hashCode
104 } else if(this.granularity == DiversityGranularity::Nodewise){
105 val codes = solutionCoder.createRepresentation(model,
106 descriptor.range,
107 descriptor.parallels,
108 descriptor.maxNumber,
109 descriptor.relevantTypes,
110 descriptor.relevantRelations).modelRepresentation.keySet.map[hashCode].toList
111
112 solutionCodeList += codes.map[it.hashCode]
113 } else {
114 throw new UnsupportedOperationException('''Unsupported diversity type: «this.granularity»''')
115 }
116
117 runtime += System.nanoTime - start
118 }
119 }
120} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend
new file mode 100644
index 00000000..8ed3e912
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend
@@ -0,0 +1,27 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import org.eclipse.viatra.dse.base.ThreadContext
4import org.eclipse.viatra.dse.objectives.IGlobalConstraint
5import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
6
7@FinalFieldsConstructor
8class SurelyViolatedObjectiveGlobalConstraint implements IGlobalConstraint {
9 val ViatraReasonerSolutionSaver solutionSaver
10
11 override init(ThreadContext context) {
12 // Nothing to initialize.
13 }
14
15 override createNew() {
16 this
17 }
18
19 override getName() {
20 class.name
21 }
22
23 override checkGlobalConstraint(ThreadContext context) {
24 val bestFitness = DseUtils.caclulateBestPossibleFitness(context)
25 bestFitness.satisifiesHardObjectives && solutionSaver.fitnessMayBeSaved(bestFitness)
26 }
27}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend
index aad9a448..e1582d3b 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend
@@ -1,15 +1,15 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.MultiplicityGoalConstraintCalculator 3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.MultiplicityGoalConstraintCalculator
4import java.util.Comparator 4import java.util.Comparator
5import org.eclipse.viatra.dse.base.ThreadContext 5import org.eclipse.viatra.dse.base.ThreadContext
6import org.eclipse.viatra.dse.objectives.IObjective
7import org.eclipse.viatra.dse.objectives.Comparators 6import org.eclipse.viatra.dse.objectives.Comparators
7import org.eclipse.viatra.dse.objectives.IObjective
8 8
9class UnfinishedMultiplicityObjective implements IObjective { 9class UnfinishedMultiplicityObjective implements IObjective {
10 val MultiplicityGoalConstraintCalculator unfinishedMultiplicity; 10 val MultiplicityGoalConstraintCalculator unfinishedMultiplicity
11 11
12 public new(MultiplicityGoalConstraintCalculator unfinishedMultiplicity) { 12 new(MultiplicityGoalConstraintCalculator unfinishedMultiplicity) {
13 this.unfinishedMultiplicity = unfinishedMultiplicity 13 this.unfinishedMultiplicity = unfinishedMultiplicity
14 } 14 }
15 15
@@ -29,9 +29,13 @@ class UnfinishedMultiplicityObjective implements IObjective {
29 override satisifiesHardObjective(Double fitness) { return fitness <=0.01 } 29 override satisifiesHardObjective(Double fitness) { return fitness <=0.01 }
30 30
31 override setComparator(Comparator<Double> comparator) { 31 override setComparator(Comparator<Double> comparator) {
32 throw new UnsupportedOperationException("TODO: auto-generated method stub") 32 throw new UnsupportedOperationException
33 } 33 }
34 override setLevel(int level) { 34 override setLevel(int level) {
35 throw new UnsupportedOperationException("TODO: auto-generated method stub") 35 throw new UnsupportedOperationException
36 }
37
38 def isContainment() {
39 return this.unfinishedMultiplicity.containment
36 } 40 }
37} \ No newline at end of file 41}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend
index e0111cf6..1b61ffa5 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend
@@ -1,56 +1,64 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import org.eclipse.viatra.dse.objectives.IObjective 3import java.util.ArrayList
4import org.eclipse.viatra.query.runtime.api.IPatternMatch
5import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
6import org.eclipse.viatra.query.runtime.api.IQuerySpecification
7import java.util.Collection 4import java.util.Collection
8import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine 5import java.util.Comparator
9import org.eclipse.viatra.query.runtime.emf.EMFScope
10import org.eclipse.viatra.dse.base.ThreadContext
11import java.util.List 6import java.util.List
7import org.eclipse.viatra.dse.base.ThreadContext
12import org.eclipse.viatra.dse.objectives.Comparators 8import org.eclipse.viatra.dse.objectives.Comparators
13import java.util.ArrayList 9import org.eclipse.viatra.dse.objectives.IObjective
14import java.util.Comparator 10import org.eclipse.viatra.query.runtime.api.IPatternMatch
11import org.eclipse.viatra.query.runtime.api.IQuerySpecification
12import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
15 13
16class UnfinishedWFObjective implements IObjective { 14class UnfinishedWFObjective implements IObjective {
17 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFs 15 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFs
18 val List<ViatraQueryMatcher<?>> matchers 16 val List<ViatraQueryMatcher<?>> matchers
19 17
20 public new(Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFs) { 18 new(
19 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFs) {
21 this.unfinishedWFs = unfinishedWFs 20 this.unfinishedWFs = unfinishedWFs
22 matchers = new ArrayList(unfinishedWFs.size) 21 matchers = new ArrayList(unfinishedWFs.size)
23 } 22 }
23
24 override getName() '''unfinishedWFs''' 24 override getName() '''unfinishedWFs'''
25
25 override createNew() { 26 override createNew() {
26 return new UnfinishedWFObjective(unfinishedWFs) 27 return new UnfinishedWFObjective(unfinishedWFs)
27 } 28 }
29
28 override init(ThreadContext context) { 30 override init(ThreadContext context) {
29 val engine = context.queryEngine//ViatraQueryEngine.on(new EMFScope(context.model)) 31 val engine = context.queryEngine // ViatraQueryEngine.on(new EMFScope(context.model))
30 for(unfinishedWF : unfinishedWFs) { 32 for (unfinishedWF : unfinishedWFs) {
31 matchers += unfinishedWF.getMatcher(engine) 33 matchers += unfinishedWF.getMatcher(engine)
32 } 34 }
33 } 35 }
34 36
35 override getComparator() { Comparators.LOWER_IS_BETTER } 37 override getComparator() { Comparators.LOWER_IS_BETTER }
38
36 override getFitness(ThreadContext context) { 39 override getFitness(ThreadContext context) {
37 var sumOfMatches = 0 40 var sumOfMatches = 0
38 for(matcher : matchers) { 41 for (matcher : matchers) {
39 val number = matcher.countMatches 42 val number = matcher.countMatches
40 //println('''«matcher.patternName» = «number»''') 43// if (number > 0) {
41 sumOfMatches+=number 44// println('''«matcher.patternName» = «number»''')
45// }
46 sumOfMatches += number
42 } 47 }
43 return sumOfMatches.doubleValue 48 return sumOfMatches.doubleValue
44 } 49 }
45 50
46 override getLevel() { 2 } 51 override getLevel() { 2 }
52
47 override isHardObjective() { true } 53 override isHardObjective() { true }
48 override satisifiesHardObjective(Double fitness) { return fitness <=0.01 } 54
49 55 override satisifiesHardObjective(Double fitness) { return fitness <= 0.01 }
56
50 override setComparator(Comparator<Double> comparator) { 57 override setComparator(Comparator<Double> comparator) {
51 throw new UnsupportedOperationException("TODO: auto-generated method stub") 58 throw new UnsupportedOperationException()
52 } 59 }
60
53 override setLevel(int level) { 61 override setLevel(int level) {
54 throw new UnsupportedOperationException("TODO: auto-generated method stub") 62 throw new UnsupportedOperationException()
55 } 63 }
56} \ No newline at end of file 64}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend
new file mode 100644
index 00000000..e00f76ff
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend
@@ -0,0 +1,250 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.Bounds
4import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.DirectionalThresholdObjective
5import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.IObjectiveBoundsProvider
6import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold
7import java.util.HashMap
8import java.util.Map
9import org.eclipse.viatra.dse.api.DSEException
10import org.eclipse.viatra.dse.api.Solution
11import org.eclipse.viatra.dse.api.SolutionTrajectory
12import org.eclipse.viatra.dse.base.ThreadContext
13import org.eclipse.viatra.dse.objectives.Fitness
14import org.eclipse.viatra.dse.objectives.IObjective
15import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper
16import org.eclipse.viatra.dse.solutionstore.SolutionStore.ISolutionSaver
17import org.eclipse.xtend.lib.annotations.Accessors
18
19/**
20 * Based on {@link SolutionStore.BestSolutionSaver}.
21 *
22 * Will also automatically fill any missing numerical values in the saved solutions
23 * using the supplied {@link NumericSolver}.
24 */
25class ViatraReasonerSolutionSaver implements ISolutionSaver, IObjectiveBoundsProvider {
26 static val TOLERANCE = 1e-10
27
28 @Accessors val SolutionCopier solutionCopier
29 @Accessors val DiversityChecker diversityChecker
30 val IObjective[][] leveledExtremalObjectives
31 val boolean hasExtremalObjectives
32 val int numberOfRequiredSolutions
33 val ObjectiveComparatorHelper comparatorHelper
34 val Map<SolutionTrajectory, Fitness> trajectories = new HashMap
35
36 @Accessors var NumericSolver numericSolver
37 @Accessors var Map<Object, Solution> solutionsCollection
38
39 new(IObjective[][] leveledExtremalObjectives, int numberOfRequiredSolutions, DiversityChecker diversityChecker) {
40 this.diversityChecker = diversityChecker
41 comparatorHelper = new ObjectiveComparatorHelper(leveledExtremalObjectives)
42 this.leveledExtremalObjectives = leveledExtremalObjectives
43 hasExtremalObjectives = leveledExtremalObjectives.exists[!empty]
44 this.numberOfRequiredSolutions = numberOfRequiredSolutions
45 this.solutionCopier = new SolutionCopier
46 }
47
48 def setNumericSolver(NumericSolver numericSolver) {
49 this.numericSolver = numericSolver
50 solutionCopier.numericSolver = numericSolver
51 }
52
53 override saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
54 if (hasExtremalObjectives) {
55 saveBestSolutionOnly(context, id, solutionTrajectory)
56 } else {
57 saveAnyDiverseSolution(context, id, solutionTrajectory)
58 }
59 }
60
61 private def saveBestSolutionOnly(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
62 val fitness = context.lastFitness
63 if (!shouldSaveSolution(fitness, context)) {
64 return false
65 }
66 println("Found: " + fitness)
67 val dominatedTrajectories = newArrayList
68 for (entry : trajectories.entrySet) {
69 val isLastFitnessBetter = comparatorHelper.compare(fitness, entry.value)
70 if (isLastFitnessBetter < 0) {
71 // Found a trajectory that dominates the current one, no need to save
72 return false
73 }
74 if (isLastFitnessBetter > 0) {
75 dominatedTrajectories += entry.key
76 }
77 }
78 if (dominatedTrajectories.size == 0 && !needsMoreSolutionsWithSameFitness) {
79 return false
80 }
81 if (!diversityChecker.newSolution(context, id, dominatedTrajectories.map[solution.stateCode])) {
82 return false
83 }
84 // We must save the new trajectory before removing dominated trajectories
85 // to avoid removing the current solution when it is reachable only via dominated trajectories.
86 val solutionSaved = basicSaveSolution(context, id, solutionTrajectory, fitness)
87 for (dominatedTrajectory : dominatedTrajectories) {
88 trajectories -= dominatedTrajectory
89 val dominatedSolution = dominatedTrajectory.solution
90 if (!dominatedSolution.trajectories.remove(dominatedTrajectory)) {
91 throw new DSEException(
92 "Dominated solution is not reachable from dominated trajectory. This should never happen!")
93 }
94 if (dominatedSolution.trajectories.empty) {
95 val dominatedSolutionId = dominatedSolution.stateCode
96 solutionCopier.markAsObsolete(dominatedSolutionId)
97 solutionsCollection -= dominatedSolutionId
98 }
99 }
100 solutionSaved
101 }
102
103 private def saveAnyDiverseSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
104 val fitness = context.lastFitness
105 if (!shouldSaveSolution(fitness, context)) {
106 return false
107 }
108 if (!diversityChecker.newSolution(context, id, emptyList)) {
109 return false
110 }
111 basicSaveSolution(context, id, solutionTrajectory, fitness)
112 }
113
114 private def shouldSaveSolution(Fitness fitness, ThreadContext context) {
115 fitness.satisifiesHardObjectives && (numericSolver === null || numericSolver.currentSatisfiable)
116 }
117
118 private def basicSaveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory,
119 Fitness fitness) {
120 var boolean solutionSaved = false
121 var dseSolution = solutionsCollection.get(id)
122 if (dseSolution === null) {
123 solutionCopier.copySolution(context, id)
124 dseSolution = new Solution(id, solutionTrajectory)
125 solutionsCollection.put(id, dseSolution)
126 solutionSaved = true
127 } else {
128 solutionSaved = dseSolution.trajectories.add(solutionTrajectory)
129 }
130 if (solutionSaved) {
131 solutionTrajectory.solution = dseSolution
132 trajectories.put(solutionTrajectory, fitness)
133 }
134 solutionSaved
135 }
136
137 def fitnessMayBeSaved(Fitness fitness) {
138 if (!hasExtremalObjectives) {
139 return true
140 }
141 var boolean mayDominate
142 for (existingFitness : trajectories.values) {
143 val isNewFitnessBetter = comparatorHelper.compare(fitness, existingFitness)
144 if (isNewFitnessBetter < 0) {
145 return false
146 }
147 if (isNewFitnessBetter > 0) {
148 mayDominate = true
149 }
150 }
151 mayDominate || needsMoreSolutionsWithSameFitness
152 }
153
154 private def boolean needsMoreSolutionsWithSameFitness() {
155 if (solutionsCollection === null) {
156 // The solutions collection will only be initialized upon saving the first solution.
157 return true
158 }
159 solutionsCollection.size < numberOfRequiredSolutions
160 }
161
162 def getTotalCopierRuntime() {
163 solutionCopier.totalCopierRuntime
164 }
165
166 override computeRequiredBounds(IObjective objective, Bounds bounds) {
167 if (!hasExtremalObjectives) {
168 return
169 }
170 if (objective instanceof DirectionalThresholdObjective) {
171 switch (threshold : objective.threshold) {
172 case ObjectiveThreshold.NO_THRESHOLD: {
173 // No threshold to set.
174 }
175 ObjectiveThreshold.Exclusive: {
176 switch (kind : objective.kind) {
177 case HIGHER_IS_BETTER:
178 bounds.tightenLowerBound(Math.floor(threshold.threshold + 1) as int)
179 case LOWER_IS_BETTER:
180 bounds.tightenUpperBound(Math.ceil(threshold.threshold - 1) as int)
181 default:
182 throw new IllegalArgumentException("Unknown objective kind" + kind)
183 }
184 if (threshold.clampToThreshold) {
185 return
186 }
187 }
188 ObjectiveThreshold.Inclusive: {
189 switch (kind : objective.kind) {
190 case HIGHER_IS_BETTER:
191 bounds.tightenLowerBound(Math.ceil(threshold.threshold) as int)
192 case LOWER_IS_BETTER:
193 bounds.tightenUpperBound(Math.floor(threshold.threshold) as int)
194 default:
195 throw new IllegalArgumentException("Unknown objective kind" + kind)
196 }
197 if (threshold.clampToThreshold) {
198 return
199 }
200 }
201 default:
202 throw new IllegalArgumentException("Unknown threshold: " + threshold)
203 }
204 for (level : leveledExtremalObjectives) {
205 switch (level.size) {
206 case 0: {
207 // Nothing to do, wait for the next level.
208 }
209 case 1: {
210 val primaryObjective = level.get(0)
211 if (primaryObjective != objective) {
212 // There are no worst-case bounds for secondary objectives.
213 return
214 }
215 }
216 default:
217 // There are no worst-case bounds for Pareto front calculation.
218 return
219 }
220 }
221 val fitnessIterator = trajectories.values.iterator
222 if (!fitnessIterator.hasNext) {
223 return
224 }
225 val fitness = fitnessIterator.next.get(objective.name)
226 while (fitnessIterator.hasNext) {
227 val otherFitness = fitnessIterator.next.get(objective.name)
228 if (Math.abs(fitness - otherFitness) > TOLERANCE) {
229 throw new IllegalStateException("Inconsistent fitness: " + objective.name)
230 }
231 }
232 switch (kind : objective.kind) {
233 case HIGHER_IS_BETTER:
234 if (needsMoreSolutionsWithSameFitness) {
235 bounds.tightenLowerBound(Math.floor(fitness) as int)
236 } else {
237 bounds.tightenLowerBound(Math.floor(fitness + 1) as int)
238 }
239 case LOWER_IS_BETTER:
240 if (needsMoreSolutionsWithSameFitness) {
241 bounds.tightenUpperBound(Math.ceil(fitness) as int)
242 } else {
243 bounds.tightenUpperBound(Math.ceil(fitness - 1) as int)
244 }
245 default:
246 throw new IllegalArgumentException("Unknown objective kind" + kind)
247 }
248 }
249 }
250}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend
index 5a528a9e..6d772f32 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend
@@ -1,5 +1,6 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import com.google.common.collect.ImmutableList
3import java.util.ArrayList 4import java.util.ArrayList
4import java.util.Collection 5import java.util.Collection
5import org.eclipse.viatra.dse.objectives.Comparators 6import org.eclipse.viatra.dse.objectives.Comparators
@@ -12,25 +13,33 @@ import org.eclipse.viatra.query.runtime.api.IQuerySpecification
12import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher 13import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
13 14
14class WF2ObjectiveConverter { 15class WF2ObjectiveConverter {
15 16 static val INVALIDATED_WFS_NAME = "invalidatedWFs"
17
16 def createCompletenessObjective( 18 def createCompletenessObjective(
17 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWF) 19 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWF) {
18 { 20 new UnfinishedWFObjective(unfinishedWF)
19 val res = new ConstraintsObjective('''unfinishedWFs''', 21 }
20 unfinishedWF.map[ 22
21 new QueryConstraint(it.fullyQualifiedName,it,2.0) 23 def createInvalidationObjective(
22 ].toList 24 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidatedByWF) {
25 createConstraintObjective(INVALIDATED_WFS_NAME, invalidatedByWF)
26 }
27
28 def IGlobalConstraint createInvalidationGlobalConstraint(
29 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidatedByWF) {
30 new ModelQueriesGlobalConstraint(INVALIDATED_WFS_NAME, new ArrayList(invalidatedByWF))
31 }
32
33 private def createConstraintObjective(String name,
34 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> queries) {
35 val res = new ConstraintsObjective(
36 name,
37 ImmutableList.copyOf(queries.map [
38 new QueryConstraint(it.fullyQualifiedName, it, 1.0)
39 ])
23 ) 40 )
24 res.withComparator(Comparators.LOWER_IS_BETTER) 41 res.withComparator(Comparators.LOWER_IS_BETTER)
25 res.level = 2 42 res.level = 2
26 return res 43 res
27 }
28
29 def IGlobalConstraint createInvalidationObjective(
30 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidatedByWF)
31 {
32 return new ModelQueriesGlobalConstraint('''invalidatedWFs''',
33 new ArrayList(invalidatedByWF)
34 )
35 } 44 }
36} \ No newline at end of file 45}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend
new file mode 100644
index 00000000..cd911ab5
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend
@@ -0,0 +1,35 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import org.eclipse.viatra.dse.base.ThreadContext
4
5abstract class AbstractThreeValuedObjective extends DirectionalThresholdObjective implements IThreeValuedObjective {
6 protected new(String name, ObjectiveKind kind, ObjectiveThreshold threshold, int level) {
7 super(name, kind, threshold, level)
8 }
9
10 abstract def double getLowestPossibleFitness(ThreadContext threadContext)
11
12 abstract def double getHighestPossibleFitness(ThreadContext threadContext)
13
14 override getWorstPossibleFitness(ThreadContext threadContext) {
15 switch (kind) {
16 case LOWER_IS_BETTER:
17 getHighestPossibleFitness(threadContext)
18 case HIGHER_IS_BETTER:
19 getLowestPossibleFitness(threadContext)
20 default:
21 throw new IllegalStateException("Unknown three valued objective kind: " + kind)
22 }
23 }
24
25 override getBestPossibleFitness(ThreadContext threadContext) {
26 switch (kind) {
27 case LOWER_IS_BETTER:
28 getLowestPossibleFitness(threadContext)
29 case HIGHER_IS_BETTER:
30 getHighestPossibleFitness(threadContext)
31 default:
32 throw new IllegalStateException("Unknown three valued objective kind: " + kind)
33 }
34 }
35}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend
new file mode 100644
index 00000000..0aa442f5
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend
@@ -0,0 +1,62 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import com.google.common.collect.ImmutableList
4import java.util.Collection
5import org.eclipse.viatra.dse.base.ThreadContext
6
7class CompositeDirectionalThresholdObjective extends DirectionalThresholdObjective {
8 val Collection<DirectionalThresholdObjective> objectives
9
10 new(String name, Collection<DirectionalThresholdObjective> objectives) {
11 this(name, objectives, getKind(objectives), getThreshold(objectives), getLevel(objectives))
12 }
13
14 new(String name, DirectionalThresholdObjective... objectives) {
15 this(name, objectives as Collection<DirectionalThresholdObjective>)
16 }
17
18 protected new(String name, Iterable<DirectionalThresholdObjective> objectives, ObjectiveKind kind,
19 ObjectiveThreshold threshold, int level) {
20 super(name, kind, threshold, level)
21 this.objectives = ImmutableList.copyOf(objectives)
22 }
23
24 override createNew() {
25 new CompositeDirectionalThresholdObjective(name, objectives.map[createNew as DirectionalThresholdObjective],
26 kind, threshold, level)
27 }
28
29 override init(ThreadContext context) {
30 for (objective : objectives) {
31 objective.init(context)
32 }
33 }
34
35 override protected getRawFitness(ThreadContext context) {
36 var double fitness = 0
37 for (objective : objectives) {
38 fitness += objective.getFitness(context)
39 }
40 fitness
41 }
42
43 private static def getKind(Collection<DirectionalThresholdObjective> objectives) {
44 val kinds = objectives.map[kind].toSet
45 if (kinds.size != 1) {
46 throw new IllegalArgumentException("Passed objectives must have the same kind")
47 }
48 kinds.head
49 }
50
51 private static def getThreshold(Collection<DirectionalThresholdObjective> objectives) {
52 objectives.map[threshold].reduce[a, b|a.merge(b)]
53 }
54
55 private static def int getLevel(Collection<DirectionalThresholdObjective> objectives) {
56 val levels = objectives.map[level].toSet
57 if (levels.size != 1) {
58 throw new IllegalArgumentException("Passed objectives must have the same level")
59 }
60 levels.head
61 }
62}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostElementMatchers.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostElementMatchers.xtend
new file mode 100644
index 00000000..885b14e8
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostElementMatchers.xtend
@@ -0,0 +1,137 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import com.google.common.collect.ImmutableList
4import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicproblemPackage
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage
6import java.util.List
7import org.eclipse.emf.ecore.EObject
8import org.eclipse.viatra.query.runtime.api.IPatternMatch
9import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
10import org.eclipse.xtend.lib.annotations.Data
11import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
12import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
13
14@FunctionalInterface
15interface ParameterScopeBound {
16 def double getUpperBound()
17}
18
19@Data
20class CostElementMatch {
21 val IPatternMatch match
22 val boolean must
23
24 def isMulti() {
25 CostElementMatchers.isMultiMatch(match)
26 }
27}
28
29@Data
30class CostElementMatchers {
31 val ViatraQueryMatcher<? extends IPatternMatch> currentMatcher
32 val ViatraQueryMatcher<? extends IPatternMatch> mayMatcher
33 val ViatraQueryMatcher<? extends IPatternMatch> mustMatcher
34 val List<ParameterScopeBound> parameterScopeBounds
35 val int weight
36
37 def getCurrentNumberOfMatches() {
38 currentMatcher.countMatches
39 }
40
41 def getMinimumNumberOfMatches() {
42 mustMatcher.countMatches
43 }
44
45 def getMaximumNumberOfMatches() {
46 var double sum = 0
47 val iterator = mayMatcher.streamAllMatches.iterator
48 while (iterator.hasNext) {
49 val match = iterator.next
50 var double product = 1
51 val numberOfParameters = parameterScopeBounds.size
52 for (var int i = 0; i < numberOfParameters; i++) {
53 if (isMulti(match.get(i + 2))) {
54 val scopeBound = parameterScopeBounds.get(i)
55 product *= scopeBound.upperBound
56 }
57
58 }
59 sum += product
60 }
61 sum
62 }
63
64 def getMatches() {
65 ImmutableList.copyOf(mayMatcher.streamAllMatches.iterator.map [ match |
66 new CostElementMatch(match, mustMatcher.isMatch(match))
67 ])
68 }
69
70 def projectMayMatch(IPatternMatch match, int... indices) {
71 mayMatcher.projectMatch(match, indices)
72 }
73
74 private static def <T extends IPatternMatch> projectMatch(ViatraQueryMatcher<T> matcher, IPatternMatch match, int... indices) {
75 checkMatch(match)
76 val n = matcher.specification.parameters.length - 2
77 if (indices.length != n) {
78 throw new IllegalArgumentException("Invalid number of projection indices")
79 }
80 val newMatch = matcher.newEmptyMatch
81 newMatch.set(0, match.get(0))
82 newMatch.set(1, match.get(1))
83 for (var int i = 0; i < n; i++) {
84 newMatch.set(i + 2, match.get(indices.get(i)))
85 }
86 if (!matcher.hasMatch(newMatch)) {
87 throw new IllegalArgumentException("Projected match does not exist")
88 }
89 return newMatch
90 }
91
92 private static def <T extends IPatternMatch> isMatch(ViatraQueryMatcher<T> matcher, IPatternMatch match) {
93 val n = matcher.specification.parameters.length
94 if (n != match.specification.parameters.length) {
95 throw new IllegalArgumentException("Invalid number of match arguments")
96 }
97 val newMatch = matcher.newEmptyMatch
98 for (var int i = 0; i < n; i++) {
99 newMatch.set(i, match.get(i))
100 }
101 return matcher.hasMatch(newMatch)
102 }
103
104 static def isMulti(Object o) {
105 if (o instanceof EObject) {
106 switch (feature : o.eContainmentFeature) {
107 case LogicproblemPackage.eINSTANCE.logicProblem_Elements,
108 case PartialinterpretationPackage.eINSTANCE.partialInterpretation_NewElements:
109 false
110 case PartialinterpretationPackage.eINSTANCE.partialInterpretation_OpenWorldElements:
111 true
112 default:
113 throw new IllegalStateException("Unknown containment feature for element: " + feature)
114 }
115 } else {
116 false
117 }
118 }
119
120 static def isMultiMatch(IPatternMatch match) {
121 checkMatch(match)
122 val n = match.specification.parameters.length
123 for (var int i = 2; i < n; i++) {
124 if (isMulti(match.get(i))) {
125 return true
126 }
127 }
128 false
129 }
130
131 private static def checkMatch(IPatternMatch match) {
132 val n = match.specification.parameters.length
133 if (n < 2 || !(match.get(0) instanceof LogicProblem) || !(match.get(1) instanceof PartialInterpretation)) {
134 throw new IllegalArgumentException("Match is not from the partial interpretation")
135 }
136 }
137}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostObjectiveHint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostObjectiveHint.xtend
new file mode 100644
index 00000000..2434073d
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CostObjectiveHint.xtend
@@ -0,0 +1,68 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.BoundSaturationListener
4import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ExtendedLinearExpressionBuilder
5import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeConstraintHint
6import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeExpressionBuilderFactory
7import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedronExtensionOperator
8import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.PatternGenerator
9import java.util.Map
10import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
11import org.eclipse.xtend.lib.annotations.Accessors
12
13abstract class CostObjectiveHint implements LinearTypeConstraintHint, BoundSaturationListener {
14 @Accessors ThreeValuedCostObjective objective
15 @Accessors IObjectiveBoundsProvider boundsProvider
16
17 Integer bestUpper = null
18
19 override getAdditionalPatterns(PatternGenerator patternGenerator, Map<String, PQuery> fqnToPQuery) {
20 ''''''
21 }
22
23 override createConstraintUpdater(LinearTypeExpressionBuilderFactory builderFactory) {
24 null
25 }
26
27 def isExact() {
28 false
29 }
30
31 def PolyhedronExtensionOperator createPolyhedronExtensionOperator(
32 Map<String, CostElementMatchers> costElementMatchers) {
33 null
34 }
35
36 def setObjective(ThreeValuedCostObjective objective) {
37 if (this.objective !== null) {
38 throw new IllegalStateException("Objective was already set")
39 }
40 this.objective = objective
41 }
42
43 def setBoundsProvider(IObjectiveBoundsProvider boundsProvider) {
44 if (this.boundsProvider !== null) {
45 throw new IllegalStateException("Objective bounds provider was already set")
46 }
47 this.boundsProvider = boundsProvider
48 }
49
50 protected def buildWithBounds(ExtendedLinearExpressionBuilder builder) {
51 val bounds = builder.build(this)
52 if (objective !== null && boundsProvider !== null) {
53 boundsProvider.computeRequiredBounds(objective, bounds)
54 }
55 if (exact && bestUpper !== null) {
56 bounds.tightenLowerBound(bestUpper)
57 }
58 bounds
59 }
60
61 override boundsSaturated(Integer lower, Integer upper) {
62 if (upper !== null && (bestUpper === null || bestUpper < upper)) {
63 bestUpper = upper
64 }
65 objective?.boundsSaturated(lower, upper)
66 }
67
68}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend
new file mode 100644
index 00000000..376e3d1a
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend
@@ -0,0 +1,164 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import java.util.Comparator
4import org.eclipse.viatra.dse.base.ThreadContext
5import org.eclipse.viatra.dse.objectives.IObjective
6import org.eclipse.xtend.lib.annotations.Accessors
7import org.eclipse.xtend.lib.annotations.Data
8import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
9
10abstract class ObjectiveThreshold {
11 public static val NO_THRESHOLD = new ObjectiveThreshold {
12 override isHard() {
13 false
14 }
15
16 override satisfiesThreshold(double cost, Comparator<Double> comparator) {
17 true
18 }
19
20 override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) {
21 cost
22 }
23
24 override ObjectiveThreshold merge(ObjectiveThreshold other) {
25 if (other == NO_THRESHOLD) {
26 NO_THRESHOLD
27 } else {
28 throw new IllegalArgumentException("Merged thresholds must have the same type")
29 }
30 }
31 }
32
33 private new() {
34 }
35
36 def boolean isHard() {
37 true
38 }
39
40 def boolean satisfiesThreshold(double cost, ObjectiveKind kind) {
41 satisfiesThreshold(cost, kind.comparator)
42 }
43
44 def boolean satisfiesThreshold(double cost, Comparator<Double> comparator)
45
46 def double postProcessCost(double cost, ObjectiveKind kind) {
47 if (satisfiesThreshold(cost, kind)) {
48 postProcessSatisfactoryCost(cost, kind)
49 } else {
50 cost
51 }
52 }
53
54 protected def double postProcessSatisfactoryCost(double cost, ObjectiveKind kind)
55
56 def ObjectiveThreshold merge(ObjectiveThreshold other)
57
58 @Data
59 static class Exclusive extends ObjectiveThreshold {
60 static val EPSILON = 0.1
61
62 val double threshold
63 val boolean clampToThreshold
64
65 @FinalFieldsConstructor
66 new() {
67 }
68
69 new(double threshold) {
70 this(threshold, true)
71 }
72
73 override satisfiesThreshold(double cost, Comparator<Double> comparator) {
74 comparator.compare(threshold, cost) < 0
75 }
76
77 override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) {
78 if (clampToThreshold) {
79 threshold + Math.signum(kind.satisfiedValue) * EPSILON
80 } else {
81 cost
82 }
83 }
84
85 override ObjectiveThreshold merge(ObjectiveThreshold other) {
86 if (other instanceof Exclusive) {
87 new Exclusive(threshold + other.threshold)
88 } else {
89 throw new IllegalArgumentException("Merged thresholds must have the same type")
90 }
91 }
92 }
93
94 @Data
95 static class Inclusive extends ObjectiveThreshold {
96 val double threshold
97 val boolean clampToThreshold
98
99 @FinalFieldsConstructor
100 new() {
101 }
102
103 new(double threshold) {
104 this(threshold, true)
105 }
106
107 override satisfiesThreshold(double cost, Comparator<Double> comparator) {
108 comparator.compare(threshold, cost) <= 0
109 }
110
111 override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) {
112 if (clampToThreshold) {
113 threshold
114 } else {
115 cost
116 }
117 }
118
119 override ObjectiveThreshold merge(ObjectiveThreshold other) {
120 if (other instanceof Inclusive) {
121 new Inclusive(threshold + other.threshold)
122 } else {
123 throw new IllegalArgumentException("Merged thresholds must have the same type")
124 }
125 }
126 }
127}
128
129abstract class DirectionalThresholdObjective implements IObjective {
130 @Accessors val String name
131 @Accessors ObjectiveKind kind
132 @Accessors ObjectiveThreshold threshold
133 @Accessors int level
134
135 protected new(String name, ObjectiveKind kind, ObjectiveThreshold threshold, int level) {
136 this.name = name
137 this.kind = kind
138 this.threshold = threshold
139 this.level = level
140 }
141
142 override isHardObjective() {
143 threshold.hard
144 }
145
146 override satisifiesHardObjective(Double fitness) {
147 threshold.satisfiesThreshold(fitness, comparator)
148 }
149
150 override getComparator() {
151 kind.comparator
152 }
153
154 override setComparator(Comparator<Double> comparator) {
155 kind = ObjectiveKind.fromComparator(comparator)
156 }
157
158 override getFitness(ThreadContext context) {
159 val fitness = getRawFitness(context)
160 threshold.postProcessCost(fitness, kind)
161 }
162
163 protected def double getRawFitness(ThreadContext context)
164}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IObjectiveBoundsProvider.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IObjectiveBoundsProvider.xtend
new file mode 100644
index 00000000..3c4d36a5
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IObjectiveBoundsProvider.xtend
@@ -0,0 +1,8 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.Bounds
4import org.eclipse.viatra.dse.objectives.IObjective
5
6interface IObjectiveBoundsProvider {
7 def void computeRequiredBounds(IObjective objective, Bounds bounds)
8}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IThreeValuedObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IThreeValuedObjective.xtend
new file mode 100644
index 00000000..4a870a3e
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IThreeValuedObjective.xtend
@@ -0,0 +1,10 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import org.eclipse.viatra.dse.base.ThreadContext
4import org.eclipse.viatra.dse.objectives.IObjective
5
6interface IThreeValuedObjective extends IObjective {
7 def Double getWorstPossibleFitness(ThreadContext threadContext)
8
9 def Double getBestPossibleFitness(ThreadContext threadContext)
10}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend
new file mode 100644
index 00000000..a0c6a2c1
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend
@@ -0,0 +1,52 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import com.google.common.collect.ImmutableList
4import java.util.Collection
5import org.eclipse.viatra.dse.base.ThreadContext
6import org.eclipse.viatra.query.runtime.api.IPatternMatch
7import org.eclipse.viatra.query.runtime.api.IQuerySpecification
8import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
9import org.eclipse.xtend.lib.annotations.Data
10
11@Data
12class MatchCostElement {
13 val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification
14 val double weight
15}
16
17class MatchCostObjective extends DirectionalThresholdObjective {
18 val Collection<MatchCostElement> costElements
19 Collection<CostElementMatcher> matchers
20
21 new(String name, Collection<MatchCostElement> costElements, ObjectiveKind kind, ObjectiveThreshold threshold,
22 int level) {
23 super(name, kind, threshold, level)
24 this.costElements = costElements
25 }
26
27 override createNew() {
28 new MatchCostObjective(name, costElements, kind, threshold, level)
29 }
30
31 override init(ThreadContext context) {
32 val queryEngine = context.queryEngine
33 matchers = ImmutableList.copyOf(costElements.map [
34 val matcher = querySpecification.getMatcher(queryEngine)
35 new CostElementMatcher(matcher, weight)
36 ])
37 }
38
39 override protected getRawFitness(ThreadContext context) {
40 var double cost = 0
41 for (it : matchers) {
42 cost += weight * matcher.countMatches
43 }
44 cost
45 }
46
47 @Data
48 private static class CostElementMatcher {
49 val ViatraQueryMatcher<? extends IPatternMatch> matcher
50 val double weight
51 }
52}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java
new file mode 100644
index 00000000..cbbaaafd
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java
@@ -0,0 +1,60 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization;
2
3import java.util.Comparator;
4
5import org.eclipse.viatra.dse.objectives.Comparators;
6
7public enum ObjectiveKind {
8 LOWER_IS_BETTER {
9
10 @Override
11 public Comparator<Double> getComparator() {
12 return Comparators.LOWER_IS_BETTER;
13 }
14
15 @Override
16 public double getInvalidValue() {
17 return Double.POSITIVE_INFINITY;
18 }
19
20 @Override
21 public double getSatisfiedValue() {
22 return Double.NEGATIVE_INFINITY;
23 }
24
25 },
26 HIGHER_IS_BETTER {
27
28 @Override
29 public Comparator<Double> getComparator() {
30 return Comparators.HIGHER_IS_BETTER;
31 }
32
33 @Override
34 public double getInvalidValue() {
35 return Double.NEGATIVE_INFINITY;
36 }
37
38 @Override
39 public double getSatisfiedValue() {
40 return Double.POSITIVE_INFINITY;
41 }
42
43 };
44
45 public abstract Comparator<Double> getComparator();
46
47 public abstract double getInvalidValue();
48
49 public abstract double getSatisfiedValue();
50
51 public static ObjectiveKind fromComparator(Comparator<Double> comparator) {
52 if (Comparators.LOWER_IS_BETTER.equals(comparator)) {
53 return ObjectiveKind.LOWER_IS_BETTER;
54 } else if (Comparators.HIGHER_IS_BETTER.equals(comparator)) {
55 return ObjectiveKind.HIGHER_IS_BETTER;
56 } else {
57 throw new IllegalStateException("Only LOWER_IS_BETTER and HIGHER_IS_BETTER comparators are supported.");
58 }
59 }
60}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend
new file mode 100644
index 00000000..d355f5be
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend
@@ -0,0 +1,48 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import org.eclipse.viatra.dse.base.ThreadContext
4import org.eclipse.viatra.query.runtime.api.IPatternMatch
5import org.eclipse.viatra.query.runtime.api.IQuerySpecification
6import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
7
8class QueryBasedObjective extends DirectionalThresholdObjective {
9 val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification
10 ViatraQueryMatcher<? extends IPatternMatch> matcher
11
12 new(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification,
13 ObjectiveKind kind, ObjectiveThreshold threshold, int level) {
14 super(querySpecification.simpleName + " objective", kind, threshold, level)
15 if (querySpecification.parameters.size != 1) {
16 throw new IllegalArgumentException("Objective query must have a single parameter")
17 }
18 this.querySpecification = querySpecification
19 }
20
21 override createNew() {
22 new QueryBasedObjective(querySpecification, kind, threshold, level)
23 }
24
25 override init(ThreadContext context) {
26 matcher = querySpecification.getMatcher(context.queryEngine)
27 }
28
29 override protected getRawFitness(ThreadContext context) {
30 val iterator = matcher.allMatches.iterator
31 if (!iterator.hasNext) {
32 return invalidValue
33 }
34 val value = iterator.next.get(0)
35 if (iterator.hasNext) {
36 throw new IllegalStateException("Multiple matches for objective query")
37 }
38 if (value instanceof Number) {
39 value.doubleValue
40 } else {
41 throw new IllegalStateException("Objective value is not an instance of Number")
42 }
43 }
44
45 private def getInvalidValue() {
46 kind.invalidValue
47 }
48}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend
new file mode 100644
index 00000000..9b1a7e9f
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend
@@ -0,0 +1,80 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.BoundSaturationListener
4import java.util.Map
5import org.eclipse.viatra.dse.base.ThreadContext
6import org.eclipse.xtend.lib.annotations.Accessors
7
8class ThreeValuedCostObjective extends AbstractThreeValuedObjective implements BoundSaturationListener {
9 @Accessors val Map<String, CostElementMatchers> matchers
10 double lowerBoundHint = Double.NEGATIVE_INFINITY
11 double upperBoundHint = Double.POSITIVE_INFINITY
12
13 new(String name, Map<String, CostElementMatchers> matchers, ObjectiveKind kind, ObjectiveThreshold threshold,
14 int level) {
15 super(name, kind, threshold, level)
16 this.matchers = matchers
17 }
18
19 override createNew() {
20 // new ThreeValuedCostObjective(name, matchers, kind, threshold, level)
21 throw new UnsupportedOperationException("ThreeValuedCostObjective can only be used from a single thread")
22 }
23
24 override init(ThreadContext context) {
25 }
26
27 override getRawFitness(ThreadContext context) {
28 var double cost = 0
29 for (matcher : matchers.values) {
30 cost += matcher.weight * matcher.currentNumberOfMatches
31 }
32 cost
33 }
34
35 override getLowestPossibleFitness(ThreadContext threadContext) {
36 var double cost = 0
37 for (matcher : matchers.values) {
38 if (matcher.weight >= 0) {
39 cost += matcher.weight * matcher.minimumNumberOfMatches
40 } else {
41 cost += matcher.weight * matcher.maximumNumberOfMatches
42 }
43 }
44 val boundWithHint = Math.max(lowerBoundHint, cost)
45 if (boundWithHint > upperBoundHint) {
46 throw new IllegalStateException("Inconsistent cost bounds")
47 }
48 boundWithHint
49 }
50
51 override getHighestPossibleFitness(ThreadContext threadContext) {
52 var double cost = 0
53 for (matcher : matchers.values) {
54 if (matcher.weight <= 0) {
55 cost += matcher.weight * matcher.minimumNumberOfMatches
56 } else {
57 cost += matcher.weight * matcher.maximumNumberOfMatches
58 }
59 }
60 val boundWithHint = Math.min(upperBoundHint, cost)
61 if (boundWithHint < lowerBoundHint) {
62 throw new IllegalStateException("Inconsistent cost bounds")
63 }
64 boundWithHint
65 }
66
67 override boundsSaturated(Integer lower, Integer upper) {
68 lowerBoundHint = if (lower === null) {
69 Double.NEGATIVE_INFINITY
70 } else {
71 lower
72 }
73 upperBoundHint = if (upper === null) {
74 Double.POSITIVE_INFINITY
75 } else {
76 upper
77 }
78 println('''Bounds saturated: «lower»..«upper»''')
79 }
80}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjectiveProvider.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjectiveProvider.xtend
new file mode 100644
index 00000000..c2750acd
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjectiveProvider.xtend
@@ -0,0 +1,205 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization
2
3import com.google.common.collect.ImmutableList
4import com.google.common.collect.ImmutableMap
5import com.google.common.collect.Lists
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference
7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference
8import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntTypeReference
9import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference
10import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
11import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.StringTypeReference
12import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDeclaration
13import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeReference
14import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.TransfomedViatraQuery
15import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedronExtensionOperator
16import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.ModalPatternQueries
17import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialBooleanInterpretation
18import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
19import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialIntegerInterpretation
20import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
21import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRealInterpretation
22import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialStringInterpretation
23import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope
24import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.CostObjectiveConfiguration
25import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.CostObjectiveElementConfiguration
26import java.util.Collection
27import java.util.Map
28import org.eclipse.viatra.dse.objectives.IObjective
29import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
30import org.eclipse.xtend.lib.annotations.Data
31
32@Data
33class ThreeValuedCostObjectiveProviderResult {
34 val Collection<IObjective> objectives
35 val Collection<CostObjectiveHint> hints
36 val Collection<PolyhedronExtensionOperator> extensionOperators
37 val IObjective[][] leveledExtremalObjectives
38 val boolean optimizationProblem
39}
40
41class ThreeValuedCostObjectiveProvider {
42 static val COST_OBJECTIVE_LEVEL = 3
43
44 val ViatraQueryEngine queryEngine
45 val Map<String, ModalPatternQueries> modalRelationQueries
46 val Map<String, Relation> qualifiedNameToRelationMap
47 val ParameterScopeBound defaultBounds
48 val ParameterScopeBound booleanBounds
49 val ParameterScopeBound integerBounds
50 val ParameterScopeBound realBounds
51 val ParameterScopeBound stringBounds
52 val Map<TypeDeclaration, ParameterScopeBound> typeDeclarationToBoundsMap
53
54 new(ViatraQueryEngine queryEngine, PartialInterpretation interpretation,
55 Map<String, ModalPatternQueries> modalRelationQueries) {
56 this.queryEngine = queryEngine
57 this.modalRelationQueries = modalRelationQueries
58 qualifiedNameToRelationMap = ImmutableMap.copyOf(
59 interpretation.problem.annotations.filter(TransfomedViatraQuery).
60 toMap([patternFullyQualifiedName], [target]))
61 defaultBounds = new PartialInterpretationBasedParameterScopeBound(interpretation)
62 var ParameterScopeBound booleanBounds = null
63 var ParameterScopeBound integerBounds = null
64 var ParameterScopeBound realBounds = null
65 var ParameterScopeBound stringBounds = null
66 val typeDeclarationToBoundsMapBuilder = ImmutableMap.builder
67 for (scope : interpretation.scopes) {
68 val bounds = new ScopeBasedParameterScopeBound(scope)
69 switch (typeInterpretation : scope.targetTypeInterpretation) {
70 PartialBooleanInterpretation:
71 if (booleanBounds === null) {
72 booleanBounds = bounds
73 } else {
74 throw new IllegalStateException("Duplicate partial boolean interpretation")
75 }
76 PartialIntegerInterpretation:
77 if (integerBounds === null) {
78 integerBounds = bounds
79 } else {
80 throw new IllegalStateException("Duplicate partial integer interpretation")
81 }
82 PartialRealInterpretation:
83 if (realBounds === null) {
84 realBounds = bounds
85 } else {
86 throw new IllegalStateException("Duplicate partial real interpretation")
87 }
88 PartialStringInterpretation:
89 if (stringBounds === null) {
90 stringBounds = bounds
91 } else {
92 throw new IllegalStateException("Duplicate partial string interpretation")
93 }
94 PartialComplexTypeInterpretation:
95 typeDeclarationToBoundsMapBuilder.put(typeInterpretation.interpretationOf, bounds)
96 }
97 }
98 this.booleanBounds = booleanBounds ?: defaultBounds
99 this.integerBounds = integerBounds ?: defaultBounds
100 this.realBounds = realBounds ?: defaultBounds
101 this.stringBounds = stringBounds ?: defaultBounds
102 typeDeclarationToBoundsMap = typeDeclarationToBoundsMapBuilder.build
103 }
104
105 def getCostObjectives(Collection<CostObjectiveConfiguration> costObjectives) {
106 val objectives = ImmutableList.<IObjective>builder
107 val hints = ImmutableList.<CostObjectiveHint>builder
108 val extensionOperators = ImmutableList.<PolyhedronExtensionOperator>builder
109 val extremalObjectives = Lists.newArrayListWithExpectedSize(costObjectives.size)
110 for (entry : costObjectives.indexed) {
111 val objectiveName = '''costObjective«entry.key»'''
112 val objectiveConfig = entry.value
113 val costObjective = transformCostObjective(objectiveConfig, objectiveName)
114 objectives.add(costObjective)
115 if (objectiveConfig.findExtremum) {
116 extremalObjectives += costObjective
117 }
118 val hint = objectiveConfig.hint
119 if (hint !== null) {
120 hints.add(hint)
121 hint.objective = costObjective
122 val extensionOperator = hint.createPolyhedronExtensionOperator(costObjective.matchers)
123 if (extensionOperator !== null) {
124 extensionOperators.add(extensionOperator)
125 }
126 }
127 }
128 new ThreeValuedCostObjectiveProviderResult(
129 objectives.build,
130 hints.build,
131 extensionOperators.build,
132 newArrayList(extremalObjectives),
133 !extremalObjectives.empty
134 )
135 }
136
137 private def transformCostObjective(CostObjectiveConfiguration configuration, String name) {
138 val costElements = ImmutableMap.copyOf(configuration.elements.toMap([patternQualifiedName], [
139 transformCostElement
140 ]))
141 new ThreeValuedCostObjective(name, costElements, configuration.kind, configuration.threshold,
142 COST_OBJECTIVE_LEVEL)
143 }
144
145 private def transformCostElement(CostObjectiveElementConfiguration elementConfig) {
146 val relationName = elementConfig.patternQualifiedName
147 val modalQueries = modalRelationQueries.get(relationName)
148 if (modalQueries === null) {
149 throw new IllegalArgumentException("Unknown relation queries: " + relationName)
150 }
151 val relation = qualifiedNameToRelationMap.get(relationName)
152 if (relation === null) {
153 throw new IllegalArgumentException("Unknown transformed relation: " + relationName)
154 }
155 val parameterBounds = ImmutableList.copyOf(relation.parameters.map[parameterBound])
156 new CostElementMatchers(
157 queryEngine.getMatcher(modalQueries.currentQuery),
158 queryEngine.getMatcher(modalQueries.mayQuery),
159 queryEngine.getMatcher(modalQueries.mustQuery),
160 parameterBounds,
161 elementConfig.weight
162 )
163 }
164
165 private def getParameterBound(TypeReference typeReference) {
166 switch (typeReference) {
167 BoolTypeReference: booleanBounds
168 IntTypeReference: integerBounds
169 RealTypeReference: realBounds
170 StringTypeReference: stringBounds
171 ComplexTypeReference: typeDeclarationToBoundsMap.getOrDefault(typeReference.referred, defaultBounds)
172 }
173 }
174
175 private static abstract class AbstractParameterScopeBound implements ParameterScopeBound {
176 override getUpperBound() {
177 val rawValue = rawUpperBound
178 if (rawValue < 0) {
179 Double.POSITIVE_INFINITY
180 } else {
181 rawValue
182 }
183 }
184
185 protected def int getRawUpperBound()
186 }
187
188 @Data
189 private static class ScopeBasedParameterScopeBound extends AbstractParameterScopeBound {
190 val Scope scope
191
192 override protected getRawUpperBound() {
193 scope.maxNewElements
194 }
195 }
196
197 @Data
198 private static class PartialInterpretationBasedParameterScopeBound extends AbstractParameterScopeBound {
199 val PartialInterpretation interpretation
200
201 override protected getRawUpperBound() {
202 interpretation.maxNewElements
203 }
204 }
205}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/META-INF/MANIFEST.MF b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/META-INF/MANIFEST.MF
index 2abc6d50..754ff55d 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/META-INF/MANIFEST.MF
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/META-INF/MANIFEST.MF
@@ -27,8 +27,7 @@ Require-Bundle: com.google.guava,
27 org.apache.batik.util.gui;bundle-version="[1.6.0,1.6.1]", 27 org.apache.batik.util.gui;bundle-version="[1.6.0,1.6.1]",
28 org.apache.xerces;bundle-version="2.9.0", 28 org.apache.xerces;bundle-version="2.9.0",
29 org.w3c.dom.svg;bundle-version="1.1.0", 29 org.w3c.dom.svg;bundle-version="1.1.0",
30 org.w3c.css.sac;bundle-version="1.3.1", 30 org.w3c.css.sac;bundle-version="1.3.1"
31 org.eclipse.m2e.maven.runtime.slf4j.simple;bundle-version="1.10.0"
32Import-Package: com.eclipsesource.v8;version="4.6.0", 31Import-Package: com.eclipsesource.v8;version="4.6.0",
33 com.eclipsesource.v8.debug;version="4.6.0", 32 com.eclipsesource.v8.debug;version="4.6.0",
34 com.eclipsesource.v8.utils;version="4.6.0", 33 com.eclipsesource.v8.utils;version="4.6.0",
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/GraphvizV8WithMemory.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/GraphvizV8WithMemory.xtend
new file mode 100644
index 00000000..542289d4
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/GraphvizV8WithMemory.xtend
@@ -0,0 +1,16 @@
1package hu.bme.mit.inf.dslreasoner.visualisation.pi2graphviz
2
3import guru.nidi.graphviz.engine.GraphvizV8Engine
4
5class GraphvizV8WithMemory extends GraphvizV8Engine {
6 val int memory;
7 new(int memory) {
8 this.memory = memory
9 //this.
10 }
11
12 override protected jsInitEnv() {
13 println super.jsInitEnv()
14 super.jsInitEnv()
15 }
16}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/PartialInterpretation2Graphviz.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/PartialInterpretation2Graphviz.xtend
index 78326207..cd0b3e00 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/PartialInterpretation2Graphviz.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/PartialInterpretation2Graphviz.xtend
@@ -30,6 +30,7 @@ import org.eclipse.xtext.xbase.lib.Functions.Function1
30import static guru.nidi.graphviz.model.Factory.* 30import static guru.nidi.graphviz.model.Factory.*
31 31
32import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* 32import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
33import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PrimitiveElement
33 34
34class GraphvizVisualiser implements PartialInterpretationVisualiser { 35class GraphvizVisualiser implements PartialInterpretationVisualiser {
35 36
@@ -106,10 +107,10 @@ class GraphvizVisualiser implements PartialInterpretationVisualiser {
106// elements2Node.put(newElement,image) 107// elements2Node.put(newElement,image)
107// } 108// }
108 109
109 partialInterpretation.newElements.filter(BooleanElement).drawDataTypes([it.value.toString],elements2Node,elements2ID) 110 //partialInterpretation.newElements.filter(BooleanElement).drawDataTypes([it.value.toString],elements2Node,elements2ID)
110 partialInterpretation.newElements.filter(IntegerElement).drawDataTypes([it.value.toString],elements2Node,elements2ID) 111 //partialInterpretation.newElements.filter(IntegerElement).drawDataTypes([it.value.toString],elements2Node,elements2ID)
111 partialInterpretation.newElements.filter(StringElement).drawDataTypes(['''"«it.value.toString»"'''],elements2Node,elements2ID) 112 //partialInterpretation.newElements.filter(StringElement).drawDataTypes(['''"«it.value.toString»"'''],elements2Node,elements2ID)
112 partialInterpretation.newElements.filter(RealElement).drawDataTypes([it.value.toString],elements2Node,elements2ID) 113 //partialInterpretation.newElements.filter(RealElement).drawDataTypes([it.value.toString],elements2Node,elements2ID)
113 114
114 // Drawing the edges 115 // Drawing the edges
115 val edges = new HashMap 116 val edges = new HashMap
@@ -135,35 +136,51 @@ class GraphvizVisualiser implements PartialInterpretationVisualiser {
135 return new GraphvizVisualisation(graph) 136 return new GraphvizVisualisation(graph)
136 } 137 }
137 138
138 def protected <T extends DefinedElement> void drawDataTypes(Iterable<T> collection, Function1<T,String> namer, HashMap<DefinedElement, Node> elements2Node, HashMap<DefinedElement, String> elements2ID) { 139// def protected <T extends DefinedElement> void drawDataTypes(Iterable<T> collection, Function1<T,String> namer, HashMap<DefinedElement, Node> elements2Node, HashMap<DefinedElement, String> elements2ID) {
139 for(booleanElementIndex: 0..<collection.size) { 140// for(booleanElementIndex: 0..<collection.size) {
140 val newElement = collection.get(booleanElementIndex) 141// val newElement = collection.get(booleanElementIndex)
141 val id = namer.apply(newElement) 142// val name = namer.apply(newElement)
142 val image = drawElement(newElement,id,false,emptySet,emptySet) 143// val image = drawElement(newElement,name,newElement.lookup(elements2ID),false,emptySet,emptySet)
143 elements2ID.put(newElement,id) 144// elements2Node.put(newElement,image)
144 elements2Node.put(newElement,image) 145// }
145 } 146// }
146 }
147 147
148 def protected drawElement(DefinedElement element, String ID, boolean old, Set<Type> mustTypes, Set<Type> mayTypes) { 148 def protected drawElement(DefinedElement element, String ID, boolean old, Set<Type> mustTypes, Set<Type> mayTypes) {
149 var tableStyle = ''' CELLSPACING="0" BORDER="2" CELLBORDER="0" CELLPADDING="1" STYLE="ROUNDED"''' 149 var tableStyle = ''' CELLSPACING="0" BORDER="2" CELLBORDER="0" CELLPADDING="1" STYLE="ROUNDED"'''
150 if(typeColoringStyle==TypeColoringStyle::AVERAGE) { 150 if(typeColoringStyle==TypeColoringStyle::AVERAGE) {
151 tableStyle += ''' BGCOLOR="#«typePredicateColor(mustTypes).toBackgroundColorString»"''' 151 tableStyle += ''' BGCOLOR="#«typePredicateColor(mustTypes).toBackgroundColorString»"'''
152 } 152 }
153 val mainLabel = if(element.name !== null) { 153 val mainLabel = if(element instanceof PrimitiveElement) {
154 if(element.isValueSet) {
155 if(element instanceof BooleanElement) { element.value.toString }
156 else if(element instanceof IntegerElement) { element.value.toString }
157 else if(element instanceof RealElement) { element.value.toString }
158 else if(element instanceof StringElement) { "\""+element.value.toString+"\"" }
159 } else {
160 "?"
161 }
162 }else if(element.name !== null) {
154 val parts = element.name.split("\\s+") 163 val parts = element.name.split("\\s+")
155 textWithSubSup(parts.getOrNull(0),parts.getOrNull(1),parts.getOrNull(2),null) 164 textWithSubSup(parts.getOrNull(0),parts.getOrNull(1),parts.getOrNull(2),null)
156 } else { 165 } else {
157 val parts = ID.split("\\s+") 166 val parts = ID.split("\\s+")
158 textWithSubSup(parts.get(0),parts.get(1),parts.getOrNull(2),null) 167 textWithSubSup(parts.getOrNull(0),parts.getOrNull(1),parts.getOrNull(2),null)
159 } 168 }
160 val label = Label.html( 169 val hasNoCompexType = (mustTypes.empty) && (mayTypes.empty)
170
171 val label = if(hasNoCompexType) {
172 Label.html(
173 '''<TABLE«tableStyle»>'''+
174 '''<TR><TD COLSPAN="2"> «mainLabel» </TD></TR>'''+
175 '''</TABLE>''')
176 } else {
177 Label.html(
161 '''<TABLE«tableStyle»>'''+ 178 '''<TABLE«tableStyle»>'''+
162 '''<TR><TD COLSPAN="2" BORDER="2" SIDES="B">«mainLabel»</TD></TR>'''+ 179 '''<TR><TD COLSPAN="2" BORDER="2" SIDES="B">«mainLabel»</TD></TR>'''+
163 '''«FOR mustTypeName : mustTypes.map[it.name].sort»«typePredicateDescription(mustTypeName,true)»«ENDFOR»'''+ 180 '''«FOR mustTypeName : mustTypes.map[it.name].sort»«typePredicateDescription(mustTypeName,true)»«ENDFOR»'''+
164 '''«FOR mayTypeName : mayTypes.map[it.name].sort»«typePredicateDescription(mayTypeName,false)»«ENDFOR»'''+ 181 '''«FOR mayTypeName : mayTypes.map[it.name].sort»«typePredicateDescription(mayTypeName,false)»«ENDFOR»'''+
165 '''</TABLE>''') 182 '''</TABLE>''')
166 183 }
167 val node = node(ID).with(label).with( 184 val node = node(ID).with(label).with(
168 Shape.NONE 185 Shape.NONE
169 //, 186 //,
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/VisualisationQueque.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/VisualisationQueque.xtend
index b067ba7d..6f003f80 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/VisualisationQueque.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.visualisation/src/hu/bme/mit/inf/dslreasoner/visualisation/pi2graphviz/VisualisationQueque.xtend
@@ -3,15 +3,15 @@ package hu.bme.mit.inf.dslreasoner.visualisation.pi2graphviz
3import guru.nidi.graphviz.engine.Format 3import guru.nidi.graphviz.engine.Format
4import guru.nidi.graphviz.engine.Graphviz 4import guru.nidi.graphviz.engine.Graphviz
5import guru.nidi.graphviz.engine.GraphvizEngine 5import guru.nidi.graphviz.engine.GraphvizEngine
6import guru.nidi.graphviz.engine.GraphvizV8Engine
7import guru.nidi.graphviz.model.Graph 6import guru.nidi.graphviz.model.Graph
8import java.io.File 7import java.io.File
9import java.io.IOException 8import java.io.IOException
10import java.util.concurrent.BlockingQueue 9import java.util.concurrent.BlockingQueue
11import java.util.concurrent.CompletableFuture 10import java.util.concurrent.CompletableFuture
12import java.util.concurrent.LinkedBlockingQueue 11import java.util.concurrent.LinkedBlockingQueue
13import org.eclipse.xtend.lib.annotations.Data
14import java.util.function.Consumer 12import java.util.function.Consumer
13import org.eclipse.xtend.lib.annotations.Data
14import guru.nidi.graphviz.engine.GraphvizV8Engine
15 15
16class VisualisationQueque { 16class VisualisationQueque {
17 val BlockingQueue<VisualisationQueueEntry> taskQueue = new LinkedBlockingQueue 17 val BlockingQueue<VisualisationQueueEntry> taskQueue = new LinkedBlockingQueue
@@ -45,7 +45,7 @@ class VisualisationQueque {
45 } else { 45 } else {
46 runnerThread = new Thread(new Runnable() { 46 runnerThread = new Thread(new Runnable() {
47 override run() { 47 override run() {
48 val engine = new GraphvizV8Engine() 48 val engine = new GraphvizV8Engine
49 val nullConsumer = new Consumer<GraphvizEngine>() { 49 val nullConsumer = new Consumer<GraphvizEngine>() {
50 override accept(GraphvizEngine t) {} 50 override accept(GraphvizEngine t) {}
51 } 51 }
@@ -69,7 +69,7 @@ class VisualisationQueque {
69 private def execute(GraphvizEngine engine, Graph document, File targetFile, Format format) { 69 private def execute(GraphvizEngine engine, Graph document, File targetFile, Format format) {
70 Graphviz.useEngine(engine); 70 Graphviz.useEngine(engine);
71 try { 71 try {
72 Graphviz.fromGraph(document).render(format).toFile(targetFile) 72 Graphviz.fromGraph(document).totalMemory(536870912).render(format).toFile(targetFile)
73 return null 73 return null
74 } catch(IOException e){ 74 } catch(IOException e){
75 return e.message 75 return e.message
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.classpath b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.classpath
new file mode 100644
index 00000000..ed0eb24c
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.classpath
@@ -0,0 +1,7 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<classpath>
3 <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
4 <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
5 <classpathentry kind="src" path="src/"/>
6 <classpathentry kind="output" path="bin"/>
7</classpath>
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.project b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.project
new file mode 100644
index 00000000..aa414f43
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.project
@@ -0,0 +1,28 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<projectDescription>
3 <name>org.eclipse.viatra.dse</name>
4 <comment></comment>
5 <projects>
6 </projects>
7 <buildSpec>
8 <buildCommand>
9 <name>org.eclipse.jdt.core.javabuilder</name>
10 <arguments>
11 </arguments>
12 </buildCommand>
13 <buildCommand>
14 <name>org.eclipse.pde.ManifestBuilder</name>
15 <arguments>
16 </arguments>
17 </buildCommand>
18 <buildCommand>
19 <name>org.eclipse.pde.SchemaBuilder</name>
20 <arguments>
21 </arguments>
22 </buildCommand>
23 </buildSpec>
24 <natures>
25 <nature>org.eclipse.pde.PluginNature</nature>
26 <nature>org.eclipse.jdt.core.javanature</nature>
27 </natures>
28</projectDescription>
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.settings/org.eclipse.jdt.core.prefs b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..9f6ece88
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
1eclipse.preferences.version=1
2org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
4org.eclipse.jdt.core.compiler.compliance=1.8
5org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
6org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
7org.eclipse.jdt.core.compiler.release=disabled
8org.eclipse.jdt.core.compiler.source=1.8
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/MANIFEST.MF b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..fabef844
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/MANIFEST.MF
@@ -0,0 +1,387 @@
1Manifest-Version: 1.0
2Automatic-Module-Name: org.eclipse.viatra.dse
3Bundle-SymbolicName: org.eclipse.viatra.dse;singleton:=true
4Require-Bundle: org.eclipse.viatra.query.runtime;bundle-version="[2.4.
5 0,2.5.0)";visibility:=reexport,org.eclipse.viatra.transformation.evm;
6 bundle-version="[2.4.0,2.5.0)";visibility:=reexport,org.eclipse.emf.e
7 core,org.eclipse.emf.ecore.xmi;bundle-version="2.7.0",org.eclipse.emf
8 .edit,org.eclipse.viatra.transformation.runtime.emf;bundle-version="[
9 2.4.0,2.5.0)";visibility:=reexport
10Bundle-ManifestVersion: 2
11Bundle-RequiredExecutionEnvironment: JavaSE-1.8
12Bundle-ActivationPolicy: lazy
13Eclipse-SourceReferences: scm:git:git://git.eclipse.org/gitroot/viatra
14 /org.eclipse.viatra.git;path="dse/plugins/org.eclipse.viatra.dse";com
15 mitId=2a7314b6b21df594743fa017d18ae62da85c73fa
16Bundle-Vendor: Eclipse VIATRA Project
17Import-Package: com.google.common.base;version="27.1.0",com.google.com
18 mon.collect;version="27.1.0",com.google.common.util.concurrent;versio
19 n="27.1.0",org.apache.log4j;version="1.2.15"
20Export-Package: org.eclipse.viatra.dse.api,org.eclipse.viatra.dse.api.
21 strategy.impl,org.eclipse.viatra.dse.api.strategy.interfaces,org.ecli
22 pse.viatra.dse.base,org.eclipse.viatra.dse.designspace.api,org.eclips
23 e.viatra.dse.multithreading,org.eclipse.viatra.dse.objectives,org.ecl
24 ipse.viatra.dse.objectives.impl,org.eclipse.viatra.dse.solutionstore,
25 org.eclipse.viatra.dse.statecode,org.eclipse.viatra.dse.statecoding,o
26 rg.eclipse.viatra.dse.statecoding.simple,org.eclipse.viatra.dse.util,
27 org.eclipse.viatra.dse.visualizer
28SCM-Revision: 2a7314b6b21df594743fa017d18ae62da85c73fa
29Bundle-Name: VIATRA-DSE framework Base (Incubation)
30Bundle-Version: 0.24.0.202005060951
31Build-Jdk-Spec: 1.8
32Created-By: Maven Archiver 3.5.0
33
34Name: org/eclipse/viatra/dse/objectives/impl/NoRuleActivationsHardObje
35 ctive.class
36SHA-256-Digest: nEIutogP27RZKAUo9eH/DshkhyOF8voUnj4BC/pkhYU=
37
38Name: org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder$1.cla
39 ss
40SHA-256-Digest: t7KG11FngBrFGTPHJuEaP5BvpPqRYMDq8qKuQyccRWQ=
41
42Name: org/eclipse/viatra/dse/base/ThreadContext.class
43SHA-256-Digest: 0Z+RpFCBKvn1+SVJSLpRbEpoMATPujvvfqGsBr99mBI=
44
45Name: org/eclipse/viatra/dse/objectives/impl/ModelQueriesGlobalConstra
46 int.class
47SHA-256-Digest: 3qw4e1RY7TqpTKHRngBjCRWfJmMmu+DiUnKHO0yXVA4=
48
49Name: org/eclipse/viatra/dse/objectives/IObjective.class
50SHA-256-Digest: io0MQDhFysUXcHYcPUZENsy/xLn98SE65b2RbJ7QttM=
51
52Name: org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder.class
53SHA-256-Digest: yOvisOPQT9D/tuLV5fLonIoDpqi8bSRbPVjtLtv4UKo=
54
55Name: org/eclipse/viatra/dse/base/ExplorerThread.class
56SHA-256-Digest: N4tY8yMnFoKGoMyS0RdRtqpGIh6ucbvvAxnf/YPr/xk=
57
58Name: org/eclipse/viatra/dse/solutionstore/SolutionStore$BestSolutionS
59 aver.class
60SHA-256-Digest: yZkg5ntRMOsrKEgo7kkAaK5J8h11Ng8tzH4QXsLRhsM=
61
62Name: org/eclipse/viatra/dse/api/strategy/impl/RandomSearchStrategy$Sh
63 aredData.class
64SHA-256-Digest: 2jBwT4lfAUh7LDDmpi3JuzyjcWhVeb+53PPB5ZKlGx4=
65
66Name: org/eclipse/viatra/dse/base/DseIdPoolHelper$IGetRuleExecutions.c
67 lass
68SHA-256-Digest: s7Pr9OPNF5baYmoZlOTWl6keA+b1TVxV8zxBXMGewrM=
69
70Name: org/eclipse/viatra/dse/api/strategy/impl/RandomSearchStrategy.cl
71 ass
72SHA-256-Digest: 0R8ENAT9UA3BCsveA38VjvR4k+Um3i1fFlQB85inLZY=
73
74Name: org/eclipse/viatra/dse/api/DesignSpaceExplorer.class
75SHA-256-Digest: JCDN006fVS56ROn6cV7Ssdl4CN+xtbdiWjVfDkkgRDM=
76
77Name: org/eclipse/viatra/dse/util/EMFHelper$ENamedElementComparator.cl
78 ass
79SHA-256-Digest: J8o5TEdYpuU/6q1qTw3lUIHaE4pEH/EpDUvuTNWusVA=
80
81Name: org/eclipse/viatra/dse/util/ValueComparableEObjectStringMap$EObj
82 ectComparator.class
83SHA-256-Digest: iwLJSS2Ip9WvN2lC8gfg+ys5Cp+P7ZSpGP6QF5lKYKQ=
84
85Name: org/eclipse/viatra/dse/api/DesignSpaceExplorer$DseLoggingLevel.c
86 lass
87SHA-256-Digest: z3h4wzaSMGzPvV4KL6ilStnLdT/mVCNNp7C/AwfQhqk=
88
89Name: org/eclipse/viatra/dse/multithreading/DSEThreadPool.class
90SHA-256-Digest: XoKcmDnafPfiyQ0LemN0ni31T+aY+lXp/Q8p157kj/g=
91
92Name: org/eclipse/viatra/dse/api/strategy/impl/DepthFirstStrategy.clas
93 s
94SHA-256-Digest: SGlKz9PbynZwkmaJ1rpE0kVUOHl7vl7GOscNFoNEHLg=
95
96Name: org/eclipse/viatra/dse/base/GlobalContext.class
97SHA-256-Digest: dLn/Iu9JVDaaKK21VeFAMDXGaJWROEJCWJjULwMzNik=
98
99Name: org/eclipse/viatra/dse/statecoding/IncrementalObjectProvider.cla
100 ss
101SHA-256-Digest: L0yK9bhku/F8MX/NyKoBuydeMbMgZir8N0BRcFzHnKs=
102
103Name: org/eclipse/viatra/dse/statecode/IStateCoderFactory.class
104SHA-256-Digest: 1GsfU5aBQs1ieo3dblcXFZ07oq9QzWr1NZLppgSdCOM=
105
106Name: org/eclipse/viatra/dse/base/DesignSpaceManager$1.class
107SHA-256-Digest: /suIApW5KeZ7OifoR8SRPc3gU+2B8/ZnWInhdpAOTd8=
108
109Name: org/eclipse/viatra/dse/objectives/ActivationFitnessProcessor.cla
110 ss
111SHA-256-Digest: vML6AN6aCbn/cKeccmvzRAai47jZJk0CpYhwFQdhwvI=
112
113Name: org/eclipse/viatra/dse/solutionstore/IdBasedSolutionNameProvider
114 .class
115SHA-256-Digest: QFWpXui2nID6PKhTHs/1e0gj9u8NiniES6/G0C/oSzM=
116
117Name: org/eclipse/viatra/dse/api/strategy/impl/BreadthFirstStrategy$Bf
118 sSharedObject.class
119SHA-256-Digest: wVno1chuJ8pYpfv5cpB0fjsGbO2s+2OWcaVQgoQb5+k=
120
121Name: org/eclipse/viatra/dse/objectives/TrajectoryFitness.class
122SHA-256-Digest: DIEgS7SFg5pWuxvFhRn3f7hBt8+qk1+40w9WpOkoyrc=
123
124Name: org/eclipse/viatra/dse/solutionstore/SolutionStore$1.class
125SHA-256-Digest: V5AAqo4/81KOegdl1Wl8jIBrH57y4TdYrj+wOzV2vdM=
126
127Name: org/eclipse/viatra/dse/api/Solution.class
128SHA-256-Digest: U71jRd/R8tarIiHM+dETwXiwwPcmXO5m82bDUp/Mduo=
129
130Name: org/eclipse/viatra/dse/util/EMFHelper$EmfHelperException.class
131SHA-256-Digest: +OCT0+wqq9XGCze/qDE8hh3zprFMBAnkR7H1J7k/Htk=
132
133Name: org/eclipse/viatra/dse/base/DseEvmRuleBase.class
134SHA-256-Digest: iRILqfjFCMPd020YX8dMyRaNlUGfEUTd4N3gnqQRtDo=
135
136Name: org/eclipse/viatra/dse/objectives/impl/TrajectoryCostSoftObjecti
137 ve.class
138SHA-256-Digest: wXSfFPucpZyh72nGKuKn83N63Orl75XUM9SkzKfFBi4=
139
140Name: org/eclipse/viatra/dse/api/DSETransformationRule.class
141SHA-256-Digest: 01Ngrz/qbLR6j/4z9NxvtD2jHQAHMl698POXw8BSpPY=
142
143Name: org/eclipse/viatra/dse/objectives/impl/ModelQueryType.class
144SHA-256-Digest: SS0yM7NbAU0U4KoA4Tzy4gXKZ2IZaszyaqbtSN4GE74=
145
146Name: org/eclipse/viatra/dse/base/DseConflictResolver.class
147SHA-256-Digest: kLquKehufJSc2fJoUgztO62ucr1UUqfLQpyiFrY8BJc=
148
149Name: org/eclipse/viatra/dse/statecoding/TheStateCoderFactory.class
150SHA-256-Digest: 7tog5/ud60nPTYwPT6HHpHBDeutpFl2KLKXt8GnM3U8=
151
152Name: org/eclipse/viatra/dse/solutionstore/LogSolutionHandler.class
153SHA-256-Digest: cbpeCy8w558CbnhljT2TKalNqWBpKlIsMppr6hWDRpw=
154
155Name: org/eclipse/viatra/dse/designspace/api/TrajectoryInfo.class
156SHA-256-Digest: mXYUokn/RePXJXnfL7O3AZjvwqFkwiLZ0IipQGgdp0A=
157
158Name: org/eclipse/viatra/dse/statecoding/StatecodingDependencyType.cla
159 ss
160SHA-256-Digest: ef+0X9EnYYjpPiRNmjXrElCCaPekh+Wh6yimRTpp15E=
161
162Name: org/eclipse/viatra/dse/objectives/impl/CompositeObjective.class
163SHA-256-Digest: SJiO5Oina3I760xBUDGc4qYp1WrcSG6Yh0+8hQKf69U=
164
165Name: org/eclipse/viatra/dse/objectives/ObjectiveComparatorHelper.clas
166 s
167SHA-256-Digest: +uKjMIfQvBlKY9djJoP5Wd/EBKMkbrdk7shGdZ0rS2M=
168
169Name: org/eclipse/viatra/dse/api/Objectives.class
170SHA-256-Digest: pNQDcSeUV3oOM7aCgscjJwdyysQrMSZCyLhrSWLMUrI=
171
172Name: org/eclipse/viatra/dse/visualizer/DesignSpaceVisualizerOptions.c
173 lass
174SHA-256-Digest: nf/uvPeNaC8Nu9SPhk+sgvSheB/kh+GqsXXHbm7qer0=
175
176Name: org/eclipse/viatra/dse/api/DSEException.class
177SHA-256-Digest: MCUPB2tBDK01enENQDJ+qONxtl+WQyZaJf87iU+NFyU=
178
179Name: org/eclipse/viatra/dse/base/SingletonSetConflictResolver.class
180SHA-256-Digest: bd4gh7UG91EkNSE0JrpAKbHDxv6HYhL7YEq7PZZkRjo=
181
182Name: org/eclipse/viatra/dse/statecoding/IObjectsProvider.class
183SHA-256-Digest: SIcYuklHbTwYjV+gvS1B77Z0CR/2bannTSL77/qm/Gs=
184
185Name: org/eclipse/viatra/dse/statecoding/IncrementalObjectProviderFact
186 ory.class
187SHA-256-Digest: F12xo+nr94L4B1m1w2xmtA7t1TzGin5pFSEqkBmYxC0=
188
189Name: org/eclipse/viatra/dse/api/SolutionTrajectory.class
190SHA-256-Digest: uFjxXsF4khsOwgCsmRPMZbSayZ4qTDtwPGxDBH2lG74=
191
192Name: org/eclipse/viatra/dse/solutionstore/SolutionStore$SimpleSolutio
193 nSaver.class
194SHA-256-Digest: 12aDZULU6fhdXx8a/BvCQwXW7RZfEmIPFueU7GOpBB0=
195
196Name: org/eclipse/viatra/dse/util/Hasher.class
197SHA-256-Digest: 0nFBMPZ6/YudYlnE/l8XiECkWIHBRvkdyi9WUCIaN4c=
198
199Name: org/eclipse/viatra/dse/solutionstore/ISolutionNameProvider.class
200SHA-256-Digest: Ig8utojCZoNY8V37gbZVVJFOX8NZiu2tPsnAIkS1BaU=
201
202Name: org/eclipse/viatra/dse/objectives/IGlobalConstraint.class
203SHA-256-Digest: UvJwqLRVvv444GgELIu/tUGs4eV8cf/Anqh6horECP8=
204
205Name: org/eclipse/viatra/dse/solutionstore/SolutionStore.class
206SHA-256-Digest: V9OJ/9GqLq9cBToiBzapjyCs3mDuk4PkeduT5YpiTwE=
207
208Name: org/eclipse/viatra/dse/objectives/impl/DepthHardObjective.class
209SHA-256-Digest: Ra8i2f1YiRldwF06QotRoHkhKJLyGMYJnS6Lco1ldTM=
210
211Name: org/eclipse/viatra/dse/objectives/impl/BaseObjective.class
212SHA-256-Digest: DH8BIQo1OvBt5oEtS4sqsjtGOhlD1Nwz2yv7gdW3/hA=
213
214Name: org/eclipse/viatra/dse/api/DesignSpaceExplorer$1.class
215SHA-256-Digest: 1AccsshxVCMI2GPkioO7lQtS9JwPx17YrPTSjTZfqBQ=
216
217Name: org/eclipse/viatra/dse/objectives/impl/ConstraintsObjective.clas
218 s
219SHA-256-Digest: +eesnPuyvrf4xQOslHAFlNIyd4K9scCn8f6qprCxKzs=
220
221Name: org/eclipse/viatra/dse/api/strategy/impl/FixedPriorityStrategy.c
222 lass
223SHA-256-Digest: /+Dkno94lswrX5YEr60iH8szAKDL9hfAe2ZZ/amSe20=
224
225Name: org/eclipse/viatra/dse/base/IDseStrategyContext.class
226SHA-256-Digest: ACDjZwH6zo71KF8hXuAvC7NWmGPDv9lJ06U/iAptwEw=
227
228Name: org/eclipse/viatra/dse/statecode/IStateCoder.class
229SHA-256-Digest: L+foclr4t9XV4ltc7aDor4Ngf135J+UvTpTxCcegz9M=
230
231Name: org/eclipse/viatra/dse/objectives/impl/NeverSatisfiedDummyHardOb
232 jective.class
233SHA-256-Digest: KB8QybGLqya7vrKCMnwRdCOaJ/URoTIeR1NVYDNiOB4=
234
235Name: org/eclipse/viatra/dse/objectives/impl/AlwaysSatisfiedDummyHardO
236 bjective.class
237SHA-256-Digest: TzG4kskc7rM96sfpJc6YsSNF7PyE48NJLkUpkkwqsiI=
238
239Name: org/eclipse/viatra/dse/base/DesignSpaceManager.class
240SHA-256-Digest: WlF2FWYiBFQNAW2PsPpPorz64wQBWssTC/73maFotD8=
241
242Name: org/eclipse/viatra/dse/visualizer/IExploreEventHandler.class
243SHA-256-Digest: ZJwhUYNU+L1B88hsbfdIejJVUwhnvBjJSDHugw+RFh0=
244
245Name: META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.pro
246 perties
247SHA-256-Digest: 0JWWPFaIUkYh4BehmajscXzAloPgjeIs0iZSPFC/g1g=
248
249Name: org/eclipse/viatra/dse/statecoding/StatecodingDependency.class
250SHA-256-Digest: AeHJlVqUAUsjBlYumYq/e/WEBNbtlvCk00SG9rHPO88=
251
252Name: org/eclipse/viatra/dse/api/strategy/interfaces/IStrategy.class
253SHA-256-Digest: K5feGvnijYpwPJCOvR4m7ChtC7wX7LhLaau5/SBnFek=
254
255Name: org/eclipse/viatra/dse/visualizer/IDesignSpaceVisualizer.class
256SHA-256-Digest: gF2AAXk6xxQIDqdn56Aeifqmj71pBicLO7VJJoB64bY=
257
258Name: org/eclipse/viatra/dse/solutionstore/SolutionStore$ANumberOfEnou
259 ghSolutions.class
260SHA-256-Digest: qAOxgehQKfKkDSF2W2Gk/cXkDIBsQuN4yJ8Q3eRCnps=
261
262Name: META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.xml
263SHA-256-Digest: /LSOqjjd6+fmn3MHbXK9bGr7k+1GKE3kgzaDoJkgCQQ=
264
265Name: org/eclipse/viatra/dse/base/DseIdPoolHelper$IdProvider.class
266SHA-256-Digest: VRQcpABZNkp3Lgivy9PUraJf04riM1MOZvY64suvo3M=
267
268Name: org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder$2.cla
269 ss
270SHA-256-Digest: NqiG7/1poRDLI2BbRvr2hfHZqH73hfFxBic+4YKHcCM=
271
272Name: org/eclipse/viatra/dse/base/ThreadContext$GetRuleExecutionsImpl.
273 class
274SHA-256-Digest: HGFHcAmOg3O3se9FT4oE4pWZ8EFdyRkkHkBVJZi+hmM=
275
276Name: org/eclipse/viatra/dse/api/strategy/impl/BestFirstStrategy.class
277SHA-256-Digest: qJyc4dMUiLGVoJPrMWQtCI2o2HW5p6Ki5J8Ra6wb/gE=
278
279Name: org/eclipse/viatra/dse/designspace/api/IDesignSpace.class
280SHA-256-Digest: IS5IjYyUCvaHWBvUsPFeGFv65W+YTG7u+iRXp/eDIuM=
281
282Name: org/eclipse/viatra/dse/api/strategy/impl/HillClimbingStrategy.cl
283 ass
284SHA-256-Digest: UfrnKlXVqN8LWbUPSoA5PDiJOT7cnCA46kIXicC5mg0=
285
286Name: org/eclipse/viatra/dse/api/strategy/impl/BestFirstStrategy$Traje
287 ctoryWithFitness.class
288SHA-256-Digest: n3K90JLwOOVAXsrkROhn0ZNogaAKVdcUpXBj8RUMI3c=
289
290Name: org/eclipse/viatra/dse/util/EMFHelper$MetaModelElements.class
291SHA-256-Digest: FjS8V9JksWMjbV9a1dn04gWFH3fctq9HdWSfbMsV5Ck=
292
293Name: org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoderFactor
294 y.class
295SHA-256-Digest: jcBdVzrTpamZrT0pQZHyJJnooB+DKF6ADVS4RRhZGl4=
296
297Name: org/eclipse/viatra/dse/objectives/Fitness.class
298SHA-256-Digest: CJPJnXYS0WMnW4JVW2YO5/vvwKhRkRE7qROa87Ailpg=
299
300Name: org/eclipse/viatra/dse/api/strategy/impl/BreadthFirstStrategy.cl
301 ass
302SHA-256-Digest: 4odjR0x9jzt7Ed/hw6Q+ydZUrQQggqL8y216Lq60azM=
303
304Name: org/eclipse/viatra/dse/api/Strategies.class
305SHA-256-Digest: tURHC++pafgodWMnk4CperJDpZ9m4Do6xHAV37bHUoc=
306
307Name: org/eclipse/viatra/dse/statecoding/StatecodingNode.class
308SHA-256-Digest: 2xM/ShgCBqpV9tgQZPBxzTSPgbT7lcp7auQE14dEEqc=
309
310Name: org/eclipse/viatra/dse/solutionstore/SolutionStore$ISolutionSave
311 r.class
312SHA-256-Digest: nuYmJKeNKfM0a9sAbRpA6Knzqu51hlK011aoAQpTH3Q=
313
314Name: org/eclipse/viatra/dse/statecoding/StatecodingDependencyGraph.cl
315 ass
316SHA-256-Digest: 9ZxUtKP6+hvWqY9l0b+opdginEK1BoksdLqZ+DYViqI=
317
318Name: org/eclipse/viatra/dse/util/EMFHelper.class
319SHA-256-Digest: hpOu0HMuLuiLYUbg0rhdfVG4/ZrlVftoKLmTsRAHW/E=
320
321Name: org/eclipse/viatra/dse/base/DesignSpaceManager$2.class
322SHA-256-Digest: x8i8lLzE/UkaQJya1kGbTlJnB/JFNy5607FLESkMQXA=
323
324Name: org/eclipse/viatra/dse/base/ActivationCodesConflictSet.class
325SHA-256-Digest: 0G/W2cxiS4R9GEpBWovAIEA4brmQ2sTjqi1F7vgS0/c=
326
327Name: org/eclipse/viatra/dse/api/SolutionTrajectory$1.class
328SHA-256-Digest: 7epxs7VJgi7Jmo2pKb22m2OLhOOIu3OHTJrWC8HjEzQ=
329
330Name: org/eclipse/viatra/dse/solutionstore/SolutionStore$IEnoughSoluti
331 ons.class
332SHA-256-Digest: /5Ux9DFOI3UHcG8om2rGzX2k0Yj1lIoeG/tR82P3zpQ=
333
334Name: org/eclipse/viatra/dse/objectives/impl/ConstraintsObjective$Quer
335 yConstraint.class
336SHA-256-Digest: 79pmTnUZbgOHEdGzyj5PIb2eGrd554q3c17LNdbTQxM=
337
338Name: org/eclipse/viatra/dse/objectives/Comparators.class
339SHA-256-Digest: V5MzedIHj3KBEBbR4UNAhqmbqB3sHuk183zxMlKhGD4=
340
341Name: org/eclipse/viatra/dse/statecoding/IObjectsProviderFactory.class
342SHA-256-Digest: VlWdfwyWo39xhvgIF9PedWC+Yv1Q0hYaDBSF7Z+ClSA=
343
344Name: org/eclipse/viatra/dse/base/GlobalContext$ExplorationProcessStat
345 e.class
346SHA-256-Digest: rNnsUlZX7z1yPBoNSfWvoXwKhSAjGUhpBo9CZVJwadw=
347
348Name: org/eclipse/viatra/dse/base/DseIdPoolHelper.class
349SHA-256-Digest: 8wUkapQg0xNS3Vy/Mtv18N9dEB9ev/QiH1tYPzFtBN8=
350
351Name: about.html
352SHA-256-Digest: Qx53vUKBh4ByLG9I8uUS7GH8BTecG5s70WKYlnHc04k=
353
354Name: org/eclipse/viatra/dse/solutionstore/ISolutionFoundHandler.class
355SHA-256-Digest: bjBZdHvq37DxouRprrTxR0l8CWUCY+aw5JtccbEeAJg=
356
357Name: org/eclipse/viatra/dse/designspace/api/DesignSpace.class
358SHA-256-Digest: D51XZw1Z2bCk+PxzX7i8WpE64L9s64FoedEMxM0fSYA=
359
360Name: org/eclipse/viatra/dse/util/ValueComparableEObjectStringMap.clas
361 s
362SHA-256-Digest: VYf9HcY2IbUo2d1K+c2rKIFkxNIRFeEi9zr9s1Inc7o=
363
364Name: org/eclipse/viatra/dse/statecoding/StatecodingNodeType.class
365SHA-256-Digest: VUsDepoiER2/0o3aIE8uX08eOdXzvKBkfXPpPaow5yU=
366
367Name: org/eclipse/viatra/dse/api/strategy/interfaces/IStrategyFactory.
368 class
369SHA-256-Digest: K51RjSOSyMrj86BO/zgmo4kO83HgxKvrEGeOTo5WoVs=
370
371Name: org/eclipse/viatra/dse/base/ActivationCodesConflictSet$Activatio
372 nCodesMultiBiMap.class
373SHA-256-Digest: DEtZHFLUnrSZG5x15o2lTasPd5+ufqWCCQXg+YXGxQA=
374
375Name: org/eclipse/viatra/dse/statecoding/TheStateCoder.class
376SHA-256-Digest: 7iWoLYIXKNGjRgpIHZDuW3i8wBpV5OqO978Fg9WxEK8=
377
378Name: org/eclipse/viatra/dse/objectives/LeveledObjectivesHelper.class
379SHA-256-Digest: HYJ6Z75XEjy3UGBB00bv/GfxdOey+9MpGM5aJuFm5fM=
380
381Name: org/eclipse/viatra/dse/solutionstore/ModelSaverSolutionFoundHand
382 ler.class
383SHA-256-Digest: CmINEWESAe5ynUDWoc8YQQdsmBx1bRLNabbzmoxxsUg=
384
385Name: org/eclipse/viatra/dse/base/DseConflictSet.class
386SHA-256-Digest: boreOAKc8L3ZEts53PUwZiZ4l+8Em3aLeXDQBJZihbY=
387
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.properties b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.properties
new file mode 100644
index 00000000..33746c20
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.properties
@@ -0,0 +1,3 @@
1artifactId=org.eclipse.viatra.dse
2groupId=org.eclipse.viatra
3version=0.24.0-SNAPSHOT
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.xml b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.xml
new file mode 100644
index 00000000..4d50659f
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/META-INF/maven/org.eclipse.viatra/org.eclipse.viatra.dse/pom.xml
@@ -0,0 +1,14 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<project
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
4 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
5 <modelVersion>4.0.0</modelVersion>
6 <parent>
7 <artifactId>org.eclipse.viatra.parent.dse</artifactId>
8 <groupId>org.eclipse.viatra</groupId>
9 <version>0.24.0-SNAPSHOT</version>
10 <relativePath>../../../releng/org.eclipse.viatra.parent.dse/pom.xml</relativePath>
11 </parent>
12 <artifactId>org.eclipse.viatra.dse</artifactId>
13 <packaging>eclipse-plugin</packaging>
14</project> \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/about.html b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/about.html
new file mode 100644
index 00000000..4c69fcc0
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/about.html
@@ -0,0 +1,21 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
2<html>
3<head>
4<title>About</title>
5<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
6</head>
7<body lang="EN-US">
8<h2>About This Content</h2>
9
10<p>March 18, 2019</p>
11<h3>License</h3>
12
13<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
14Eclipse Public License Version 2.0 (&quot;EPL&quot;). A copy of the EPL is available at <a href="http://www.eclipse.org/org/documents/epl-v20.php">http://www.eclipse.org/legal/epl-v20.html</a>.
15For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
16
17<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
18apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
19indicated below, the terms and conditions of the EPL still apply to any source code in the Content and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
20</body>
21</html> \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/build.properties b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/build.properties
new file mode 100644
index 00000000..08373bf1
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/build.properties
@@ -0,0 +1,4 @@
1source.. = src/
2bin.includes = META-INF/,\
3 .,\
4 about.html
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSEException.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSEException.java
new file mode 100644
index 00000000..f0da19ed
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSEException.java
@@ -0,0 +1,47 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api;
10
11/**
12 * Represents a general runtime exception that happened during the execution of the design space exploration process.
13 * Problems that cause this exception are not recoverable within the scope of the design space exploration process.
14 */
15public class DSEException extends RuntimeException {
16
17 private static final long serialVersionUID = -8312212010574763824L;
18
19 /**
20 * @see RuntimeException#RuntimeException()
21 */
22 public DSEException() {
23 super();
24 }
25
26 /**
27 * @see RuntimeException#RuntimeException(String)
28 */
29 public DSEException(String message) {
30 super(message);
31 }
32
33 /**
34 * @see RuntimeException#RuntimeException(String, Throwable)
35 */
36 public DSEException(String message, Throwable cause) {
37 super(message, cause);
38 }
39
40 /**
41 * @see RuntimeException#RuntimeException(Throwable)
42 */
43 public DSEException(Throwable cause) {
44 super(cause);
45 }
46
47}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSETransformationRule.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSETransformationRule.java
new file mode 100644
index 00000000..8c3511ae
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DSETransformationRule.java
@@ -0,0 +1,51 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api;
10
11import java.util.Objects;
12import java.util.function.Consumer;
13
14import org.eclipse.viatra.query.runtime.api.IPatternMatch;
15import org.eclipse.viatra.query.runtime.api.IQuerySpecification;
16import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher;
17import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
18
19/**
20 * An instance of this class is a specification of a graph transformation rule on a given metamodel. Such a rule
21 * consists of a left hand side (LHS), which is specified by an {@link IQuerySpecification} and a right hand side (RHS),
22 * which is specified by an {@link Consumer}.
23 *
24 * @author Andras Szabolcs Nagy
25 *
26 * @param <Match>
27 * A VIATRA Query pattern match - left hand side of the rule
28 * @param <Matcher>
29 * A VIATRA Query pattern matcher - left hand side of the rule
30 * @deprecated
31 */
32@Deprecated
33public class DSETransformationRule<Match extends IPatternMatch, Matcher extends ViatraQueryMatcher<Match>> extends
34 BatchTransformationRule<Match, Matcher> {
35
36 public DSETransformationRule(String name, IQuerySpecification<Matcher> querySpec,
37 Consumer<Match> action) {
38 super(name, querySpec, BatchTransformationRule.STATELESS_RULE_LIFECYCLE, action);
39
40 Objects.requireNonNull(name);
41 Objects.requireNonNull(querySpec);
42 Objects.requireNonNull(action);
43
44 }
45
46 public DSETransformationRule(IQuerySpecification<Matcher> querySpec,
47 Consumer<Match> action) {
48 this(querySpec.getFullyQualifiedName(), querySpec, action);
49 }
50
51}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DesignSpaceExplorer.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DesignSpaceExplorer.java
new file mode 100644
index 00000000..9cd6e68a
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DesignSpaceExplorer.java
@@ -0,0 +1,622 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api;
10
11import java.util.Collection;
12import java.util.HashSet;
13import java.util.Set;
14import java.util.Timer;
15import java.util.TimerTask;
16import java.util.concurrent.atomic.AtomicBoolean;
17
18import org.apache.log4j.BasicConfigurator;
19import org.apache.log4j.Level;
20import org.apache.log4j.Logger;
21import org.eclipse.emf.common.notify.Notifier;
22import org.eclipse.emf.ecore.EObject;
23import org.eclipse.emf.ecore.EPackage;
24import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
25import org.eclipse.viatra.dse.base.DesignSpaceManager;
26import org.eclipse.viatra.dse.base.GlobalContext;
27import org.eclipse.viatra.dse.designspace.api.DesignSpace;
28import org.eclipse.viatra.dse.designspace.api.IDesignSpace;
29import org.eclipse.viatra.dse.objectives.IGlobalConstraint;
30import org.eclipse.viatra.dse.objectives.IObjective;
31import org.eclipse.viatra.dse.solutionstore.ISolutionNameProvider;
32import org.eclipse.viatra.dse.solutionstore.IdBasedSolutionNameProvider;
33import org.eclipse.viatra.dse.solutionstore.SolutionStore;
34import org.eclipse.viatra.dse.statecode.IStateCoder;
35import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
36import org.eclipse.viatra.dse.statecoding.simple.SimpleStateCoderFactory;
37import org.eclipse.viatra.dse.visualizer.IDesignSpaceVisualizer;
38import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
39import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver;
40import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
41
42/**
43 * <p>
44 * The {@link DesignSpaceExplorer} is the main API of the <b>Design Space Exploration</b> engine.
45 * </p>
46 *
47 * <p>
48 * To parameterize the algorithm one must use the following methods after instantiating:
49 * <ul>
50 * <li>{@link #setInitialModel(EObject)} or it's overloads to set the starting model.</li>
51 * <li>{@link #addTransformationRule(BatchTransformationRule)} to define the transformations.</li> <li
52 * {@link #addObjective(IObjective)} to define the objective functions. Use the {@link Objectives} helper class for
53 * instantiating built-in, configurable objectives.</li>
54 * <li>{@link #startExploration(IStrategy)} or it's overloads to start an exploration with the given exploration
55 * strategy. Use the {@link Strategies} helper class for instantiating built-in, configurable exploration strategies.
56 * </li>
57 * </ul>
58 * </p>
59 *
60 * <p>
61 * <b>Designs Space Exploration</b> is the process of finding a sequence (or sequences) of predefined transformation
62 * rules ("transitions") that, if applied in order on the starting model, results in a new model state that fulfills the
63 * hard (or goal) constraints and is near optimal with respect to the objectives.
64 * </p>
65 *
66 * <p>
67 * An extension to this paradigm is the introduction of global constraints, which guarantees, that no sequence will be
68 * returned, which if executed, results in an intermediate model state that violates the specified global constraints,
69 * including the final state. You can add constraints by invoking {@link #addGlobalConstraint(IGlobalConstraint)}.
70 * </p>
71 *
72 * @author Andras Szabolcs Nagy & Miklos Foldenyi
73 *
74 */
75public class DesignSpaceExplorer {
76
77 private Notifier model;
78
79 private GlobalContext globalContext = new GlobalContext();
80
81 private final Logger logger = Logger.getLogger(this.getClass());
82
83 private Set<EPackage> metaModelPackages = new HashSet<EPackage>();
84
85 private static final String MODEL_NOT_YET_GIVEN = "The starting model is not given yet. Please call the setInitialModel method first.";
86
87 private boolean deepCopyModel;
88
89 /**
90 * <p>
91 * Creates a {@link DesignSpaceExplorer} object that is able to execute a design space exploration process.
92 * </p>
93 *
94 * <p>
95 * By default the state coder used is the generic (not meta-model specific) {@link GraphHash}. You can provide your
96 * custom state coder by implementing the {@link IStateCoderFactory} and {@link IStateCoder} interfaces, and passing
97 * the former to the {@link #setStateCoderFactory(IStateCoderFactory)} method.
98 *
99 */
100 public DesignSpaceExplorer() {
101 setDesignspace(new DesignSpace());
102 }
103
104 /**
105 * Adds a metamodel in the form of {@link EPackage}, which is needed for certain guidance.
106 *
107 * @param metaModelPackage
108 */
109 public void addMetaModelPackage(EPackage metaModelPackage) {
110 metaModelPackages.add(metaModelPackage);
111 }
112
113 /**
114 * Defines the initial model of the exploration, and whether it is supposed to be used to execute the DSE process or
115 * it should be cloned. Please note, that in multithreaded mode any subsequent threads will be working on cloned
116 * models.
117 *
118 * @param model
119 * The root object of the EMF model.
120 * @param deepCopyModel
121 * If it is set to true, the exploration will run on a cloned model.
122 */
123 public void setInitialModel(Notifier model, boolean deepCopyModel) {
124 this.model = model;
125 this.deepCopyModel = deepCopyModel;
126 }
127
128 /**
129 * Defines the initial model of the exploration. The model will be cloned, which is desired in most cases as the
130 * given model won't be changed.
131 *
132 * @param model
133 * The root object of the EMF model.
134 */
135 public void setInitialModel(Notifier model) {
136 setInitialModel(model, true);
137 }
138
139 /**
140 * Defines the initial model of the exploration. The given model won't be cloned, thus the exploration will modify
141 * it.
142 *
143 * @param model
144 * The root object of the EMF model. It won't be cloned.
145 */
146 public void setInitialModelUncloned(Notifier model) {
147 setInitialModel(model, false);
148 }
149
150 /**
151 * Adds a {@link BatchTransformationRule}.
152 *
153 * @param rule
154 * The transformationRule.
155 */
156 public void addTransformationRule(BatchTransformationRule<?, ?> rule) {
157 Preconditions.checkArgument(rule != null);
158 for (BatchTransformationRule<?, ?> rule2 : globalContext.getTransformations()) {
159 if (rule.getPrecondition().equals(rule2.getPrecondition())) {
160 throw new DSEException(
161 "Two transformation rule ("
162 + rule.getName()
163 + "; "
164 + rule2.getName()
165 + ") uses the same LHS VIATRA Query pattern ("
166 + rule.getPrecondition().getFullyQualifiedName()
167 + "), which may lead to hash collision."
168 + " Please wrap the pattern with an other pattern with the 'find' keyword (or duplicate the code), and use that for one of the rules LHS.");
169 }
170 }
171
172 globalContext.getTransformations().add(rule);
173 }
174
175 /**
176 * Adds a global constraint to the exploration process. Please see the {@link IGlobalConstraint} interface and its
177 * implementations for details.
178 *
179 * @param constraint
180 * The global constraint.
181 * @see IGlobalConstraint
182 */
183 public void addGlobalConstraint(IGlobalConstraint constraint) {
184 globalContext.getGlobalConstraints().add(constraint);
185 }
186
187 /**
188 * Adds an objective the the exploration process. Please see the {@link IObjective} interface and its
189 * implementations for details.
190 *
191 * @param objective
192 * The objective.
193 * @see IObjective
194 */
195 public void addObjective(IObjective objective) {
196 for (IObjective o : globalContext.getObjectives()) {
197 if (o.getName().equals(objective.getName())) {
198 throw new DSEException("Two objectives with the same name cannot be registered:" + o.getName());
199 }
200 }
201 globalContext.getObjectives().add(objective);
202 }
203
204 /**
205 * Sets a {@link IStateCoderFactory} for which will be used for creating {@link IStateCoder}s. The default
206 * implementation is the {@link SimpleStateCoderFactory}, which works well in most of the cases.
207 *
208 * @param stateCoderFactory
209 * The factory.
210 */
211 public final void setStateCoderFactory(IStateCoderFactory stateCoderFactory) {
212 globalContext.setStateCoderFactory(stateCoderFactory);
213 }
214
215 /**
216 * Defines the maximum processing threads that the design space exploration can use. Note, that this is only
217 * limiting the threads doing the actual calculation. By default this value will be set to the number of logical
218 * processors (including HyperThreading) in the computer, reported by {@link Runtime#availableProcessors()}.
219 *
220 * @param maxNumberOfThreads
221 * The number of maximum processing threads available to the design space exploration process.
222 */
223 public void setMaxNumberOfThreads(int maxNumberOfThreads) {
224 globalContext.getThreadPool().setMaximumPoolSize(maxNumberOfThreads);
225 }
226
227 /**
228 * Sets the {@link IDesignSpace} implementation that is to be used during the design space exploration process. By
229 * default, the {@link DesignSpace} implementation is used.
230 *
231 * @param designspace
232 * The {@link IDesignSpace} implementation.
233 */
234 public final void setDesignspace(IDesignSpace designspace) {
235 globalContext.setDesignSpace(designspace);
236 }
237
238 /**
239 * Sets the solution store for strategies. Please see the {@link SolutionStore} for how to configure it.
240 *
241 * @param solutionStore
242 * The parameterized {@link SolutionStore} implementation.
243 */
244 public void setSolutionStore(SolutionStore solutionStore) {
245 globalContext.setSolutionStore(solutionStore);
246 }
247
248 /**
249 * Starts the design space exploration. It returns only when the strategy decides to stop the execution.
250 *
251 * @param strategy
252 * The strategy of the exploration.
253 */
254 public void startExploration(IStrategy strategy) {
255 startExploration(strategy, true, -1);
256 }
257
258 /**
259 * Starts the design space exploration asynchronously. Completion of the process can be verified by calling
260 * {@link DesignSpaceExplorer#isDone()}.
261 *
262 * @param strategy
263 * The strategy of the exploration.
264 */
265 public void startExplorationAsync(IStrategy strategy) {
266 startExploration(strategy, false, -1);
267 }
268
269 /**
270 * Starts the design space exploration with a timeout. It returns only when the strategy decides to stop the
271 * execution or the given timeout is elapsed.
272 *
273 * @param strategy
274 * The strategy of the exploration.
275 * @param timeout
276 * The number of milliseconds before the exploration is forced to stop.
277 * @return Returns true if the exploration stopped by the timeout.
278 */
279 public boolean startExplorationWithTimeout(IStrategy strategy, long timeout) {
280 return startExploration(strategy, true, timeout);
281 }
282
283 /**
284 * Starts the design space exploration asynchronously with a timeout. Completion of the process can be verified by
285 * calling {@link DesignSpaceExplorer#isDone()}.
286 *
287 * @param strategy
288 * The strategy of the exploration.
289 * @param timeout
290 * The number of milliseconds before the exploration is forced to stop.
291 * @return Returns true if the exploration stopped by the timeout.
292 */
293 public boolean startExplorationAsyncWithTimeout(IStrategy strategy, long timeout) {
294 return startExploration(strategy, false, timeout);
295 }
296
297 /**
298 * Starts the design space exploration. If {@code waitForTermination} is true, then it returns only when the
299 * strategy decides to stop the execution or there was a timeout, otherwise when the exploration process is started
300 * it returns immediately. In this case, process completion can be verified by calling
301 * {@link DesignSpaceExplorer#isDone()}.
302 *
303 * @param strategy
304 * The strategy of the exploration.
305 * @param waitForTermination
306 * True if the method must wait for the engine to stop, i.e. whether to start synchronously.
307 * @param timeout
308 * The number of milliseconds before the exploration is forced to stop.
309 * @return Returns true if the exploration stopped by the timeout.
310 */
311 public boolean startExploration(IStrategy strategy, boolean waitForTermination, final long timeout) {
312 initExploration(strategy);
313
314 Timer timer = new Timer();
315 final AtomicBoolean wasTimeout = new AtomicBoolean(false);
316
317 if (timeout > 0) {
318 TimerTask timerTask = new TimerTask() {
319 @Override
320 public void run() {
321 logger.info("Timeout, stopping threads...");
322 globalContext.stopAllThreads();
323 wasTimeout.set(true);
324 }
325 };
326 timer.schedule(timerTask, timeout);
327 }
328
329 if (waitForTermination) {
330 waitForTerminaition();
331 timer.cancel();
332 } else {
333 logger.info("Design space exploration started asynchronously.");
334 }
335
336 return wasTimeout.get();
337
338 }
339
340 private void initExploration(IStrategy strategy) {
341 Preconditions.checkArgument(model != null, MODEL_NOT_YET_GIVEN);
342 Preconditions.checkArgument(strategy != null, "A strategy must be given. Use the Strategies helper class.");
343 Preconditions.checkState(!globalContext.getTransformations().isEmpty(),
344 "At least one transformation rule must be added to start the exploration.");
345
346 if (globalContext.getStateCoderFactory() == null) {
347 if (getMetaModelPackages() == null || getMetaModelPackages().isEmpty()) {
348 throw new DSEException("Cannot initialize state coder."
349 + " Please specifiy the EPackages your model uses with addMetaModelPackage(EPackage)");
350 }
351 globalContext.setStateCoderFactory(new SimpleStateCoderFactory(getMetaModelPackages()));
352 }
353
354 logger.info("DesignSpaceExplorer started exploration.");
355
356 if (deepCopyModel) {
357 globalContext.startFirstThread(strategy, model);
358 } else {
359 globalContext.startFirstThreadWithoutModelClone(strategy, model);
360 }
361 }
362
363 /**
364 * Returns all of the found {@link Solution}s, trajectories. Call it after
365 * {@link DesignSpaceExplorer#startExploration()}. Calling this while the process is running returns the solutions
366 * that have been found <b>so far</b>. The returned {@link Solution} objects may change internal state after they
367 * have been returned, if a shorter trajectory has been found to the referred state.
368 *
369 * @return The found solutions.
370 */
371 public Collection<Solution> getSolutions() {
372 return globalContext.getSolutionStore().getSolutions();
373 }
374
375 /**
376 * Returns an arbitrary solution trajectory or null if the exploration failed to find any.
377 *
378 * @return An arbitrary solution trajectory.
379 */
380 public SolutionTrajectory getArbitrarySolution() {
381 Collection<Solution> solutions = getSolutions();
382 if (solutions.isEmpty()) {
383 return null;
384 }
385 return solutions.iterator().next().getArbitraryTrajectory();
386 }
387
388 /**
389 * Returns the number of distinct states the exploration process has visited so far.
390 *
391 * @return the number of distinct states.
392 */
393 public long getNumberOfStates() {
394 return globalContext.getDesignSpace().getNumberOfStates();
395 }
396
397 /**
398 * Returns the number of distinct transitions the exploration process has discovered (but not necessarily traversed)
399 * so far.
400 *
401 * @return the number of distinct transitions.
402 */
403 public long getNumberOfTransitions() {
404 return globalContext.getDesignSpace().getNumberOfTransitions();
405 }
406
407 /**
408 * Returns the {@link EPackage}s, which were registered with the
409 * {@link DesignSpaceExplorer#addMetaModelPackage(EPackage)} method.
410 *
411 * @return The set of meta model packages.
412 */
413 public Set<EPackage> getMetaModelPackages() {
414 return metaModelPackages;
415 }
416
417 /**
418 * Returns true if the {@link IExplorerThread strategy} decided to stop, and all the threads finished their work.
419 *
420 * @return true if the process has finished, false otherwise.
421 */
422 public boolean isDone() {
423 return globalContext.isDone();
424 }
425
426 /**
427 * Returns the {@link GlobalContext} which holds the configurations such as rule, objectives, etc.
428 *
429 * @return The global context.
430 */
431 public GlobalContext getGlobalContext() {
432 return globalContext;
433 }
434
435 /**
436 * Registers a design space visualizer. Please see the corresponding interface {@link IDesignSpaceVisualizer}.
437 *
438 * @see IDesignSpaceVisualizer
439 *
440 * @param visualizer
441 */
442 public void addDesignSpaceVisulaizer(IDesignSpaceVisualizer visualizer) {
443 globalContext.registerDesignSpaceVisualizer(visualizer);
444 }
445
446 /**
447 * Creates a string containing the state codes of all the found solutions and the found trajectories to these
448 * solutions with fitness values.
449 *
450 * @return A pretty string with the solutions.
451 */
452 public String toStringSolutions() {
453 StringBuilder sb = new StringBuilder();
454 Collection<Solution> solutions = getSolutions();
455 sb.append("Number of solutions: ");
456 sb.append(solutions.size());
457 sb.append("\n");
458 for (Solution solution : solutions) {
459 sb.append("Solution: ");
460 sb.append(solution.getStateCode());
461 sb.append("\n");
462 for (SolutionTrajectory trajectory : solution.getTrajectories()) {
463 sb.append(" ");
464 sb.append(trajectory.toPrettyString());
465 sb.append("\n");
466 }
467 }
468 return sb.toString();
469 }
470
471 /**
472 * A conflict resolver can filter rule activations the DSE engine will see. The primary use of this is symmetry
473 * reduction. This function is subject to change for better API.
474 *
475 * @param conflictResolver
476 */
477 public void setConflictResolver(ConflictResolver conflictResolver) {
478 globalContext.setConflictResolver(conflictResolver);
479 }
480
481 /**
482 * Enumeration for different use cases of logging, including:
483 * <ul>
484 * <li>OFF - no error messages.</li>
485 * <li>WARN - only error and warn messages.</li>
486 * <li>BASIC - logs basic information on how the exploration is going.</li>
487 * <li>VERBOSE_STRATEGY - logs everything the exploration strategy is prepared for.</li>
488 * <li>VERBOSE_FULL - logs every transformation.</li>
489 * </ul>
490 *
491 * @author Andras Szabolcs Nagy
492 *
493 */
494 public enum DseLoggingLevel {
495 OFF, WARN, BASIC, VERBOSE_STRATEGY, VERBOSE_FULL
496 }
497
498 /**
499 * Changes the level of logging. See {@link DseLoggingLevel} for details.
500 *
501 * @param dseLoggingLevel
502 */
503 public static void turnOnLogging(DseLoggingLevel dseLoggingLevel) {
504 switch (dseLoggingLevel) {
505 case OFF:
506 Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.OFF);
507 Logger.getLogger(IStrategy.class).setLevel(Level.OFF);
508 Logger.getLogger(DesignSpaceManager.class).setLevel(Level.OFF);
509 break;
510 case WARN:
511 Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.WARN);
512 Logger.getLogger(IStrategy.class).setLevel(Level.WARN);
513 Logger.getLogger(DesignSpaceManager.class).setLevel(Level.WARN);
514 break;
515 case BASIC:
516 Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.INFO);
517 Logger.getLogger(IStrategy.class).setLevel(Level.INFO);
518 Logger.getLogger(DesignSpaceManager.class).setLevel(Level.WARN);
519 break;
520 case VERBOSE_STRATEGY:
521 Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.DEBUG);
522 Logger.getLogger(IStrategy.class).setLevel(Level.DEBUG);
523 Logger.getLogger(DesignSpaceManager.class).setLevel(Level.WARN);
524 break;
525 case VERBOSE_FULL:
526 Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.DEBUG);
527 Logger.getLogger(IStrategy.class).setLevel(Level.DEBUG);
528 Logger.getLogger(DesignSpaceManager.class).setLevel(Level.DEBUG);
529 break;
530 default:
531 throw new DSEException("Not supported logging level.");
532 }
533 }
534
535 /**
536 * Changes the level of logging. See {@link DseLoggingLevel} for details.
537 *
538 * Also configures a basic console appender for log4j.
539 *
540 * @param dseLoggingLevel
541 */
542 public static void turnOnLoggingWithBasicConfig(DseLoggingLevel dseLoggingLevel) {
543 BasicConfigurator.configure();
544 Logger.getRootLogger().setLevel(Level.WARN);
545 turnOnLogging(dseLoggingLevel);
546 }
547
548 /**
549 * Stops the exploration and waits for termination. It has no effect if the exploration is already terminated or not
550 * even started.
551 */
552 public void stopExploration() {
553 if (globalContext.isDone()) {
554 logger.info("Cannot stop exploration - design space exploration has already finished.");
555 } else if (globalContext.isNotStarted()) {
556 logger.info("Cannot stop exploration - design space exploration has not been started.");
557 } else {
558 globalContext.stopAllThreads();
559 waitForTerminaition();
560 }
561 }
562
563 /**
564 * Stops the exploration asynchronously. It has no effect if the exploration is already terminated or not even
565 * started.
566 */
567 public void stopExplorationAsync() {
568 if (globalContext.isDone()) {
569 logger.info("Cannot stop exploration - design space exploration has already finished.");
570 } else if (globalContext.isNotStarted()) {
571 logger.info("Cannot stop exploration - design space exploration has not been started.");
572 } else {
573 globalContext.stopAllThreads();
574 }
575 }
576
577 /**
578 * Waits for termination.
579 */
580 public void waitForTerminaition() {
581 globalContext.waitForTermination();
582 }
583
584 /**
585 * Serializes all the found solutions by transforming the given initial model.
586 * </p>Files will be named <code>solution[id].xmi</code>.
587 * @param model The initial model.
588 */
589 public void saveModels(Notifier model) {
590 this.saveModels(model, "solution", "xmi");
591 }
592
593 /**
594 * Serializes all the found solutions by transforming the given initial model.
595 * </p>Files will be named <code>solution[id].[extension]</code>.
596 * @param model The initial model.
597 * @param extension The extension of the omitted file.
598 */
599 public void saveModels(Notifier model, String extension) {
600 this.saveModels(model, "solution", extension);
601 }
602
603 /**
604 * Serializes all the found solutions by transforming the given initial model.
605 * </p>Files will be named <code>[fileNamePrefix][id].[extension]</code>.
606 * @param model The initial model.
607 * @param fileNamePrefix The prefix (optionally including a file path) of the omitted file.
608 * @param extension The extension of the omitted file.
609 */
610 public void saveModels(Notifier model, String fileNamePrefix, String extension) {
611 globalContext.getSolutionStore().saveModels(model, new IdBasedSolutionNameProvider(fileNamePrefix, extension));
612 }
613
614 /**
615 * Serializes all the found solutions by transforming the given initial model.
616 * </p>Files will be named using the {@link ISolutionNameProvider}.
617 * @param model The initial model.
618 */
619 public void saveModels(Notifier model, ISolutionNameProvider solutionNameProvider) {
620 globalContext.getSolutionStore().saveModels(model, solutionNameProvider);
621 }
622}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Objectives.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Objectives.java
new file mode 100644
index 00000000..3b375fac
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Objectives.java
@@ -0,0 +1,153 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api;
10
11import org.eclipse.viatra.dse.objectives.impl.CompositeObjective;
12import org.eclipse.viatra.dse.objectives.impl.ConstraintsObjective;
13import org.eclipse.viatra.dse.objectives.impl.AlwaysSatisfiedDummyHardObjective;
14import org.eclipse.viatra.dse.objectives.impl.DepthHardObjective;
15import org.eclipse.viatra.dse.objectives.impl.NeverSatisfiedDummyHardObjective;
16import org.eclipse.viatra.dse.objectives.impl.NoRuleActivationsHardObjective;
17import org.eclipse.viatra.dse.objectives.impl.TrajectoryCostSoftObjective;
18
19/**
20 *
21 * Helper class for creating built-in objectives.
22 *
23 * @author Andras Szabolcs Nagy
24 *
25 */
26public class Objectives {
27
28 private Objectives() {
29 }
30
31 /**
32 * This objective uses VIATRA Queries to calculate fitness and/or goal constraints. Use methods on the returned
33 * objective to configure it.
34 *
35 * @param name
36 * @return The objective.
37 * @see ConstraintsObjective
38 */
39 public static ConstraintsObjective createConstraintsObjective(String name) {
40 return new ConstraintsObjective(name);
41 }
42
43 /**
44 * This objective calculates fitness on the trajectory by adding either fix costs to the rules, or by calculating
45 * custom fitness on activation of rules.
46 *
47 * @param name
48 * @return The objective.
49 * @see TrajectoryCostSoftObjective
50 */
51 public static TrajectoryCostSoftObjective createTrajcetoryCostObjective(String name) {
52 return new TrajectoryCostSoftObjective(name);
53 }
54
55 /**
56 * This objective adds a goal constraint that a solution state should not have any activations.
57 *
58 * @return The objective.
59 * @see NoRuleActivationsHardObjective
60 */
61 public static NoRuleActivationsHardObjective createNoRuleActivationsHardConstraint() {
62 return new NoRuleActivationsHardObjective();
63 }
64
65 /**
66 * This objective adds a goal constraint that a solution state should not have any activations.
67 *
68 * @param name
69 * @return The objective.
70 * @see NoRuleActivationsHardObjective
71 */
72 public static NoRuleActivationsHardObjective createNoRuleActivationsHardConstraint(String name) {
73 return new NoRuleActivationsHardObjective(name);
74 }
75
76 /**
77 * This objective can combine the calculated fitness value of other objectives. Weights are supported.
78 *
79 * @param name
80 * @return The objective.
81 * @see NoRuleActivationsHardObjective
82 */
83 public static CompositeObjective createCompositeObjective(String name) {
84 return new CompositeObjective(name);
85 }
86
87 /**
88 * This hard objective is fulfilled in any circumstances. Use it if all states should be regarded as a valid
89 * solution.
90 *
91 * @return The objective.
92 * @see AlwaysSatisfiedDummyHardObjective
93 */
94 public static AlwaysSatisfiedDummyHardObjective createAlwaysSatisfiedDummyHardObjective() {
95 return new AlwaysSatisfiedDummyHardObjective();
96 }
97
98 /**
99 * This hard objective is fulfilled in any circumstances. Use it if all states should be regarded as a valid
100 * solution.
101 *
102 * @param name
103 * @return The objective.
104 * @see AlwaysSatisfiedDummyHardObjective
105 */
106 public static AlwaysSatisfiedDummyHardObjective createDummyHardObjective(String name) {
107 return new AlwaysSatisfiedDummyHardObjective(name);
108 }
109
110 /**
111 * This hard objective is never fulfilled. Use it if all states should be regarded as an invalid solution.
112 *
113 * @return The objective.
114 * @see AlwaysSatisfiedDummyHardObjective
115 */
116 public static NeverSatisfiedDummyHardObjective createNeverSatisfiedDummyHardObjective() {
117 return new NeverSatisfiedDummyHardObjective();
118 }
119
120 /**
121 * This hard objective is never fulfilled. Use it if all states should be regarded as an invalid solution.
122 *
123 * @return The objective.
124 * @see AlwaysSatisfiedDummyHardObjective
125 */
126 public static NeverSatisfiedDummyHardObjective createNeverSatisfiedDummyHardObjective(String name) {
127 return new NeverSatisfiedDummyHardObjective(name);
128 }
129
130 /**
131 * This hard objective is fulfilled if the length of the trajectory is in the specified interval (inclusive). Use
132 * {@link DepthHardObjective#withMinDepth(int)} and {@link DepthHardObjective#withMaxDepth(int)} to configure.
133 *
134 * @return The objective.
135 * @see DepthHardObjective
136 */
137 public static DepthHardObjective createDepthHardObjective() {
138 return new DepthHardObjective();
139 }
140
141 /**
142 * This hard objective is fulfilled if the length of the trajectory is in the specified interval (inclusive). Use
143 * {@link DepthHardObjective#withMinDepth(int)} and {@link DepthHardObjective#withMaxDepth(int)} to configure.
144 *
145 * @param name
146 * @return The objective.
147 * @see DepthHardObjective
148 */
149 public static DepthHardObjective createDepthHardObjective(String name) {
150 return new DepthHardObjective(name);
151 }
152
153}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Solution.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Solution.java
new file mode 100644
index 00000000..b776db7a
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Solution.java
@@ -0,0 +1,60 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api;
10
11import java.util.Collection;
12import java.util.HashSet;
13import java.util.Iterator;
14import java.util.Set;
15
16public class Solution {
17
18 private Set<SolutionTrajectory> trajectories;
19 private final Object stateId;
20
21 public Solution(Object stateId, SolutionTrajectory trajectory) {
22 this.stateId = stateId;
23 trajectories = new HashSet<>();
24 trajectories.add(trajectory);
25 }
26
27 public void addTrajectory(SolutionTrajectory trajectory) {
28 trajectories.add(trajectory);
29 }
30
31 public SolutionTrajectory getArbitraryTrajectory() {
32 return trajectories.iterator().next();
33 }
34
35 public SolutionTrajectory getShortestTrajectory() {
36 Iterator<SolutionTrajectory> iterator = trajectories.iterator();
37 SolutionTrajectory shortestTrajecotry = iterator.next();
38 int minSize = shortestTrajecotry.getTrajectoryLength();
39
40 while (iterator.hasNext()) {
41 SolutionTrajectory traj = iterator.next();
42 int size = traj.getTrajectoryLength();
43 if (size < minSize) {
44 shortestTrajecotry = traj;
45 minSize = size;
46 }
47 }
48
49 return shortestTrajecotry;
50 }
51
52 public Collection<SolutionTrajectory> getTrajectories() {
53 return trajectories;
54 }
55
56 public Object getStateCode() {
57 return stateId;
58 }
59
60}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/SolutionTrajectory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/SolutionTrajectory.java
new file mode 100644
index 00000000..500dd7d2
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/SolutionTrajectory.java
@@ -0,0 +1,345 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api;
10
11import java.lang.reflect.InvocationTargetException;
12import java.util.HashSet;
13import java.util.List;
14import java.util.Objects;
15import java.util.function.Consumer;
16
17import org.eclipse.emf.common.notify.Notifier;
18import org.eclipse.emf.edit.command.ChangeCommand;
19import org.eclipse.emf.edit.domain.EditingDomain;
20import org.eclipse.viatra.dse.base.DseIdPoolHelper;
21import org.eclipse.viatra.dse.designspace.api.IBacktrackListener;
22import org.eclipse.viatra.dse.objectives.Fitness;
23import org.eclipse.viatra.dse.statecode.IStateCoder;
24import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
25import org.eclipse.viatra.dse.util.EMFHelper;
26import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine;
27import org.eclipse.viatra.query.runtime.api.IPatternMatch;
28import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
29import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher;
30import org.eclipse.viatra.query.runtime.emf.EMFScope;
31import org.eclipse.viatra.query.runtime.matchers.ViatraQueryRuntimeException;
32import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
33import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
34
35import com.google.common.util.concurrent.UncheckedExecutionException;
36
37/**
38 * A SolutionTrajectory represents a trajectory (i.e. sequence of transformation
39 * rule applications), which can transform the initial model to a desired state.
40 * An instance of this class holds the the actual rule sequence and the
41 * corresponding activation codes. Furthermore it can be used to perform the
42 * transformation on a given model (if possible).
43 * <p>
44 * It is also possible to undo the transformation if initialized with an editing
45 * domain.
46 * <p>
47 * The instance of this class can be reused for different models.
48 *
49 * @author Andras Szabolcs Nagy
50 *
51 */
52public class SolutionTrajectory {
53
54 private final List<Object> activationCodes;
55 private final List<BatchTransformationRule<?, ?>> transformationRules;
56 private final IStateCoderFactory stateCoderFactory;
57 private Fitness fitness;
58 private Solution solution;
59
60 private ViatraQueryEngine engine;
61 private Notifier model;
62 private EditingDomain editingDomain;
63 private IStateCoder stateCoder;
64 private IBacktrackListener listener;
65
66 private int currentIndex;
67
68 public SolutionTrajectory(final List<Object> activationCodes,
69 final List<BatchTransformationRule<?, ?>> transformationRules, final IStateCoderFactory stateCoderFactory,
70 final IBacktrackListener backtrackListener) {
71 Objects.requireNonNull(transformationRules, "Parameter transformationRules cannot be null!");
72 Objects.requireNonNull(stateCoderFactory, "Parameter stateCoderFactory cannot be null!");
73 Objects.requireNonNull(activationCodes, "Parameter activations cannot be null!");
74 Preconditions.checkState(transformationRules.size() == activationCodes.size(),
75 "The two List parameters must be the same in size.");
76
77 this.activationCodes = activationCodes;
78 this.transformationRules = transformationRules;
79 this.stateCoderFactory = stateCoderFactory;
80 this.listener = backtrackListener;
81 currentIndex = 0;
82 }
83
84 /**
85 * Initialize this SolutionTrajectory for transforming the model along the
86 * trajectory.
87 *
88 * @param model The model.
89 * @throws ViatraQueryRuntimeException If the VIATRA Query fails to initialize.
90 */
91 public void setModel(Notifier model) {
92 editingDomain = null;
93 EMFScope scope = new EMFScope(model);
94 this.engine = ViatraQueryEngine.on(scope);
95 this.model = model;
96 stateCoder = stateCoderFactory.createStateCoder();
97 stateCoder.init(model);
98 currentIndex = 0;
99 DseIdPoolHelper.INSTANCE.disposeByThread();
100 DseIdPoolHelper.INSTANCE.registerRules(rule -> {
101 int id = 0;
102 for (BatchTransformationRule<?, ?> r : transformationRules.subList(0, currentIndex)) {
103 if (r.equals(rule)) {
104 id++;
105 }
106 }
107 return id;
108 }, new HashSet<BatchTransformationRule<?, ?>>(transformationRules));
109 }
110
111 /**
112 * Initialize this SolutionTrajectory for transforming the given model along the
113 * trajectory.
114 * <p>
115 * The transformation will be reversible by creating an {@link EditingDomain} on
116 * the model.
117 *
118 * @param modelRoot The root of the model.
119 * @throws ViatraQueryRuntimeException If the VIATRA Query fails to initialize.
120 */
121 public void setModelWithEditingDomain(Notifier modelRoot) {
122 setModel(modelRoot);
123 editingDomain = EMFHelper.createEditingDomain(model);
124 }
125
126 /**
127 * Transforms the given model along the trajectory.
128 *
129 * @param modelRoot The root of the model.
130 * @throws ViatraQueryRuntimeException If the VIATRA Query fails to initialize.
131 */
132 public void doTransformation(Notifier modelRoot) {
133 setModel(modelRoot);
134 doTransformation();
135 }
136
137 /**
138 * Transforms the given model along the trajectory.
139 * <p>
140 * The transformation will be reversible by creating an {@link EditingDomain} on
141 * the model.
142 *
143 * @param modelRoot The root of the model.
144 * @throws ViatraQueryRuntimeException If the VIATRA Query fails to initialize.
145 */
146 public void doTransformationUndoable(Notifier modelRoot) {
147 setModelWithEditingDomain(modelRoot);
148 doTransformation();
149 }
150
151 /**
152 * Transforms the given model along the trajectory. To initialize the model call
153 * the {@link SolutionTrajectory#setModel(Notifier)} method.
154 *
155 * @throws Exception If the activation to fire is not found.
156 * Possible problems: wrong model, bad state
157 * serializer.
158 * @throws ViatraQueryRuntimeException If the VIATRA Query fails to initialize.
159 */
160 public void doTransformation() {
161 while (doNextTransformation())
162 ;
163 }
164
165 /**
166 * Transforms the given model by one step to the solution (makes one step in the
167 * trajectory). To initialize the model call the
168 * {@link SolutionTrajectory#setModel(Notifier)} method.
169 *
170 * @throws ViatraQueryRuntimeException
171 */
172 public boolean doNextTransformation() {
173 if (currentIndex >= activationCodes.size()) {
174 return false;
175 } else {
176 doNextTransformation(currentIndex);
177 currentIndex++;
178 return true;
179 }
180 }
181
182 @SuppressWarnings("unchecked")
183 private void doNextTransformation(int index) {
184 Objects.requireNonNull(model, "The model cannot be null! Use the setModel method.");
185
186 // cast for the ".process(match)" method.
187 BatchTransformationRule<?, ?> tr = transformationRules.get(index);
188 Object activationCode = activationCodes.get(index);
189
190 ViatraQueryMatcher<?> matcher = tr.getPrecondition().getMatcher(engine);
191
192 boolean isActivationFound = false;
193 for (final IPatternMatch match : matcher.getAllMatches()) {
194 Object matchHash = stateCoder.createActivationCode(match);
195 if (matchHash.equals(activationCode)) {
196 @SuppressWarnings("rawtypes")
197 final Consumer action = tr.getAction();
198
199 if (editingDomain == null) {
200 action.accept(match);
201 } else {
202 ChangeCommand cc = new ChangeCommand(model) {
203 @Override
204 protected void doExecute() {
205 action.accept(match);
206 }
207 };
208 long start = System.nanoTime();
209 try {
210 ((AdvancedViatraQueryEngine) engine).delayUpdatePropagation(() -> {
211 editingDomain.getCommandStack().execute(cc);
212 return null;
213 });
214 } catch (InvocationTargetException e) {
215 throw new RuntimeException(e);
216 }
217 listener.forwardWorked(System.nanoTime() - start);
218 }
219
220 isActivationFound = true;
221 break;
222 }
223 }
224 if (!isActivationFound) {
225 throw new UncheckedExecutionException(
226 "Activation was not found for transformation! Possible cause: wrong model, bad state coder. index: "
227 + index + " Activation code: " + activationCode,
228 null);
229 }
230 }
231
232 /**
233 * Call this method to undo the last transformation.
234 *
235 * @return True, if it was successful.
236 */
237 public boolean undoLastTransformation() {
238 Objects.requireNonNull(editingDomain, "To be able to undo the transformation initialize with editing domain.");
239 long start = System.nanoTime();
240 boolean result;
241
242 if (currentIndex > 0) {
243 try {
244 ((AdvancedViatraQueryEngine) engine).delayUpdatePropagation(() -> {
245 editingDomain.getCommandStack().undo();
246 return null;
247 });
248 } catch (InvocationTargetException e) {
249 throw new RuntimeException(e);
250 }
251 currentIndex--;
252 result = true;
253 }
254 result = false;
255 listener.backtrackWorked(System.nanoTime() - start);
256 return result;
257 }
258
259 /**
260 * Call this method to undo the transformation.
261 */
262 public void undoTransformation() {
263 while (undoLastTransformation())
264 ;
265 }
266
267 public List<Object> getActivationCodes() {
268 return activationCodes;
269 }
270
271 public List<BatchTransformationRule<?, ?>> getTransformationRules() {
272 return transformationRules;
273 }
274
275 public IStateCoderFactory getStateCoderFactory() {
276 return stateCoderFactory;
277 }
278
279 public ViatraQueryEngine getEngine() {
280 return engine;
281 }
282
283 public Notifier getModel() {
284 return model;
285 }
286
287 public IStateCoder getStateCoder() {
288 return stateCoder;
289 }
290
291 public int getCurrentIndex() {
292 return currentIndex;
293 }
294
295 public int getTrajectoryLength() {
296 return activationCodes.size();
297 }
298
299 public Fitness getFitness() {
300 return fitness;
301 }
302
303 public void setFitness(Fitness fitness) {
304 this.fitness = fitness;
305 }
306
307 public String toPrettyString() {
308 StringBuilder sb = new StringBuilder();
309 sb.append("Fitness: ");
310 sb.append(fitness.toString());
311 sb.append(" | Trajectory (");
312 sb.append(activationCodes.size());
313 sb.append("): ");
314 for (Object object : activationCodes) {
315 sb.append(object.toString());
316 sb.append(" | ");
317 }
318 return sb.toString();
319 }
320
321 @Override
322 public int hashCode() {
323 return activationCodes.hashCode();
324 }
325
326 @Override
327 public boolean equals(Object obj) {
328 if (this == obj) {
329 return true;
330 }
331 if (obj instanceof SolutionTrajectory) {
332 SolutionTrajectory that = (SolutionTrajectory) obj;
333 return activationCodes.equals(that.activationCodes);
334 }
335 return false;
336 }
337
338 public Solution getSolution() {
339 return solution;
340 }
341
342 public void setSolution(Solution solution) {
343 this.solution = solution;
344 }
345}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Strategies.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Strategies.java
new file mode 100644
index 00000000..ed7a90da
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/Strategies.java
@@ -0,0 +1,123 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api;
10
11import org.eclipse.viatra.dse.api.strategy.impl.BestFirstStrategy;
12import org.eclipse.viatra.dse.api.strategy.impl.BreadthFirstStrategy;
13import org.eclipse.viatra.dse.api.strategy.impl.DepthFirstStrategy;
14import org.eclipse.viatra.dse.api.strategy.impl.FixedPriorityStrategy;
15import org.eclipse.viatra.dse.api.strategy.impl.HillClimbingStrategy;
16import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
17
18/**
19 * Helper class for instantiating strategies. To implement a new strategy use the {@link IStrategy} interface.
20 *
21 * @author Andras Szabolcs Nagy
22 *
23 */
24public final class Strategies {
25
26 private Strategies() {
27 }
28
29 /**
30 * Creates a depth-first search exploration strategy without a depth limit.
31 *
32 * @return The strategy.
33 * @see DepthFirstStrategy
34 */
35 public static DepthFirstStrategy createDfsStrategy() {
36 return new DepthFirstStrategy();
37 }
38
39 /**
40 * Creates a depth-first search exploration strategy with a depth limit. A negative depth limit means no
41 * depth limit, zero means that it will check the initial state.
42 *
43 * @param depthLimit
44 * @return The strategy.
45 * @see DepthFirstStrategy
46 */
47 public static DepthFirstStrategy createDfsStrategy(int depthLimit) {
48 return new DepthFirstStrategy(depthLimit);
49 }
50
51 /**
52 * Creates a fixed priority exploration strategy without a depth limit. It is a depth-first search exploration
53 * strategy but from a current state it only explores the activations with the highest priority. Priorities can be
54 * defined on the strategy itself.
55 *
56 * @return The strategy.
57 * @see FixedPriorityStrategy
58 */
59 public static FixedPriorityStrategy createFixedPriorityStrategy() {
60 return createFixedPriorityStrategy(-1);
61 }
62
63 /**
64 * Creates a fixed priority exploration strategy with a depth limit, where a zero or negative depth limit means no
65 * depth limit. It is a depth-first search exploration strategy but from a current state it only explores the
66 * activations with the highest priority. Priorities can be defined on the strategy itself.
67 *
68 * @param depthLimit
69 * @return The strategy.
70 * @see FixedPriorityStrategy
71 */
72 public static FixedPriorityStrategy createFixedPriorityStrategy(int depthLimit) {
73 return new FixedPriorityStrategy().withDepthLimit(depthLimit);
74 }
75
76 /**
77 * Creates a breadth-first search exploration strategy without a depth limit.
78 *
79 * @return The strategy.
80 * @see BreadthFirstStrategy
81 */
82 public static BreadthFirstStrategy createBfsStrategy() {
83 return new BreadthFirstStrategy();
84 }
85
86 /**
87 * Creates a breadth-first search exploration strategy with a depth limit. A zero or negative depth limit means no
88 * depth limit.
89 *
90 * @param depthLimit
91 * @return The strategy.
92 * @see BreadthFirstStrategy
93 */
94 public static BreadthFirstStrategy createBfsStrategy(int depthLimit) {
95 return new BreadthFirstStrategy(depthLimit);
96 }
97
98 /**
99 * Creates a hill climbing exploration strategy. By default, it explores all neighborhood states and chooses the
100 * best one to continue with until all neighborhood states are dominated by the current state. Other options are
101 * available on the strategy.
102 *
103 * @return The strategy.
104 * @see HillClimbingStrategy
105 */
106 public static HillClimbingStrategy creatHillClimbingStrategy() {
107 return new HillClimbingStrategy();
108 }
109
110 /**
111 * See {@link BestFirstStrategy}.
112 */
113 public static BestFirstStrategy createBestFirstStrategy() {
114 return new BestFirstStrategy();
115 }
116
117 /**
118 * See {@link BestFirstStrategy}.
119 */
120 public static BestFirstStrategy createBestFirstStrategy(int depthLimit) {
121 return new BestFirstStrategy(depthLimit);
122 }
123}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BestFirstStrategy.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BestFirstStrategy.java
new file mode 100644
index 00000000..fe5604a1
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BestFirstStrategy.java
@@ -0,0 +1,228 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.impl;
10
11import java.util.Arrays;
12import java.util.Collection;
13import java.util.Iterator;
14import java.util.PriorityQueue;
15
16import org.apache.log4j.Logger;
17import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
18import org.eclipse.viatra.dse.base.ThreadContext;
19import org.eclipse.viatra.dse.objectives.Fitness;
20import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
21import org.eclipse.viatra.dse.solutionstore.SolutionStore;
22
23/**
24 * This exploration strategy eventually explorers the whole design space but goes in the most promising directions
25 * first, based on the {@link Fitness}.
26 *
27 * There are a few parameter to tune such as
28 * <ul>
29 * <li>maximum depth</li>
30 * <li>continue the exploration from a state that satisfies the hard objectives (the default that it will
31 * backtrack),</li>
32 * <li>whether to continue the exploration from the newly explored state if it is at least equally good than the
33 * previous one or only if it is better (default is "at least equally good").</li>
34 * </ul>
35 *
36 * @author Andras Szabolcs Nagy
37 *
38 */
39public class BestFirstStrategy implements IStrategy {
40
41 private ThreadContext context;
42 private SolutionStore solutionStore;
43
44 private int maxDepth;
45 private boolean isInterrupted = false;
46 private boolean backTrackIfSolution = true;
47 private boolean onlyBetterFirst = false;
48
49 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore;
50 private Logger logger = Logger.getLogger(IStrategy.class);
51
52 private static class TrajectoryWithFitness {
53
54 public Object[] trajectory;
55 public Fitness fitness;
56
57 public TrajectoryWithFitness(Object[] trajectory, Fitness fitness) {
58 super();
59 this.trajectory = trajectory;
60 this.fitness = fitness;
61 }
62
63 @Override
64 public String toString() {
65 return Arrays.toString(trajectory) + fitness.toString();
66 }
67
68 }
69
70 /**
71 * Creates a new best-first search algorithm without depth limit.
72 */
73 public BestFirstStrategy() {
74 this(-1);
75 }
76
77 /**
78 * Creates a new best-first search algorithm with depth limit.
79 *
80 * @param maxDepth
81 * A negative <code>maxDepth</code> means no depth limit, zero means the checking of the initial state.
82 */
83 public BestFirstStrategy(int maxDepth) {
84 if (maxDepth < 0) {
85 this.maxDepth = Integer.MAX_VALUE;
86 } else {
87 this.maxDepth = maxDepth;
88 }
89 }
90
91 public BestFirstStrategy continueIfHardObjectivesFulfilled() {
92 backTrackIfSolution = false;
93 return this;
94 }
95
96 public BestFirstStrategy goOnOnlyIfFitnessIsBetter() {
97 onlyBetterFirst = true;
98 return this;
99 }
100
101 @Override
102 public void initStrategy(ThreadContext context) {
103 this.context = context;
104 this.solutionStore = context.getGlobalContext().getSolutionStore();
105 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
106
107 trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11,
108 (o1, o2) -> objectiveComparatorHelper.compare(o2.fitness, o1.fitness));
109 }
110
111 @Override
112 public void explore() {
113 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
114
115 boolean globalConstraintsAreSatisfied = context.checkGlobalConstraints();
116 if (!globalConstraintsAreSatisfied) {
117 logger.info("Global contraint is not satisifed in the first state. Terminate.");
118 return;
119 }
120
121 final Fitness firstFittness = context.calculateFitness();
122 if (firstFittness.isSatisifiesHardObjectives()) {
123 context.newSolution();
124 logger.info("First state is a solution. Terminate.");
125 return;
126 }
127
128 if (maxDepth == 0) {
129 return;
130 }
131
132 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]);
133 TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness);
134 trajectoiresToExplore.add(currentTrajectoryWithFittness);
135
136 mainLoop: while (!isInterrupted) {
137
138 if (currentTrajectoryWithFittness == null) {
139 if (trajectoiresToExplore.isEmpty()) {
140 logger.debug("State space is fully traversed.");
141 return;
142 } else {
143 currentTrajectoryWithFittness = trajectoiresToExplore.element();
144 if (logger.isDebugEnabled()) {
145 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness);
146 }
147 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory);
148 }
149 }
150
151 Collection<Object> activationIds = context.getUntraversedActivationIds();
152 Iterator<Object> iterator = activationIds.iterator();
153
154 while (!isInterrupted && iterator.hasNext()) {
155 final Object nextActivation = iterator.next();
156 if (!iterator.hasNext()) {
157 logger.debug("Last untraversed activation of the state.");
158 trajectoiresToExplore.remove(currentTrajectoryWithFittness);
159 }
160
161 if (logger.isDebugEnabled()) {
162 logger.debug("Executing new activation: " + nextActivation);
163 }
164 context.executeAcitvationId(nextActivation);
165 if (context.isCurrentStateAlreadyTraversed()) {
166 logger.info("The new state is already visited.");
167 context.backtrack();
168 } else if (!context.checkGlobalConstraints()) {
169 logger.debug("Global contraint is not satisifed.");
170 context.backtrack();
171 } else {
172 final Fitness nextFitness = context.calculateFitness();
173 if (nextFitness.isSatisifiesHardObjectives()) {
174 solutionStore.newSolution(context);
175 logger.debug("Found a solution.");
176 if (backTrackIfSolution) {
177 context.backtrack();
178 continue;
179 }
180 }
181 if (context.getDepth() >= maxDepth) {
182 logger.debug("Reached max depth.");
183 context.backtrack();
184 continue;
185 }
186
187 TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness(
188 context.getTrajectory().toArray(), nextFitness);
189 trajectoiresToExplore.add(nextTrajectoryWithFittness);
190
191 int compare = objectiveComparatorHelper.compare(currentTrajectoryWithFittness.fitness,
192 nextTrajectoryWithFittness.fitness);
193 if (compare < 0) {
194 logger.debug("Better fitness, moving on: " + nextFitness);
195 currentTrajectoryWithFittness = nextTrajectoryWithFittness;
196 continue mainLoop;
197 } else if (compare == 0) {
198 if (onlyBetterFirst) {
199 logger.debug("Equally good fitness, backtrack: " + nextFitness);
200 context.backtrack();
201 continue;
202 } else {
203 logger.debug("Equally good fitness, moving on: " + nextFitness);
204 currentTrajectoryWithFittness = nextTrajectoryWithFittness;
205 continue mainLoop;
206 }
207 } else {
208 logger.debug("Worse fitness.");
209 currentTrajectoryWithFittness = null;
210 continue mainLoop;
211 }
212 }
213 }
214
215 logger.debug("State is fully traversed.");
216 trajectoiresToExplore.remove(currentTrajectoryWithFittness);
217 currentTrajectoryWithFittness = null;
218
219 }
220 logger.info("Interrupted.");
221 }
222
223 @Override
224 public void interruptStrategy() {
225 isInterrupted = true;
226 }
227
228}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BreadthFirstStrategy.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BreadthFirstStrategy.java
new file mode 100644
index 00000000..6b7d9817
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/BreadthFirstStrategy.java
@@ -0,0 +1,220 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.impl;
10
11import java.util.Collection;
12import java.util.Iterator;
13import java.util.concurrent.BrokenBarrierException;
14import java.util.concurrent.ConcurrentLinkedQueue;
15import java.util.concurrent.CyclicBarrier;
16import java.util.concurrent.atomic.AtomicBoolean;
17
18import org.apache.log4j.Logger;
19import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
20import org.eclipse.viatra.dse.base.GlobalContext;
21import org.eclipse.viatra.dse.base.ThreadContext;
22import org.eclipse.viatra.dse.objectives.Fitness;
23import org.eclipse.viatra.dse.solutionstore.SolutionStore;
24
25/**
26 * A breadth-first search algorithm implementation, that
27 * <ul>
28 * <li>can work with multiple threads,</li>
29 * <li>indeterministic,</li>
30 * <li>saves all states (trajectories) as solutions that fulfill all the hard objectives,</li>
31 * <li>can have a depth limit,</li>
32 * <li>will backtrack when a model satisfies the hard objectives (after saving it as a solution) and will not explore
33 * beyond that state.</li>
34 * </ul>
35 *
36 * @author Andras Szabolcs Nagy
37 *
38 */
39public class BreadthFirstStrategy implements IStrategy {
40
41 private static final class BfsSharedObject {
42 private final ConcurrentLinkedQueue<Object[]> trajectoryQueue1 = new ConcurrentLinkedQueue<>();
43 private final ConcurrentLinkedQueue<Object[]> trajectoryQueue2 = new ConcurrentLinkedQueue<>();
44
45 private final AtomicBoolean pushToQueue1 = new AtomicBoolean(false);
46 private final AtomicBoolean designSpaceTraversed = new AtomicBoolean(false);
47
48 public final CyclicBarrier barrier;
49
50 public BfsSharedObject(int numberOfThreads) {
51 barrier = new CyclicBarrier(numberOfThreads, () -> {
52 boolean oldValue = pushToQueue1.get();
53 pushToQueue1.set(!oldValue);
54 if (trajectoryQueue1.isEmpty() && trajectoryQueue2.isEmpty()) {
55 designSpaceTraversed.set(true);
56 }
57 });
58 }
59
60 public Object[] poll() {
61 if (pushToQueue1.get()) {
62 return trajectoryQueue2.poll();
63 } else {
64 return trajectoryQueue1.poll();
65 }
66 }
67
68 public void push(Object[] trajectory) {
69 if (pushToQueue1.get()) {
70 trajectoryQueue1.add(trajectory);
71 } else {
72 trajectoryQueue2.add(trajectory);
73 }
74 }
75
76 public boolean isDesignSpaceTraversed() {
77 return designSpaceTraversed.get();
78 }
79 }
80
81 private int maxDepth = 0;
82 private BfsSharedObject shared;
83 private boolean isInterrupted = false;
84 private ThreadContext context;
85 private Logger logger = Logger.getLogger(IStrategy.class);
86 private SolutionStore solutionStore;
87 private boolean isFirstThread = false;
88
89 /**
90 * Creates a new breadth-first search algorithm without depth limit.
91 */
92 public BreadthFirstStrategy() {
93 this.maxDepth = Integer.MAX_VALUE;
94 }
95
96 /**
97 * Creates a new breadth-first search algorithm with depth limit.
98 *
99 * @param maxDepth
100 * A negative <code>maxDepth</code> means no depth limit, zero means the checking of the initial state.
101 */
102 public BreadthFirstStrategy(int maxDepth) {
103 if (maxDepth < 0) {
104 this.maxDepth = Integer.MAX_VALUE;
105 } else {
106 this.maxDepth = maxDepth;
107 }
108 }
109
110 @Override
111 public void initStrategy(ThreadContext context) {
112 this.context = context;
113 this.solutionStore = context.getGlobalContext().getSolutionStore();
114
115 GlobalContext globalContext = context.getGlobalContext();
116 if (globalContext.getSharedObject() == null) {
117 isFirstThread = true;
118 shared = new BfsSharedObject(globalContext.getThreadPool().getMaximumPoolSize());
119 globalContext.setSharedObject(shared);
120 logger.info("Breadth-first exploration strategy is inited.");
121 } else {
122 shared = (BfsSharedObject) globalContext.getSharedObject();
123 }
124 }
125
126 @Override
127 public void explore() {
128
129 if (isFirstThread) {
130
131 boolean globalConstraintsAreSatisfied = context.checkGlobalConstraints();
132 if (!globalConstraintsAreSatisfied) {
133 logger.info("Global contraint is not satisifed in the first state. Terminate.");
134 return;
135 }
136
137 Fitness fitness = context.calculateFitness();
138 if (fitness.isSatisifiesHardObjectives()) {
139 context.newSolution();
140 logger.info("First state is a solution. Terminate.");
141 return;
142 }
143
144 Object[] currentTrajectory = context.getTrajectory().toArray(new Object[0]);
145
146 shared.push(currentTrajectory);
147
148 startThreads();
149 } else {
150 try {
151 shared.barrier.await();
152 } catch (InterruptedException | BrokenBarrierException e) {
153 }
154 }
155
156 mainLoop: while (!isInterrupted && !shared.isDesignSpaceTraversed()) {
157
158 Object[] next = shared.poll();
159 while (next == null) {
160 try {
161 logger.debug("Reached barrier.");
162 shared.barrier.await();
163 } catch (InterruptedException | BrokenBarrierException e1) {
164 }
165 if (isInterrupted || shared.isDesignSpaceTraversed()) {
166 break mainLoop;
167 }
168 next = shared.poll();
169 }
170
171 context.backtrackUntilRoot();
172
173 context.executeTrajectory(next);
174
175 Collection<Object> activationIds = context.getCurrentActivationIds();
176 int i = activationIds.size() - 1;
177
178 while (!isInterrupted && i >= 0) {
179
180 Iterator<Object> iterator = activationIds.iterator();
181 int index = i--;
182 while (iterator.hasNext() && index > 0) {
183 index--;
184 iterator.next();
185 }
186 Object activationIdToTry = iterator.next();
187
188 context.executeAcitvationId(activationIdToTry);
189
190 if (context.isCurrentStateAlreadyTraversed()) {
191 logger.info("The new state is already visited.");
192 } else if (!context.checkGlobalConstraints()) {
193 logger.debug("Global contraint is not satisifed.");
194 } else if (context.calculateFitness().isSatisifiesHardObjectives()) {
195 solutionStore.newSolution(context);
196 logger.debug("Found a solution.");
197 } else if (context.getDepth() >= maxDepth) {
198 logger.debug("Reached max depth.");
199 } else {
200 Object[] currentTrajectory = context.getTrajectory().toArray(new Object[0]);
201 shared.push(currentTrajectory);
202 }
203
204 context.backtrack();
205 }
206
207 }
208 }
209
210 private void startThreads() {
211 context.startAllThreads(() -> new BreadthFirstStrategy(maxDepth));
212 }
213
214 @Override
215 public void interruptStrategy() {
216 isInterrupted = true;
217 shared.barrier.reset();
218 }
219
220}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/DepthFirstStrategy.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/DepthFirstStrategy.java
new file mode 100644
index 00000000..22a4a683
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/DepthFirstStrategy.java
@@ -0,0 +1,188 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.impl;
10
11import java.util.Collection;
12import java.util.Iterator;
13import java.util.Random;
14import java.util.concurrent.atomic.AtomicBoolean;
15
16import org.apache.log4j.Logger;
17import org.eclipse.viatra.dse.api.DSEException;
18import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
19import org.eclipse.viatra.dse.base.ThreadContext;
20import org.eclipse.viatra.dse.objectives.Fitness;
21
22/**
23 * A depth-first search algorithm implementation, that
24 * <ul>
25 * <li>can work with multiple threads,</li>
26 * <li>randomly traverses the search space,</li>
27 * <li>saves all states (trajectories) as solutions that fulfill all the hard objectives,</li>
28 * <li>can have a depth limit,</li>
29 * <li>will backtrack when a model satisfies the hard objectives (after saving it as a solution), which can be modified
30 * by calling {@link #continueIfHardObjectivesFulfilled()}</li>
31 * </ul>
32 *
33 * @author Andras Szabolcs Nagy
34 *
35 */
36public class DepthFirstStrategy implements IStrategy {
37
38 private int maxDepth;
39 private AtomicBoolean isInterrupted = new AtomicBoolean(false);
40 private ThreadContext context;
41
42 private Logger logger = Logger.getLogger(IStrategy.class);
43
44 private Random random = new Random();
45 private boolean backTrackIfSolution = true;
46
47 /**
48 * Creates a new depth-first search algorithm without depth limit.
49 */
50 public DepthFirstStrategy() {
51 this.maxDepth = Integer.MAX_VALUE;
52 }
53
54 /**
55 * Creates a new depth-first search algorithm with depth limit.
56 *
57 * @param maxDepth
58 * A negative <code>maxDepth</code> means no depth limit, zero means the checking of the initial state.
59 */
60 public DepthFirstStrategy(int maxDepth) {
61 if (maxDepth < 0) {
62 this.maxDepth = Integer.MAX_VALUE;
63 } else {
64 this.maxDepth = maxDepth;
65 }
66 }
67
68 /**
69 * If called, the algorithm will not backtrack after the hard objectives are fulfilled, instead it goes deeper in
70 * the search space.
71 */
72 public DepthFirstStrategy continueIfHardObjectivesFulfilled() {
73 backTrackIfSolution = false;
74 return this;
75 }
76
77 @Override
78 public void initStrategy(ThreadContext context) {
79 this.context = context;
80
81 if (context.getSharedObject() == null) {
82 context.setSharedObject(new Object());
83 logger.info("Depth-first exploration strategy is initied.");
84 startThreads();
85 }
86
87 }
88
89 private void startThreads() {
90 context.startAllThreads(() -> new DepthFirstStrategy(maxDepth));
91 }
92
93 @Override
94 public void explore() {
95
96 mainloop: do {
97
98 boolean globalConstraintsAreSatisfied = context.checkGlobalConstraints();
99 if (!globalConstraintsAreSatisfied) {
100 boolean isSuccessfulUndo = context.backtrack();
101 if (!isSuccessfulUndo) {
102 logger.info("Global contraint is not satisifed and cannot backtrack.");
103 break;
104 } else {
105 logger.debug("Global contraint is not satisifed, backtrack.");
106 continue;
107 }
108 }
109
110 Fitness fitness = context.calculateFitness();
111 if (fitness.isSatisifiesHardObjectives()) {
112 context.newSolution();
113 if (backTrackIfSolution) {
114 boolean isSuccessfulUndo = context.backtrack();
115 if (!isSuccessfulUndo) {
116 logger.info("Found a solution but cannot backtrack.");
117 break;
118 } else {
119 logger.debug("Found a solution, backtrack.");
120 continue;
121 }
122 }
123 }
124
125 if (context.getDepth() >= maxDepth) {
126 boolean isSuccessfulUndo = context.backtrack();
127 if (!isSuccessfulUndo) {
128 logger.info("Reached max depth but cannot bactrack.");
129 break;
130 } else {
131 logger.debug("Reached max depth, bactrack.");
132 continue;
133 }
134 }
135
136 if (isInterrupted.get()) {
137 logger.info("Interrupted, stop exploration.");
138 break;
139 }
140
141 Object activationId = null;
142 Collection<Object> activationIds;
143
144 do {
145 activationIds = context.getUntraversedActivationIds();
146 if (activationIds.isEmpty()) {
147 boolean isSuccessfulUndo = context.backtrack();
148 if (!isSuccessfulUndo) {
149 logger.info("No more transitions from current state and cannot backtrack.");
150 break mainloop;
151 } else {
152 logger.debug("No more transitions from current state, backtrack.");
153 continue;
154 }
155 }
156 } while (activationIds.isEmpty());
157
158 int index = random.nextInt(activationIds.size());
159
160 Iterator<Object> iterator = activationIds.iterator();
161 while (index-- > 0) {
162 iterator.next();
163 }
164 activationId = iterator.next();
165
166 context.executeAcitvationId(activationId);
167
168 boolean loopInTrajectory = context.isCurrentStateInTrajectory();
169 if (loopInTrajectory) {
170 boolean isSuccessfulUndo = context.backtrack();
171 if (!isSuccessfulUndo) {
172 throw new DSEException("The new state is present in the trajectoy but cannot bactkrack. Should never happen!");
173 } else {
174 logger.info("The new state is already visited in the trajectory, backtrack.");
175 }
176 }
177
178 } while (true);
179
180 logger.info("Terminated.");
181 }
182
183 @Override
184 public void interruptStrategy() {
185 isInterrupted.set(true);
186 }
187
188}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/FixedPriorityStrategy.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/FixedPriorityStrategy.java
new file mode 100644
index 00000000..4ccda4ce
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/FixedPriorityStrategy.java
@@ -0,0 +1,208 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.impl;
10
11import java.util.Collection;
12import java.util.HashMap;
13import java.util.List;
14import java.util.Map;
15import java.util.Random;
16import java.util.concurrent.atomic.AtomicBoolean;
17
18import org.apache.log4j.Logger;
19import org.eclipse.viatra.dse.api.DSEException;
20import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
21import org.eclipse.viatra.dse.base.ThreadContext;
22import org.eclipse.viatra.dse.objectives.Fitness;
23import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
24
25import com.google.common.collect.Lists;
26
27/**
28 * Works as {@link DepthFirstStrategy} but:
29 * <ul>
30 * <li>works only with single thread,</li>
31 * <li>in a given state, it only traverses the activations with locally the highest priority.</li>
32 * </ul>
33 *
34 * @author Andras Szabolcs Nagy
35 *
36 */
37public class FixedPriorityStrategy implements IStrategy {
38
39 private int maxDepth = Integer.MAX_VALUE;
40 private AtomicBoolean isInterrupted = new AtomicBoolean(false);
41 private ThreadContext context;
42
43 private Logger logger = Logger.getLogger(IStrategy.class);
44 private Map<BatchTransformationRule<?, ?>, Integer> priorities = new HashMap<BatchTransformationRule<?, ?>, Integer>();
45
46 private Random random = new Random();
47 private Map<Object, List<Object>> bestPriorityInState = new HashMap<>();
48
49 /**
50 * Adds a depth limit to the strategy.
51 *
52 * @param depthLimit
53 * The depth limit.
54 * @return The actual instance to enable a builder pattern like usage.
55 */
56 public FixedPriorityStrategy withDepthLimit(int maxDepth) {
57 if (maxDepth < 0) {
58 this.maxDepth = Integer.MAX_VALUE;
59 } else {
60 this.maxDepth = maxDepth;
61 }
62 return this;
63 }
64
65 /**
66 * Assigns a priority to a rule. Unassigned rule will have a priority of 0.
67 *
68 * @param rule
69 * The transformation rule.
70 * @param priority
71 * The priority of the rule. Higher is better.
72 * @return The actual instance to enable a builder pattern like usage.
73 */
74 public FixedPriorityStrategy withRulePriority(BatchTransformationRule<?, ?> rule, int priority) {
75 priorities.put(rule, priority);
76 return this;
77 }
78
79 public Map<BatchTransformationRule<?, ?>, Integer> getPriorities() {
80 return priorities;
81 }
82
83 @Override
84 public void initStrategy(ThreadContext context) {
85 this.context = context;
86
87 logger.info("Fixed priority exploration strategy is initied.");
88 }
89
90 @Override
91 public void explore() {
92
93 mainloop: do {
94
95 boolean globalConstraintsAreSatisfied = context.checkGlobalConstraints();
96 if (!globalConstraintsAreSatisfied) {
97 boolean isSuccessfulUndo = context.backtrack();
98 if (!isSuccessfulUndo) {
99 logger.info("Global contraint is not satisifed and cannot backtrack.");
100 break;
101 } else {
102 logger.debug("Global contraint is not satisifed, backtrack.");
103 continue;
104 }
105 }
106
107 Fitness fitness = context.calculateFitness();
108 if (fitness.isSatisifiesHardObjectives()) {
109 context.newSolution();
110 boolean isSuccessfulUndo = context.backtrack();
111 if (!isSuccessfulUndo) {
112 logger.info("Found a solution but cannot backtrack.");
113 break;
114 } else {
115 logger.debug("Found a solution, backtrack.");
116 continue;
117 }
118 }
119
120 if (context.getDepth() >= maxDepth) {
121 boolean isSuccessfulUndo = context.backtrack();
122 if (!isSuccessfulUndo) {
123 logger.info("Reached max depth but cannot bactrack.");
124 break;
125 } else {
126 logger.debug("Reached max depth, bactrack.");
127 continue;
128 }
129 }
130
131 if (isInterrupted.get()) {
132 logger.info("Interrupted, stop exploration.");
133 break;
134 }
135
136 List<Object> transitions;
137
138 do {
139
140 transitions = bestPriorityInState.get(context.getCurrentStateId());
141
142 if (transitions == null) {
143 Integer bestPriority = getBestPriority(context.getCurrentActivationIds());
144 transitions = Lists.newArrayList();
145 for (Object iTransition : context.getCurrentActivationIds()) {
146 Integer integer = priorities.get(context.getRuleByActivationId(iTransition));
147 if (integer == null) {
148 integer = Integer.valueOf(0);
149 }
150 if (integer.equals(bestPriority)) {
151 transitions.add(iTransition);
152 }
153 }
154 bestPriorityInState.put(context.getCurrentStateId(), transitions);
155 }
156
157 if (transitions.isEmpty()) {
158 boolean isSuccessfulUndo = context.backtrack();
159 if (!isSuccessfulUndo) {
160 logger.info("No more transitions from current state and cannot backtrack.");
161 break mainloop;
162 } else {
163 logger.debug("No more transitions from current state, backtrack.");
164 continue;
165 }
166 }
167 } while (transitions.isEmpty());
168
169 int index = random.nextInt(transitions.size());
170 Object transition = transitions.remove(index);
171
172 context.executeAcitvationId(transition);
173
174 boolean loopInTrajectory = context.isCurrentStateInTrajectory();
175 if (loopInTrajectory) {
176 boolean isSuccessfulUndo = context.backtrack();
177 if (!isSuccessfulUndo) {
178 throw new DSEException(
179 "The new state is present in the trajectoy but cannot bactkrack. Should never happen!");
180 } else {
181 logger.info("The new state is already visited in the trajectory, backtrack.");
182 }
183 }
184
185 } while (true);
186
187 logger.info("Terminated.");
188 }
189
190 @Override
191 public void interruptStrategy() {
192 isInterrupted.set(true);
193 }
194
195 private Integer getBestPriority(Collection<? extends Object> transitions) {
196 Integer bestPriority = Integer.MIN_VALUE;
197 for (Object iTransition : transitions) {
198 Integer priority = priorities.get(context.getRuleByActivationId(iTransition));
199 if (priority == null) {
200 priority = Integer.valueOf(0);
201 }
202 if (priority > bestPriority) {
203 bestPriority = priority;
204 }
205 }
206 return bestPriority;
207 }
208}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/HillClimbingStrategy.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/HillClimbingStrategy.java
new file mode 100644
index 00000000..0ccb0668
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/HillClimbingStrategy.java
@@ -0,0 +1,142 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.impl;
10
11import java.util.ArrayList;
12import java.util.Collection;
13import java.util.Random;
14import java.util.concurrent.atomic.AtomicBoolean;
15
16import org.apache.log4j.Logger;
17import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
18import org.eclipse.viatra.dse.base.ThreadContext;
19import org.eclipse.viatra.dse.objectives.Fitness;
20import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
21import org.eclipse.viatra.dse.objectives.TrajectoryFitness;
22
23public class HillClimbingStrategy implements IStrategy {
24
25 private AtomicBoolean isInterrupted = new AtomicBoolean(false);
26 private ThreadContext context;
27
28 private Logger logger = Logger.getLogger(IStrategy.class);
29
30 private Random random = new Random();
31 private double percentOfOpenedStates;
32 private ObjectiveComparatorHelper objectiveComparatorHelper;
33
34 public HillClimbingStrategy() {
35 this(2);
36 }
37
38 public HillClimbingStrategy(double percentOfOpenedStates) {
39 this.percentOfOpenedStates = percentOfOpenedStates;
40 }
41
42 @Override
43 public void initStrategy(ThreadContext context) {
44 this.context = context;
45 objectiveComparatorHelper = context.getObjectiveComparatorHelper();
46 logger.info("Hill climbing exploration strategy is initied.");
47 }
48
49 @Override
50 public void explore() {
51
52 boolean globalConstraintsAreSatisfied = context.checkGlobalConstraints();
53 if (!globalConstraintsAreSatisfied) {
54 boolean isSuccessfulUndo = context.backtrack();
55 if (!isSuccessfulUndo) {
56 logger.info("Global contraint is not satisifed and cannot backtrack.");
57 return;
58 }
59 }
60
61 mainloop: do {
62
63 Fitness previousFitness = context.calculateFitness();
64
65 logger.debug("Current depth: " + context.getDepth() + " Fitness: " + previousFitness);
66
67 Collection<Object> transitionsFromCurrentState = context.getCurrentActivationIds();
68
69 while (transitionsFromCurrentState.isEmpty()) {
70 logger.debug("No transitions from current state: considered as a solution.");
71 saveSolutionAndBacktrack();
72 continue mainloop;
73 }
74
75 ArrayList<Object> transitionsToTry = new ArrayList<>(transitionsFromCurrentState.size());
76 for (Object transition : transitionsFromCurrentState) {
77 transitionsToTry.add(transition);
78 }
79 double numberOfTransitionsToTry = transitionsToTry.size() * percentOfOpenedStates;
80
81 for (; numberOfTransitionsToTry > 0 && !transitionsToTry.isEmpty(); numberOfTransitionsToTry--) {
82 int index = random.nextInt(transitionsToTry.size());
83 Object transition = transitionsToTry.remove(index);
84
85 context.executeAcitvationId(transition);
86
87 if (!context.checkGlobalConstraints()) {
88 logger.debug("Global contraint is not satisifed, backtrack.");
89 context.backtrack();
90 continue;
91 }
92 if (context.isCurrentStateInTrajectory()) {
93 logger.debug("Current state is in trajectory, backtrack.");
94 context.backtrack();
95 continue;
96 }
97
98 Fitness fitness = context.calculateFitness();
99 objectiveComparatorHelper.addTrajectoryFitness(
100 new TrajectoryFitness(context.getTrajectoryInfo().getLastActivationId(), fitness));
101 context.backtrack();
102 }
103
104 if (objectiveComparatorHelper.getTrajectoryFitnesses().isEmpty()) {
105 logger.debug("No viable transitions from current state: considered as a solution.");
106 saveSolutionAndBacktrack();
107 continue;
108 }
109
110 TrajectoryFitness randomBestFitness = objectiveComparatorHelper.getRandomBest();
111 objectiveComparatorHelper.clearTrajectoryFitnesses();
112
113 int compare = objectiveComparatorHelper.compare(previousFitness, randomBestFitness.fitness);
114
115 if (compare > 0) {
116 saveSolutionAndBacktrack();
117 continue;
118 } else {
119 previousFitness = randomBestFitness.fitness;
120 Object transition = randomBestFitness.trajectory[randomBestFitness.trajectory.length - 1];
121 context.executeAcitvationId(transition);
122 }
123
124 } while (!isInterrupted.get());
125
126 logger.info("Terminated.");
127 }
128
129 private void saveSolutionAndBacktrack() {
130 context.calculateFitness();
131 context.newSolution();
132 logger.debug("Found solution: " + context.getTrajectoryInfo().toString());
133 logger.debug("Backtrack for more solutions, if needed.");
134 context.backtrackUntilRoot();
135 }
136
137 @Override
138 public void interruptStrategy() {
139 isInterrupted.set(true);
140 }
141
142}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/RandomSearchStrategy.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/RandomSearchStrategy.java
new file mode 100644
index 00000000..af8fb8cc
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/impl/RandomSearchStrategy.java
@@ -0,0 +1,163 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.impl;
10
11import java.util.Collection;
12import java.util.Iterator;
13import java.util.Random;
14import java.util.concurrent.atomic.AtomicBoolean;
15import java.util.concurrent.atomic.AtomicInteger;
16
17import org.apache.log4j.Logger;
18import org.eclipse.viatra.dse.api.DSEException;
19import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
20import org.eclipse.viatra.dse.base.GlobalContext;
21import org.eclipse.viatra.dse.base.ThreadContext;
22import org.eclipse.viatra.dse.designspace.api.TrajectoryInfo;
23import org.eclipse.viatra.dse.objectives.Fitness;
24
25public class RandomSearchStrategy implements IStrategy {
26
27 private static class SharedData {
28 public final AtomicInteger triesLeft;
29 public final int minDepth;
30 public final int maxDepth;
31
32 public SharedData(int minDepth, int maxDepth, int numberOfTries) {
33 this.minDepth = minDepth;
34 this.maxDepth = maxDepth;
35 this.triesLeft = new AtomicInteger(numberOfTries);
36 }
37 }
38
39 private int maxDepth = -1;
40 private Random rnd = new Random();
41 private SharedData shared;
42 private TrajectoryInfo trajectoryInfo;
43 int nth;
44 private ThreadContext context;
45 private AtomicBoolean isInterrupted = new AtomicBoolean(false);
46 private Logger logger = Logger.getLogger(IStrategy.class);
47
48 public RandomSearchStrategy(int minDepth, int maxDepth, int numberOfTries) {
49 shared = new SharedData(minDepth, maxDepth, numberOfTries);
50 }
51
52 private RandomSearchStrategy() {
53 }
54
55 @Override
56 public void initStrategy(ThreadContext context) {
57 this.context = context;
58 trajectoryInfo = context.getTrajectoryInfo();
59 GlobalContext gc = context.getGlobalContext();
60
61 Object sharedObject = gc.getSharedObject();
62 if (sharedObject == null) {
63 gc.setSharedObject(shared);
64 logger.info("Random exploration strategy is initied.");
65 startThreads();
66 } else {
67 shared = (SharedData) sharedObject;
68 }
69
70 maxDepth = rnd.nextInt(shared.maxDepth - shared.minDepth) + shared.minDepth;
71
72 }
73
74 @Override
75 public void explore() {
76
77 do {
78
79 boolean globalConstraintsAreSatisfied = context.checkGlobalConstraints();
80 if (!globalConstraintsAreSatisfied) {
81 boolean isSuccessfulUndo = context.backtrack();
82 if (!isSuccessfulUndo) {
83 logger.info("Global contraint is not satisifed and cannot backtrack.");
84 break;
85 } else {
86 logger.debug("Global contraint is not satisifed, backtrack.");
87 continue;
88 }
89 }
90
91 Fitness fitness = context.calculateFitness();
92 if (fitness.isSatisifiesHardObjectives()) {
93 context.newSolution();
94 boolean isSuccessfulUndo = context.backtrack();
95 if (!isSuccessfulUndo) {
96 logger.info("Found a solution but cannot backtrack.");
97 break;
98 } else {
99 logger.debug("Found a solution, backtrack.");
100 continue;
101 }
102 }
103
104 if (trajectoryInfo.getDepth() < maxDepth) {
105
106 Collection<Object> transitions = context.getCurrentActivationIds();
107 int index = rnd.nextInt(transitions.size());
108 Object transition = getByIndex(transitions, index);
109 context.executeAcitvationId(transition);
110
111 } else {
112
113 nth = shared.triesLeft.getAndDecrement();
114 logger.debug(nth + " tries left");
115 if (nth > 0) {
116
117 context.backtrackUntilRoot();
118 maxDepth = rnd.nextInt(shared.maxDepth - shared.minDepth) + shared.minDepth;
119
120 } else {
121 break;
122 }
123 }
124
125 boolean loopInTrajectory = context.isCurrentStateInTrajectory();
126 if (loopInTrajectory) {
127 boolean isSuccessfulUndo = context.backtrack();
128 if (!isSuccessfulUndo) {
129 throw new DSEException(
130 "The new state is present in the trajectoy but cannot bactkrack. Should never happen!");
131 } else {
132 logger.info("The new state is already visited in the trajectory, backtrack.");
133 }
134 }
135
136 } while (isInterrupted.get());
137
138 logger.info("Terminated.");
139 }
140
141 @Override
142 public void interruptStrategy() {
143 isInterrupted.set(true);
144 }
145
146 private void startThreads() {
147 context.startAllThreads(RandomSearchStrategy::new);
148 }
149
150 private static Object getByIndex(Collection<Object> availableTransitions, int index) {
151 int i = 0;
152 Iterator<Object> iterator = availableTransitions.iterator();
153 while (iterator.hasNext()) {
154 Object transition = iterator.next();
155 if (i == index) {
156 return transition;
157 } else {
158 ++i;
159 }
160 }
161 throw new IndexOutOfBoundsException("size: " + availableTransitions.size() + ", index: " + index);
162 }
163}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategy.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategy.java
new file mode 100644
index 00000000..8c164396
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategy.java
@@ -0,0 +1,44 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.interfaces;
10
11import org.eclipse.viatra.dse.base.ThreadContext;
12import org.eclipse.viatra.dse.solutionstore.SolutionStore;
13
14/**
15 * This high level interface is responsible for defining basic operations of an exploration strategy.
16 *
17 * @author Andras Szabolcs Nagy
18 *
19 */
20public interface IStrategy {
21
22 /**
23 * Initializes the strategy with a specific {@link ThreadContext}.
24 *
25 * @param context
26 * The context.
27 */
28 void initStrategy(ThreadContext context);
29
30 /**
31 * This method explores the design space as the implementation specifies. It will be called only once, hence the
32 * exploration loop is run by the implementation. The termination condition is also specified by the implementation
33 * and when it returns the exploration thread will be disposed.
34 */
35 void explore();
36
37 /**
38 * The implementation of this interface should be ready to be interrupted. If this method is called, the
39 * {@link IStrategy#explore()} method should return ASAP.
40 *
41 * This method is also called by the {@link SolutionStore} class if enough solutions are found.
42 */
43 void interruptStrategy();
44}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategyFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategyFactory.java
new file mode 100644
index 00000000..b3352d13
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/strategy/interfaces/IStrategyFactory.java
@@ -0,0 +1,13 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.api.strategy.interfaces;
10
11public interface IStrategyFactory {
12 IStrategy createStrategy();
13}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ActivationCodesConflictSet.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ActivationCodesConflictSet.java
new file mode 100644
index 00000000..d3990c23
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ActivationCodesConflictSet.java
@@ -0,0 +1,213 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import java.util.Collection;
12import java.util.HashMap;
13import java.util.HashSet;
14import java.util.Map;
15import java.util.Objects;
16import java.util.Set;
17
18import org.eclipse.viatra.dse.statecode.IStateCoder;
19import org.eclipse.viatra.query.runtime.api.IPatternMatch;
20import org.eclipse.viatra.transformation.evm.api.Activation;
21import org.eclipse.viatra.transformation.evm.api.resolver.ChangeableConflictSet;
22import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver;
23import org.eclipse.viatra.transformation.evm.api.resolver.ConflictSet;
24
25public class ActivationCodesConflictSet implements ChangeableConflictSet {
26
27 private static class ActivationCodesMultiBiMap {
28 public Map<Activation<?>, Object> activationsToCodes = new HashMap<>();
29 public Map<Object, Set<Activation<?>>> codesToActivations = new HashMap<>();
30
31 public void addActivation(Activation<?> activation, Object activationCode) {
32 activationsToCodes.put(activation, activationCode);
33 codesToActivations.computeIfAbsent(activationCode, k -> new HashSet<>()).add(activation);
34 }
35
36 public void removeActivaion(Activation<?> activation) {
37 Object activationCode = activationsToCodes.remove(activation);
38 Set<Activation<?>> activations = codesToActivations.get(activationCode);
39 if (activations != null) {
40 activations.remove(activation);
41 }
42 }
43
44 public void clear() {
45 activationsToCodes.clear();
46 codesToActivations.clear();
47 }
48 }
49
50 protected ActivationCodesMultiBiMap activationCodes;
51 protected IStateCoder stateCoder;
52
53 protected Set<Activation<?>> newActivations = new HashSet<>();
54 protected Set<Activation<?>> removedActivations = new HashSet<>();
55// private Logger logger = Logger.getLogger(getClass());
56
57 private boolean isIncremental = false;
58 private ConflictSet nextActivationsConflictSet;
59
60 public void setIncremental(boolean isIncremental) {
61 this.isIncremental = isIncremental;
62 }
63
64 public ActivationCodesConflictSet(ConflictSet nextActivationsConflictSet, IStateCoder stateCoder) {
65 Objects.requireNonNull(nextActivationsConflictSet);
66 this.nextActivationsConflictSet = nextActivationsConflictSet;
67 this.stateCoder = stateCoder;
68 activationCodes = new ActivationCodesMultiBiMap();
69 }
70
71 private Object createActivationCode(Activation<?> activation) {
72 return stateCoder.createActivationCode((IPatternMatch) activation.getAtom());
73 }
74
75 @Override
76 public boolean removeActivation(Activation<?> activation) {
77 if (isIncremental) {
78//*
79 removedActivations.add(activation);
80 newActivations.remove(activation);
81/*/
82 if(!removedActivations.add(activation)) {
83 logger.debug("Abnormal: already marked to remove: " + activation);
84 } else {
85 logger.debug("marked to remove: " + activation);
86 }
87 if(newActivations.remove(activation)) {
88 logger.debug("Abnormal: removed from new activations: " + activation);
89 }
90//*/
91 }
92 return false;
93 }
94
95 @Override
96 public boolean addActivation(Activation<?> activation) {
97 if (isIncremental) {
98//*
99 newActivations.add(activation);
100 removedActivations.remove(activation);
101 /*/
102 if (activation.isEnabled()) {
103 if (!newActivations.add(activation)) {
104 logger.debug("Abnormal: already added as new: " + activation);
105 } else {
106 logger.debug("activation added: " + activation);
107 }
108 }
109 if(removedActivations.remove(activation)) {
110 logger.debug("Abnormal: was already marked to remove: " + activation);
111 }
112//*/
113 }
114 return false;
115 }
116
117 public Object getActivationId(Activation<?> activation) {
118 return activationCodes.activationsToCodes.get(activation);
119 }
120
121 public Activation<?> getActivation(Object activationId) {
122 Set<Activation<?>> activationsSet = activationCodes.codesToActivations.get(activationId);
123 if (activationsSet == null || activationsSet.isEmpty()) {
124 return null;
125 } else {
126 return activationsSet.iterator().next();
127 }
128 }
129
130 public void updateActivationCodes() {
131// logger.debug("Updating activation codes.");
132
133 if (isIncremental) {
134 for (Activation<?> activation : removedActivations) {
135 activationCodes.removeActivaion(activation);
136// logger.debug("removed activation: " + activationId);
137 }
138
139 for (Activation<?> activation : newActivations) {
140 if (activation.getState().isInactive()) {
141 continue;
142 }
143 Object activationCode = createActivationCode(activation);
144 activationCodes.addActivation(activation, activationCode);
145// logger.debug("new activation: " + activationId);
146// Activation<?> similarActivation = activationIds.inverse().get(activationId);
147// if (similarActivation != null) {
148// logger.debug("Activation " + toStringAct(activation) + " is already present with id: " + activationId);
149// if (similarActivation.isEnabled()) {
150// logger.warn("Duplicate activation code: " + activationId);
151// } else {
152// logger.debug("Force put: " + activationId);
153// }
154// continue;
155// }
156// activationIds.put(activation, activationId);
157 }
158 removedActivations.clear();
159 newActivations.clear();
160 } else {
161 activationCodes.clear();
162 for (Activation<?> activation : nextActivationsConflictSet.getNextActivations()) {
163 Object activationCode = createActivationCode(activation);
164 activationCodes.addActivation(activation, activationCode);
165 }
166 }
167
168
169 }
170
171 protected void reinitWithActivations(ConflictSet nextActivationsConflictSet) {
172 this.nextActivationsConflictSet = nextActivationsConflictSet;
173 activationCodes.clear();
174 for (Activation<?> activation : nextActivationsConflictSet.getNextActivations()) {
175 Object activationCode = createActivationCode(activation);
176 activationCodes.addActivation(activation, activationCode);
177 }
178 }
179
180 @Override
181 public Activation<?> getNextActivation() {
182 throw new UnsupportedOperationException();
183 }
184
185 @Override
186 public Set<Activation<?>> getNextActivations() {
187 throw new UnsupportedOperationException();
188 }
189
190 @Override
191 public Set<Activation<?>> getConflictingActivations() {
192 throw new UnsupportedOperationException();
193 }
194
195 @Override
196 public ConflictResolver getConflictResolver() {
197 throw new UnsupportedOperationException();
198 }
199
200 @Override
201 public String toString() {
202 StringBuilder sb = new StringBuilder();
203 for (Object activationCode : activationCodes.activationsToCodes.values()) {
204 sb.append(activationCode);
205 sb.append(" | ");
206 }
207 return sb.toString();
208 }
209
210 public Collection<Object> getCurrentActivationCodes() {
211 return activationCodes.activationsToCodes.values();
212 }
213}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DesignSpaceManager.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DesignSpaceManager.java
new file mode 100644
index 00000000..133ef948
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DesignSpaceManager.java
@@ -0,0 +1,577 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import java.lang.reflect.InvocationTargetException;
12import java.util.ArrayList;
13import java.util.Collection;
14import java.util.HashMap;
15import java.util.Iterator;
16import java.util.List;
17import java.util.Map;
18import java.util.Random;
19
20import org.apache.log4j.Logger;
21import org.eclipse.emf.common.notify.Notifier;
22import org.eclipse.emf.edit.command.ChangeCommand;
23import org.eclipse.emf.edit.domain.EditingDomain;
24import org.eclipse.viatra.dse.api.DSEException;
25import org.eclipse.viatra.dse.api.SolutionTrajectory;
26import org.eclipse.viatra.dse.designspace.api.IBacktrackListener;
27import org.eclipse.viatra.dse.designspace.api.IDesignSpace;
28import org.eclipse.viatra.dse.designspace.api.TrajectoryInfo;
29import org.eclipse.viatra.dse.objectives.ActivationFitnessProcessor;
30import org.eclipse.viatra.dse.statecode.IStateCoder;
31import org.eclipse.viatra.dse.visualizer.IExploreEventHandler;
32import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine;
33import org.eclipse.viatra.query.runtime.api.IPatternMatch;
34import org.eclipse.viatra.transformation.evm.api.Activation;
35import org.eclipse.viatra.transformation.evm.api.Context;
36import org.eclipse.viatra.transformation.evm.api.resolver.ChangeableConflictSet;
37import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
38
39public class DesignSpaceManager implements IBacktrackListener {
40
41 private final IStateCoder stateCoder;
42 private final EditingDomain domain;
43 private Notifier model;
44
45 private IDesignSpace designSpace;
46
47 private final TrajectoryInfo trajectory;
48
49 // the occurence vector callback
50 private List<IExploreEventHandler> handlers;
51
52 // Dummy context for evm
53 private final Context evmContext = Context.create();
54
55 private Logger logger = Logger.getLogger(this.getClass());
56
57 private boolean isNewState = false;
58 private Map<BatchTransformationRule<?, ?>, ActivationFitnessProcessor> activationFitnessProcessors;
59 private Map<BatchTransformationRule<?, ?>, String> activationFitnessProcessorNames;
60 private ThreadContext context;
61
62 private ActivationCodesConflictSet activationCodes;
63 private ChangeableConflictSet conflictSet;
64
65 private AdvancedViatraQueryEngine engine;
66
67 private Random random = new Random();
68
69 private long forwardTime = 0;
70 private long backtrackingTime = 0;
71
72 public DesignSpaceManager(ThreadContext context) {
73
74 this.context = context;
75 model = context.getModel();
76 designSpace = context.getGlobalContext().getDesignSpace();
77 domain = context.getEditingDomain();
78
79 conflictSet = context.getConflictResolver().getLastCreatedConflictSet();
80
81 stateCoder = context.getStateCoder();
82 Object initialStateId = stateCoder.createStateCode();
83 designSpace.addState(null, null, initialStateId);
84
85 activationCodes = context.getActivationCodesConflictSet();
86
87 engine = (AdvancedViatraQueryEngine) context.getQueryEngine();
88
89 this.trajectory = new TrajectoryInfo(initialStateId);
90
91 logger.debug("DesignSpaceManager initialized with initial model: " + initialStateId);
92 }
93
94 public void fireActivation(final Object transition) {
95 if (fireActivationSilent(transition)) {
96 return;
97 }
98
99 StringBuilder sb = new StringBuilder();
100 sb.append(
101 "A retrieved Transition SHOULD have a matching Activation. Possible causes: the state serializer is faulty; the algorithm choosed a wrong Transition.");
102 sb.append("\nSought transition: ");
103 sb.append(transition);
104 Object currentStateId = getCurrentState();
105 sb.append("\nCurrent known state: ");
106 sb.append(currentStateId);
107 Object actualStateId = stateCoder.createStateCode();
108 sb.append("\nActual state: ");
109 sb.append((actualStateId.equals(currentStateId) ? "same as current" : actualStateId));
110 sb.append("\n");
111 sb.append(trajectory);
112 sb.append("\nAvailable transitions:");
113 for (Activation<?> act : conflictSet.getNextActivations()) {
114 IPatternMatch match = (IPatternMatch) act.getAtom();
115 Object code = generateMatchCode(match);
116 sb.append("\n\t");
117 sb.append(code);
118 }
119
120 throw new DSEException(sb.toString());
121 }
122
123 public boolean tryFireActivation(final Object transition) {
124 return fireActivationSilent(transition);
125 }
126
127 private boolean fireActivationSilent(final Object transition) {
128 final Activation<?> activation = getActivationById(transition);
129
130 if (activation == null) {
131 return false;
132 }
133
134 BatchTransformationRule<?, ?> rule = getRuleByActivation(activation);
135
136 Map<String, Double> measureCosts = new HashMap<String, Double>();
137 if (activationFitnessProcessors != null && activationFitnessProcessors.containsKey(rule)) {
138 IPatternMatch match = (IPatternMatch) activation.getAtom();
139 ActivationFitnessProcessor processor = activationFitnessProcessors.get(rule);
140 double fitness = processor.process(match);
141 measureCosts.put(activationFitnessProcessorNames.get(rule), fitness);
142 }
143
144 ChangeCommand rc = new ChangeCommand(model) {
145 @Override
146 protected void doExecute() {
147 activation.fire(evmContext);
148 }
149 };
150
151 Object previousState = trajectory.getCurrentStateId();
152
153 long start = System.nanoTime();
154 try {
155 engine.delayUpdatePropagation(() -> {
156 domain.getCommandStack().execute(rc);
157 return null;
158 });
159 } catch (InvocationTargetException e) {
160 throw new RuntimeException(e);
161 }
162 forwardTime += System.nanoTime() - start;
163
164 Object newStateId = stateCoder.createStateCode();
165 updateActivationCodes();
166
167 if (designSpace != null) {
168 isNewState = !designSpace.isTraversed(newStateId);
169 designSpace.addState(previousState, transition, newStateId);
170 }
171
172 trajectory.addStep(transition, rule, newStateId, measureCosts);
173
174 if (handlers != null) {
175 for (IExploreEventHandler iExploreEventHandler : handlers) {
176 iExploreEventHandler.transitionFired(transition);
177 }
178 }
179
180 logger.debug("Executed activation: " + transition);/*
181 * + " from state: " + previousState + " to " + newStateId);
182 */
183
184 return true;
185 }
186
187 public boolean executeRandomActivationId() {
188 Collection<Object> transitions = getTransitionsFromCurrentState();
189 int size = transitions.size();
190 if (size == 0) {
191 return false;
192 }
193
194 int index = random.nextInt(size);
195 Iterator<Object> iterator = transitions.iterator();
196 for (int i = 0; i < index; ++i) {
197 iterator.next();
198 }
199 Object transition = iterator.next();
200
201 fireActivation(transition);
202 return true;
203 }
204
205 public int executeTrajectory(Object[] trajectoryToExecute) {
206 return executeTrajectory(trajectoryToExecute, 0, trajectoryToExecute.length, false, true);
207 }
208
209 public int executeTrajectory(Object[] trajectoryToExecute, int fromIncludedIndex, int toExcludedIndex) {
210 return executeTrajectory(trajectoryToExecute, fromIncludedIndex, toExcludedIndex, false, true);
211 }
212
213 public int executeTrajectoryByTrying(Object[] trajectoryToExecute) {
214 return executeTrajectory(trajectoryToExecute, 0, trajectoryToExecute.length, true, true);
215 }
216
217 public int executeTrajectoryByTrying(Object[] trajectoryToExecute, int fromIncludedIndex, int toExcludedIndex) {
218 return executeTrajectory(trajectoryToExecute, fromIncludedIndex, toExcludedIndex, true, true);
219 }
220
221 public int executeTrajectoryWithoutStateCoding(Object[] trajectoryToExecute) {
222 return executeTrajectory(trajectoryToExecute, 0, trajectoryToExecute.length, false, false);
223 }
224
225 public int executeTrajectoryWithoutStateCoding(Object[] trajectoryToExecute, int fromIncludedIndex,
226 int toExcludedIndex) {
227 return executeTrajectory(trajectoryToExecute, fromIncludedIndex, toExcludedIndex, false, false);
228 }
229
230 public int executeTrajectoryByTryingWithoutStateCoding(Object[] trajectoryToExecute) {
231 return executeTrajectory(trajectoryToExecute, 0, trajectoryToExecute.length, true, false);
232 }
233
234 public int executeTrajectoryByTryingWithoutStateCoding(Object[] trajectoryToExecute, int fromIncludedIndex,
235 int toExcludedIndex) {
236 return executeTrajectory(trajectoryToExecute, fromIncludedIndex, toExcludedIndex, true, false);
237 }
238
239 private int executeTrajectory(Object[] trajectoryToExecute, int fromIncludedIndex, int toExcludedIndex,
240 boolean tryAllActivations, boolean createStateCode) {
241 logger.debug("Executing trajectory.");
242 int unsuccesfulIndex = -1;
243 if (tryAllActivations) {
244 unsuccesfulIndex = 0;
245 }
246 for (int i = fromIncludedIndex; i < toExcludedIndex; i++) {
247 Object activationId = trajectoryToExecute[i];
248 final Activation<?> activation = getActivationById(activationId);
249
250 if (activation == null) {
251 logger.debug("Couldn't execute activation: " + activationId);
252 if (tryAllActivations) {
253 unsuccesfulIndex++;
254 continue;
255 } else {
256 unsuccesfulIndex = i;
257 logger.debug("Trajectory execution stopped at index " + i + "/" + trajectoryToExecute.length);
258 break;
259 }
260 }
261
262 BatchTransformationRule<?, ?> rule = getRuleByActivation(activation);
263
264 Map<String, Double> measureCosts = new HashMap<String, Double>();
265 if (activationFitnessProcessors != null && activationFitnessProcessors.containsKey(rule)) {
266 IPatternMatch match = (IPatternMatch) activation.getAtom();
267 ActivationFitnessProcessor processor = activationFitnessProcessors.get(rule);
268 double fitness = processor.process(match);
269 measureCosts.put(activationFitnessProcessorNames.get(rule), fitness);
270 }
271
272 ChangeCommand rc = new ChangeCommand(model) {
273 @Override
274 protected void doExecute() {
275 activation.fire(evmContext);
276 }
277 };
278
279 long start = System.nanoTime();
280 try {
281 engine.delayUpdatePropagation(() -> {
282 domain.getCommandStack().execute(rc);
283 return null;
284 });
285 } catch (InvocationTargetException e) {
286 throw new RuntimeException(e);
287 }
288 forwardTime += System.nanoTime() - start;
289
290 Object newStateId = null;
291 if (createStateCode) {
292 newStateId = stateCoder.createStateCode();
293 }
294 updateActivationCodes();
295
296 trajectory.addStep(activationId, rule, newStateId, measureCosts);
297
298 logger.debug("Activation executed: " + activationId);
299 }
300 if (!createStateCode) {
301 trajectory.modifyLastStateCode(stateCoder.createStateCode());
302 }
303 logger.debug("Trajectory execution finished.");
304 return unsuccesfulIndex;
305
306 }
307
308 public Object getTransitionByActivation(Activation<?> activation) {
309 return activationCodes.getActivationId(activation);
310 }
311
312 public Activation<?> getActivationById(Object activationId) {
313 return activationCodes.getActivation(activationId);
314 }
315
316 public BatchTransformationRule<?, ?> getRuleByActivation(Activation<?> activation) {
317 return context.getGlobalContext().getSpecificationRuleMap().get(activation.getInstance().getSpecification());
318 }
319
320 public BatchTransformationRule<?, ?> getRuleByActivationId(Object activationId) {
321 return getRuleByActivation(getActivationById(activationId));
322 }
323
324 /**
325 * Returns true if the given state is not owned by this crawler.
326 *
327 **/
328 public boolean isNewModelStateAlreadyTraversed() {
329 return !isNewState;
330 }
331
332 public List<Object> getTrajectoryFromRoot() {
333 return trajectory.getTrajectory();
334 }
335
336 public Collection<Object> getTransitionsFromCurrentState() {
337 return activationCodes.getCurrentActivationCodes();
338 }
339
340 public Collection<Object> getUntraversedTransitionsFromCurrentState() {
341 if (designSpace == null) {
342 throw new DSEException("Unsupported without a design space");
343 }
344 Object currentState = trajectory.getCurrentStateId();
345 Collection<Object> traversedIds = designSpace.getActivationIds(currentState);
346
347 List<Object> untraversedTransitions = new ArrayList<>();
348 for (Object activationId : activationCodes.getCurrentActivationCodes()) {
349 if (!traversedIds.contains(activationId)) {
350 untraversedTransitions.add(activationId);
351 }
352 }
353
354 return untraversedTransitions;
355 }
356
357 public boolean undoLastTransformation() {
358
359 if (!trajectory.canStepBack()) {
360 return false;
361 }
362
363 long start = System.nanoTime();
364 try {
365 engine.delayUpdatePropagation(() -> {
366 domain.getCommandStack().undo();
367 return null;
368 });
369 } catch (InvocationTargetException e) {
370 throw new RuntimeException(e);
371 }
372 backtrackingTime += System.nanoTime() - start;
373 updateActivationCodes();
374
375 Object lastActivationId = trajectory.getLastActivationId();
376
377 trajectory.backtrack();
378
379 if (handlers != null) {
380 for (IExploreEventHandler iExploreEventHandler : handlers) {
381 iExploreEventHandler.undo(lastActivationId);
382 }
383 }
384
385 logger.debug("Backtrack.");
386
387 return true;
388 }
389
390 public void backtrackXTimes(int steps) {
391 long start = System.nanoTime();
392 try {
393 engine.delayUpdatePropagation(() -> {
394 for (int i = steps; i > 0; i--) {
395 domain.getCommandStack().undo();
396 trajectory.backtrack();
397 }
398 return null;
399 });
400 } catch (InvocationTargetException e) {
401 throw new RuntimeException(e);
402 }
403 backtrackingTime += System.nanoTime() - start;
404 updateActivationCodes();
405 logger.debug("Backtracked " + steps + " times.");
406 }
407
408 public int backtrackUntilLastCommonActivation(Object[] newTrajectory) {
409 long start = System.nanoTime();
410 Iterator<Object> currentTrajectoryIterator = trajectory.getTrajectory().iterator();
411 if (!currentTrajectoryIterator.hasNext()) {
412 return 0;
413 }
414 int indexOfLastCommonActivation = 0;
415 for (Object activationCode : newTrajectory) {
416 if (currentTrajectoryIterator.hasNext()) {
417 Object activationCodeFromCurrent = currentTrajectoryIterator.next();
418 if (activationCodeFromCurrent.equals(activationCode)) {
419 indexOfLastCommonActivation++;
420 } else {
421 break;
422 }
423 } else {
424 // current trajectory is smaller
425 break;
426 }
427 }
428 int numberOfBacktracks = trajectory.getDepth() - indexOfLastCommonActivation;
429 if (numberOfBacktracks > 0) {
430 try {
431 engine.delayUpdatePropagation(() -> {
432 for (int i = numberOfBacktracks; i > 0; i--) {
433 domain.getCommandStack().undo();
434 trajectory.backtrack();
435 }
436 return null;
437 });
438 } catch (InvocationTargetException e) {
439 throw new RuntimeException(e);
440 }
441 }
442 backtrackingTime += System.nanoTime() - start;
443 updateActivationCodes();
444 logger.debug("Backtracked " + numberOfBacktracks + " times.");
445 return indexOfLastCommonActivation;
446 }
447
448 public void executeTrajectoryWithMinimalBacktrack(Object[] trajectory) {
449 executeTrajectoryWithMinimalBacktrack(trajectory, trajectory.length);
450 }
451
452 public void executeTrajectoryWithMinimalBacktrack(Object[] trajectory, int toExcludedIndex) {
453 int fromIndex = backtrackUntilLastCommonActivation(trajectory);
454 executeTrajectory(trajectory, fromIndex, toExcludedIndex, false, true);
455 }
456
457 public void executeTrajectoryWithMinimalBacktrackWithoutStateCoding(Object[] trajectory) {
458 executeTrajectoryWithMinimalBacktrackWithoutStateCoding(trajectory, trajectory.length);
459 }
460
461 public void executeTrajectoryWithMinimalBacktrackWithoutStateCoding(Object[] trajectory, int toExcludedIndex) {
462 int fromIndex = backtrackUntilLastCommonActivation(trajectory);
463 executeTrajectory(trajectory, fromIndex, toExcludedIndex, false, false);
464 Object stateCode = stateCoder.createStateCode();
465 this.trajectory.modifyLastStateCode(stateCode);
466 }
467
468 public void undoUntilRoot() {
469 long start = System.nanoTime();
470 try {
471 engine.delayUpdatePropagation(() -> {
472 while (trajectory.canStepBack()) {
473 domain.getCommandStack().undo();
474 trajectory.backtrack();
475 }
476 return null;
477 });
478 } catch (InvocationTargetException e) {
479 throw new RuntimeException(e);
480 }
481 backtrackingTime += System.nanoTime() - start;
482 updateActivationCodes();
483 logger.debug("Backtracked to root.");
484 }
485
486 private Object generateMatchCode(IPatternMatch match) {
487 return stateCoder.createActivationCode(match);
488 }
489
490 public Object getCurrentState() {
491 return trajectory.getCurrentStateId();
492 }
493
494 public SolutionTrajectory createSolutionTrajectroy() {
495 return trajectory.createSolutionTrajectory(context.getGlobalContext().getStateCoderFactory(), this);
496 }
497
498 public TrajectoryInfo getTrajectoryInfo() {
499 return trajectory;
500 }
501
502 public void setDesignSpace(IDesignSpace designSpace) {
503 this.designSpace = designSpace;
504 }
505
506 public IDesignSpace getDesignSpace() {
507 return designSpace;
508 }
509
510 public void registerExploreEventHandler(IExploreEventHandler handler) {
511 if (handler == null) {
512 return;
513 }
514 if (handlers == null) {
515 handlers = new ArrayList<IExploreEventHandler>();
516 }
517 handlers.add(handler);
518 }
519
520 public void deregisterExploreEventHandler(IExploreEventHandler handler) {
521 if (handler == null) {
522 return;
523 }
524 if (handlers != null) {
525 handlers.remove(handler);
526 }
527 }
528
529 public void registerActivationCostProcessor(String name, BatchTransformationRule<?, ?> rule,
530 ActivationFitnessProcessor activationFitnessProcessor) {
531 if (activationFitnessProcessors == null || activationFitnessProcessorNames == null) {
532 activationFitnessProcessors = new HashMap<BatchTransformationRule<?, ?>, ActivationFitnessProcessor>();
533 activationFitnessProcessorNames = new HashMap<BatchTransformationRule<?, ?>, String>();
534 }
535 activationFitnessProcessors.put(rule, activationFitnessProcessor);
536 activationFitnessProcessorNames.put(rule, name);
537 }
538
539 public boolean isCurentStateInTrajectory() {
540 Object currentStateId = trajectory.getCurrentStateId();
541 List<Object> stateTrajectory = trajectory.getStateTrajectory();
542 int size = stateTrajectory.size();
543 for (int i = 0; i < size - 1; i++) {
544 Object stateId = stateTrajectory.get(i);
545 if (currentStateId.equals(stateId)) {
546 return true;
547 }
548 }
549 return false;
550 }
551
552 public IStateCoder getStateCoder() {
553 return stateCoder;
554 }
555
556 private void updateActivationCodes() {
557 activationCodes.updateActivationCodes();
558 }
559
560 public long getForwardTime() {
561 return forwardTime;
562 }
563
564 public long getBacktrackingTime() {
565 return backtrackingTime;
566 }
567
568 @Override
569 public void forwardWorked(long nanos) {
570 forwardTime += nanos;
571 }
572
573 @Override
574 public void backtrackWorked(long nanos) {
575 backtrackingTime += nanos;
576 }
577}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictResolver.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictResolver.java
new file mode 100644
index 00000000..35504b56
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictResolver.java
@@ -0,0 +1,35 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import org.eclipse.viatra.dse.statecode.IStateCoder;
12import org.eclipse.viatra.transformation.evm.api.resolver.ChangeableConflictSet;
13import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver;
14
15public class DseConflictResolver implements ConflictResolver {
16
17 private ConflictResolver activationOrderingconflictResolver;
18 private IStateCoder stateCoder;
19 private DseConflictSet lastCreatedConflictSet;
20
21 public DseConflictResolver(ConflictResolver activationOrderingConflictResolver, IStateCoder stateCoder) {
22 this.activationOrderingconflictResolver = activationOrderingConflictResolver;
23 this.stateCoder = stateCoder;
24 }
25
26 @Override
27 public ChangeableConflictSet createConflictSet() {
28 lastCreatedConflictSet = new DseConflictSet(this, activationOrderingconflictResolver, stateCoder);
29 return lastCreatedConflictSet;
30 }
31
32 public DseConflictSet getLastCreatedConflictSet() {
33 return lastCreatedConflictSet;
34 }
35}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictSet.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictSet.java
new file mode 100644
index 00000000..cba595f4
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseConflictSet.java
@@ -0,0 +1,83 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import java.util.Set;
12
13import org.eclipse.viatra.dse.statecode.IStateCoder;
14import org.eclipse.viatra.transformation.evm.api.Activation;
15import org.eclipse.viatra.transformation.evm.api.resolver.ChangeableConflictSet;
16import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver;
17
18public class DseConflictSet implements ChangeableConflictSet {
19
20 private ActivationCodesConflictSet activationCodesConflictSet;
21 private ChangeableConflictSet activationOrderingConflictSet;
22 private ChangeableConflictSet prevActivationOrderingConflictSet;
23 private ConflictResolver resolver;
24
25 public DseConflictSet(ConflictResolver resolver, ConflictResolver activationOrderingConflictResolver,
26 IStateCoder stateCoder) {
27 this.resolver = resolver;
28 activationOrderingConflictSet = activationOrderingConflictResolver.createConflictSet();
29 activationCodesConflictSet = new ActivationCodesConflictSet(activationOrderingConflictSet, stateCoder);
30 }
31
32 @Override
33 public Activation<?> getNextActivation() {
34 return activationOrderingConflictSet.getNextActivation();
35 }
36
37 @Override
38 public Set<Activation<?>> getNextActivations() {
39 return activationOrderingConflictSet.getNextActivations();
40 }
41
42 @Override
43 public Set<Activation<?>> getConflictingActivations() {
44 return activationOrderingConflictSet.getConflictingActivations();
45 }
46
47 @Override
48 public ConflictResolver getConflictResolver() {
49 return resolver;
50 }
51
52 @Override
53 public boolean addActivation(Activation<?> activation) {
54 activationCodesConflictSet.addActivation(activation);
55 return activationOrderingConflictSet.addActivation(activation);
56 }
57
58 @Override
59 public boolean removeActivation(Activation<?> activation) {
60 activationCodesConflictSet.removeActivation(activation);
61 return activationOrderingConflictSet.removeActivation(activation);
62 }
63
64 public ActivationCodesConflictSet getActivationCodesConflictSet() {
65 return activationCodesConflictSet;
66 }
67
68 public void changeActivationOrderingConflictSet(ChangeableConflictSet newActivationOrderingConflictSet) {
69 for (Activation<?> activation : activationOrderingConflictSet.getConflictingActivations()) {
70 newActivationOrderingConflictSet.addActivation(activation);
71 }
72 activationCodesConflictSet.reinitWithActivations(newActivationOrderingConflictSet);
73 ChangeableConflictSet tmp = activationOrderingConflictSet;
74 activationOrderingConflictSet = newActivationOrderingConflictSet;
75 prevActivationOrderingConflictSet = tmp;
76 }
77
78 public void changeActivationOrderingConflictSetBack() {
79 ChangeableConflictSet newActivationOrderingConflictSet =
80 prevActivationOrderingConflictSet.getConflictResolver().createConflictSet();
81 changeActivationOrderingConflictSet(newActivationOrderingConflictSet);
82 }
83}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseEvmRuleBase.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseEvmRuleBase.java
new file mode 100644
index 00000000..838c1d1b
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseEvmRuleBase.java
@@ -0,0 +1,21 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import org.eclipse.viatra.transformation.evm.api.Agenda;
12import org.eclipse.viatra.transformation.evm.api.RuleBase;
13import org.eclipse.viatra.transformation.evm.api.event.EventRealm;
14
15public class DseEvmRuleBase extends RuleBase {
16
17 public DseEvmRuleBase(EventRealm eventRealm, Agenda agenda) {
18 super(eventRealm, agenda);
19 }
20
21}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseIdPoolHelper.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseIdPoolHelper.java
new file mode 100644
index 00000000..f6fee7be
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/DseIdPoolHelper.java
@@ -0,0 +1,68 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import java.util.Collection;
12import java.util.HashMap;
13import java.util.concurrent.ConcurrentHashMap;
14
15import org.eclipse.viatra.dse.api.DSEException;
16import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
17
18public enum DseIdPoolHelper {
19
20 INSTANCE;
21
22 public static interface IGetRuleExecutions {
23 int getRuleExecutions(BatchTransformationRule<?, ?> rule);
24 }
25
26 public static class IdProvider {
27
28 private final BatchTransformationRule<?, ?> rule;
29 private IGetRuleExecutions getRuleExecutions;
30
31 public IdProvider(IGetRuleExecutions getRuleExecutions, BatchTransformationRule<?, ?> rule) {
32 this.getRuleExecutions = getRuleExecutions;
33 this.rule = rule;
34 }
35
36 public int getId() {
37 return getRuleExecutions.getRuleExecutions(rule);
38 }
39
40 }
41
42 private ConcurrentHashMap<Thread, HashMap<BatchTransformationRule<?, ?>, IdProvider>> idProviders = new ConcurrentHashMap<>();
43
44 public int getId(BatchTransformationRule<?, ?> rule) {
45 Thread currentThread = Thread.currentThread();
46 HashMap<BatchTransformationRule<?, ?>, IdProvider> ruleMap = idProviders.get(currentThread);
47 if (ruleMap == null) {
48 throw new DSEException("There is no registered id provider");
49 }
50 IdProvider idProvider = ruleMap.get(rule);
51 return idProvider.getId();
52 }
53
54 public void registerRules(IGetRuleExecutions getRuleExecutions, Collection<BatchTransformationRule<?, ?>> rules) {
55 Thread currentThread = Thread.currentThread();
56 HashMap<BatchTransformationRule<?, ?>, IdProvider> ruleMap = new HashMap<>();
57 for (BatchTransformationRule<?, ?> rule : rules) {
58 IdProvider idProvider = new IdProvider(getRuleExecutions, rule);
59 ruleMap.put(rule, idProvider);
60 }
61 idProviders.put(currentThread, ruleMap);
62 }
63
64 public void disposeByThread() {
65 Thread currentThread = Thread.currentThread();
66 idProviders.remove(currentThread);
67 }
68}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ExplorerThread.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ExplorerThread.java
new file mode 100644
index 00000000..f2231e5c
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ExplorerThread.java
@@ -0,0 +1,88 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import org.apache.log4j.Logger;
12import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
13import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
14import org.eclipse.viatra.transformation.evm.api.RuleEngine;
15
16/**
17 * This class implements the {@link Runnable} interface, to able to run an exploration strategy in a separate thread. It
18 * is also responsible to initialize the exploration, start the exploration (call the {@link IStrategy#explore()}
19 * method), catch any exception during exploration and to shutdown the thread correctly.
20 *
21 * @author Földenyi Miklos & Nagy Andras Szabolcs
22 *
23 */
24public class ExplorerThread implements Runnable {
25
26 private final ThreadContext threadContext;
27
28 private IStrategy strategy;
29
30 public ExplorerThread(final ThreadContext context) {
31 this.threadContext = context;
32 strategy = threadContext.getStrategy();
33 }
34
35 /**
36 * Signals the {@link IStrategy} instance that execution should be stopped. By contract, the strategy is to
37 * stop execution at the next stage of execution where stopping and exiting is appropriate.
38 */
39 public void stopRunning() {
40 strategy.interruptStrategy();
41 }
42
43 /**
44 * Starts the design space exploration. Returns only when the {@link IStrategy#explore()} method returns.
45 */
46 public void run() {
47 GlobalContext globalContext = threadContext.getGlobalContext();
48 try {
49
50 threadContext.init();
51
52 strategy.initStrategy(threadContext);
53
54 strategy.explore();
55
56 threadContext.backtrackUntilRoot();
57
58 } catch (Throwable e) {
59 Logger.getLogger(IStrategy.class).error("Thread stopped unexpectedly!", e);
60 globalContext.registerException(e);
61 } finally {
62 globalContext.strategyFinished(this);
63 dispose();
64 }
65 }
66
67 /**
68 * Disposes of this strategy. Recursively calls dispose on the underlying {@link RuleEngine} and
69 * {@link ViatraQueryEngine}. Calling this is only required if the design space exploration was launched in thread, as
70 * the underlying engines get collected on the stop of the running {@link Thread}.
71 */
72 public void dispose() {
73 threadContext.getRuleEngine().dispose();
74 DseIdPoolHelper.INSTANCE.disposeByThread();
75 }
76
77 /**
78 * Returns the associated {@link ThreadContext} that houses all the thread specific data about the exploration
79 * process, and is also the gateway to the {@link GlobalContext} which stores data relevant to the design space
80 * exploration process as a whole.
81 *
82 * @return the relevant {@link ThreadContext}.
83 */
84 public ThreadContext getThreadContext() {
85 return threadContext;
86 }
87
88}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/GlobalContext.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/GlobalContext.java
new file mode 100644
index 00000000..7325ead3
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/GlobalContext.java
@@ -0,0 +1,374 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import java.util.ArrayList;
12import java.util.Collection;
13import java.util.HashMap;
14import java.util.HashSet;
15import java.util.List;
16import java.util.Map;
17import java.util.Set;
18import java.util.concurrent.ConcurrentLinkedQueue;
19import java.util.concurrent.atomic.AtomicBoolean;
20
21import org.apache.log4j.Logger;
22import org.eclipse.emf.common.notify.Notifier;
23import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
24import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategyFactory;
25import org.eclipse.viatra.dse.designspace.api.IDesignSpace;
26import org.eclipse.viatra.dse.multithreading.DSEThreadPool;
27import org.eclipse.viatra.dse.objectives.IGlobalConstraint;
28import org.eclipse.viatra.dse.objectives.IObjective;
29import org.eclipse.viatra.dse.objectives.LeveledObjectivesHelper;
30import org.eclipse.viatra.dse.solutionstore.SolutionStore;
31import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
32import org.eclipse.viatra.dse.util.EMFHelper;
33import org.eclipse.viatra.dse.visualizer.IDesignSpaceVisualizer;
34import org.eclipse.viatra.transformation.evm.api.RuleSpecification;
35import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver;
36import org.eclipse.viatra.transformation.evm.specific.ConflictResolvers;
37import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
38
39import com.google.common.base.Preconditions;
40import com.google.common.collect.ImmutableList;
41
42/**
43 * Creates new contexts for strategies. It is needed because of the multithreading.
44 *
45 * @author Andras Szabolcs Nagy
46 *
47 */
48public class GlobalContext {
49
50 // **** fields and methods for multi threading *****//
51 // *************************************************//
52
53 public enum ExplorationProcessState {
54 NOT_STARTED,
55 RUNNING,
56 STOPPING,
57 COMPLETED
58 }
59
60 private ConcurrentLinkedQueue<Throwable> exceptions = new ConcurrentLinkedQueue<Throwable>();
61
62 private volatile ExplorationProcessState state = ExplorationProcessState.NOT_STARTED;
63 private final Set<ExplorerThread> runningThreads = new HashSet<ExplorerThread>();
64 private DSEThreadPool threadPool = new DSEThreadPool();
65 private int numberOfStartedThreads = 0;
66 private IDesignSpace designSpace;
67
68 private AtomicBoolean firstThreadContextInited = new AtomicBoolean(false);
69 private AtomicBoolean firstThreadContextIniting = new AtomicBoolean(false);
70
71 private Map<RuleSpecification<?>, BatchTransformationRule<?,?>> specificationRuleMap;
72
73 private Object terminationSnycObject = new Object();
74
75 private Logger logger = Logger.getLogger(IStrategy.class);
76
77 private boolean isAlreadyInited;
78
79 public void waitForTermination() {
80 synchronized (terminationSnycObject) {
81 while (!isDone()) {
82 try {
83 terminationSnycObject.wait();
84 } catch (InterruptedException e) {
85 }
86 }
87 }
88 }
89
90 /**
91 * Starts a new thread to explore the design space.
92 *
93 * @param originalThreadContext The context of the thread which starts the new thread.
94 * @param model The model to start from.
95 * @param cloneModel It should be true in most cases.
96 * @param strategy The strategy, the thread will use.
97 * @return The {@link ExplorerThread}
98 */
99 private synchronized ExplorerThread tryStartNewThread(ThreadContext originalThreadContext, Notifier model,
100 IStrategy strategy) {
101
102 if(!isAlreadyInited) {
103 isAlreadyInited = true;
104 init();
105 }
106
107 if (state != ExplorationProcessState.COMPLETED && state != ExplorationProcessState.STOPPING
108 && threadPool.canStartNewThread()) {
109
110 ThreadContext newThreadContext = new ThreadContext(this, strategy, model);
111
112 // TODO : clone undo list? slave strategy can't go further back...
113 ExplorerThread explorerThread = new ExplorerThread(newThreadContext);
114 newThreadContext.setExplorerThread(explorerThread);
115
116 boolean isSuccessful = threadPool.tryStartNewStrategy(explorerThread);
117
118 if (isSuccessful) {
119 runningThreads.add(explorerThread);
120
121 state = ExplorationProcessState.RUNNING;
122 ++numberOfStartedThreads;
123
124 logger.info("New thread started, active threads: " + runningThreads.size());
125
126 return explorerThread;
127 }
128 }
129 return null;
130 }
131
132 public synchronized ExplorerThread tryStartNewThread(ThreadContext originalThreadContext, IStrategy strategy) {
133 return tryStartNewThread(originalThreadContext, EMFHelper.clone(originalThreadContext.getModel()), strategy);
134 }
135
136 public synchronized ExplorerThread tryStartNewThreadWithoutModelClone(ThreadContext originalThreadContext,
137 IStrategy strategy) {
138 return tryStartNewThread(originalThreadContext, originalThreadContext.getModel(), strategy);
139 }
140
141 public synchronized ExplorerThread startFirstThread(IStrategy strategy, Notifier model) {
142 Preconditions.checkState(!isAlreadyInited, "First thread is already started.");
143 return tryStartNewThread(null, EMFHelper.clone(model), strategy);
144 }
145
146 public synchronized ExplorerThread startFirstThreadWithoutModelClone(IStrategy strategy, Notifier model) {
147 Preconditions.checkState(!isAlreadyInited, "First thread is already started.");
148 return tryStartNewThread(null, model, strategy);
149 }
150
151 public synchronized void startAllThreads(ThreadContext originalThreadContext, IStrategyFactory strategyFactory) {
152 while (canStartNewThread()) {
153 tryStartNewThread(originalThreadContext, strategyFactory.createStrategy());
154 }
155 }
156
157 /**
158 * Starts a new thread to explore the design space.
159 *
160 * @param strategyBase
161 * The {@link Strategy}.
162 * @param tedToClone
163 * The model to clone. Hint: context.getTed()
164 */
165
166 public synchronized void strategyFinished(ExplorerThread strategy) {
167 runningThreads.remove(strategy);
168
169 logger.info("Thread finished, active threads: " + runningThreads.size());
170
171 // is the first part necessary?
172 if (runningThreads.isEmpty()) {
173 state = ExplorationProcessState.COMPLETED;
174 threadPool.shutdown();
175
176 // if the main thread (which started the exploration)
177 // is waiting for the solution, than wake it up
178 synchronized (terminationSnycObject) {
179 terminationSnycObject.notify();
180 logger.info("Exploration terminated.");
181 }
182
183 }
184 }
185
186 public synchronized boolean isDone() {
187 return state == ExplorationProcessState.COMPLETED && runningThreads.isEmpty();
188 }
189
190 public synchronized boolean isNotStarted() {
191 return state == ExplorationProcessState.NOT_STARTED;
192 }
193
194 public boolean canStartNewThread() {
195 return (state == ExplorationProcessState.NOT_STARTED || state == ExplorationProcessState.RUNNING)
196 && threadPool.canStartNewThread();
197 }
198
199 public synchronized void stopAllThreads() {
200 if (state == ExplorationProcessState.RUNNING) {
201 state = ExplorationProcessState.STOPPING;
202 logger.info("Stopping all threads.");
203 for (ExplorerThread strategy : runningThreads) {
204 strategy.stopRunning();
205 }
206 }
207 }
208
209 public void registerException(Throwable e) {
210 exceptions.add(e);
211 }
212
213 // ******* fields and methods for exploration *******//
214 // **************************************************//
215
216 private List<IObjective> objectives = new ArrayList<IObjective>();
217 private IObjective[][] leveledObjectives;
218 private List<IGlobalConstraint> globalConstraints = new ArrayList<IGlobalConstraint>();
219 private Set<BatchTransformationRule<?, ?>> transformations = new HashSet<BatchTransformationRule<?, ?>>();
220 private IStateCoderFactory stateCoderFactory;
221 private SolutionStore solutionStore = new SolutionStore(1);
222 private Object sharedObject;
223 private List<IDesignSpaceVisualizer> visualizers;
224
225 private ConflictResolver conflictResolver = ConflictResolvers.createArbitraryResolver();
226
227 private void init() {
228 leveledObjectives = new LeveledObjectivesHelper(objectives).initLeveledObjectives();
229
230 specificationRuleMap = new HashMap<>();
231 for (BatchTransformationRule<?,?> rule : transformations) {
232 specificationRuleMap.put(rule.getRuleSpecification(), rule);
233 }
234 }
235
236 public List<IDesignSpaceVisualizer> getVisualizers() {
237 return ImmutableList.copyOf(visualizers);
238 }
239
240 public void registerDesignSpaceVisualizer(IDesignSpaceVisualizer visualizer) {
241 if (visualizer == null) {
242 return;
243 }
244 if (visualizers == null) {
245 visualizers = new ArrayList<IDesignSpaceVisualizer>();
246 }
247 visualizers.add(visualizer);
248 }
249
250 public void deregisterDesignSpaceVisualizer(IDesignSpaceVisualizer visualizer) {
251 if (visualizer == null) {
252 return;
253 }
254 if (visualizers != null) {
255 visualizers.remove(visualizer);
256 }
257 }
258
259 public boolean isDesignSpaceVisualizerRegistered(IDesignSpaceVisualizer visualizer) {
260 if (visualizers != null) {
261 return visualizers.contains(visualizer);
262 }
263 return false;
264 }
265
266 public void initVisualizersForThread(ThreadContext threadContext) {
267 if (visualizers != null && !visualizers.isEmpty()) {
268 for (IDesignSpaceVisualizer visualizer : visualizers) {
269 visualizer.init(threadContext);
270 threadContext.getDesignSpaceManager().registerExploreEventHandler(visualizer);
271 }
272 }
273 }
274
275 public boolean isExceptionHappendInOtherThread() {
276 return !exceptions.isEmpty();
277 }
278
279 public Collection<Throwable> getExceptions() {
280 return exceptions;
281 }
282
283 public IStateCoderFactory getStateCoderFactory() {
284 return stateCoderFactory;
285 }
286
287 public void setStateCoderFactory(IStateCoderFactory stateCoderFactory) {
288 this.stateCoderFactory = stateCoderFactory;
289 }
290
291 public Set<BatchTransformationRule<?, ?>> getTransformations() {
292 return transformations;
293 }
294
295 public void setTransformations(Set<BatchTransformationRule<?, ?>> transformations) {
296 this.transformations = transformations;
297 }
298
299 public DSEThreadPool getThreadPool() {
300 return threadPool;
301 }
302
303 public IDesignSpace getDesignSpace() {
304 return designSpace;
305 }
306
307 public void setDesignSpace(IDesignSpace designSpace) {
308 this.designSpace = designSpace;
309 }
310
311 public int getNumberOfStartedThreads() {
312 return numberOfStartedThreads;
313 }
314
315 public Object getSharedObject() {
316 return sharedObject;
317 }
318
319 public void setSharedObject(Object sharedObject) {
320 this.sharedObject = sharedObject;
321 }
322
323 public ExplorationProcessState getState() {
324 return state;
325 }
326
327 public List<IObjective> getObjectives() {
328 return objectives;
329 }
330
331 public void setObjectives(List<IObjective> objectives) {
332 this.objectives = objectives;
333 }
334
335 public List<IGlobalConstraint> getGlobalConstraints() {
336 return globalConstraints;
337 }
338
339 public void setGlobalConstraints(List<IGlobalConstraint> globalConstraints) {
340 this.globalConstraints = globalConstraints;
341 }
342
343 AtomicBoolean getFirstThreadContextInited() {
344 return firstThreadContextInited;
345 }
346
347 AtomicBoolean getFirstThreadContextIniting() {
348 return firstThreadContextIniting;
349 }
350
351 public IObjective[][] getLeveledObjectives() {
352 return leveledObjectives;
353 }
354
355 public void setSolutionStore(SolutionStore solutionStore) {
356 this.solutionStore = solutionStore;
357 }
358
359 public SolutionStore getSolutionStore() {
360 return solutionStore;
361 }
362
363 public Map<RuleSpecification<?>, BatchTransformationRule<?, ?>> getSpecificationRuleMap() {
364 return specificationRuleMap;
365 }
366
367 public void setConflictResolver(ConflictResolver conflictResolver) {
368 this.conflictResolver = conflictResolver;
369 }
370
371 public ConflictResolver getConflictResolver() {
372 return conflictResolver;
373 }
374}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/IDseStrategyContext.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/IDseStrategyContext.java
new file mode 100644
index 00000000..d630964f
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/IDseStrategyContext.java
@@ -0,0 +1,117 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import java.util.Collection;
12import java.util.List;
13import java.util.Set;
14
15import org.eclipse.emf.common.notify.Notifier;
16import org.eclipse.emf.edit.domain.EditingDomain;
17import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
18import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategyFactory;
19import org.eclipse.viatra.dse.designspace.api.IDesignSpace;
20import org.eclipse.viatra.dse.designspace.api.TrajectoryInfo;
21import org.eclipse.viatra.dse.objectives.Fitness;
22import org.eclipse.viatra.dse.objectives.IGlobalConstraint;
23import org.eclipse.viatra.dse.objectives.IObjective;
24import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
25import org.eclipse.viatra.dse.solutionstore.SolutionStore;
26import org.eclipse.viatra.dse.statecode.IStateCoder;
27import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
28import org.eclipse.viatra.transformation.evm.api.Activation;
29import org.eclipse.viatra.transformation.evm.api.RuleEngine;
30import org.eclipse.viatra.transformation.evm.api.RuleSpecification;
31import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
32
33/**
34 * This interface is only to overview the required methods for exploration strategies. It is not used explicitly.
35 *
36 * @author Andras Szabolcs Nagy
37 *
38 */
39public interface IDseStrategyContext {
40
41 void init();
42
43 Notifier getModel();
44 EditingDomain getEditingDomain();
45 ViatraQueryEngine getQueryEngine();
46 RuleEngine getRuleEngine();
47 IStrategy getStrategy();
48 ExplorerThread getExplorerThread();
49 List<IObjective> getObjectives();
50 IObjective[][] getLeveledObjectives();
51 List<IGlobalConstraint> getGlobalConstraints();
52
53 SolutionStore getSolutionStore();
54 void newSolution();
55// TODO void newSolution(TrajectoryFitness trajectoryFitness);
56
57
58 ObjectiveComparatorHelper getObjectiveComparatorHelper();
59
60 GlobalContext getGlobalContext();
61 Set<BatchTransformationRule<?, ?>> getRules();
62 BatchTransformationRule<?, ?> getRuleByRuleSpecification(RuleSpecification<?> ruleSpecification);
63 ExplorerThread tryStartNewThread(IStrategy strategy); /*IDseStrategyContext originalContext*/
64 ExplorerThread tryStartNewThreadWithoutModelClone(IStrategy strategy);
65 void startAllThreads(IStrategyFactory strategyFactory);
66 Object getSharedObject();
67 void setSharedObject(Object sharedObject);
68
69
70 DesignSpaceManager getDesignSpaceManager();
71 IStateCoder getStateCoder();
72 IDesignSpace getDesignSpace();
73 TrajectoryInfo getTrajectoryInfo();
74 List<Object> getTrajectory();
75 List<Object> getTrajectoryCopied();
76 int getDepth();
77 Object getCurrentStateId();
78
79 Object getTransitionByActivation(Activation<?> activation);
80 Activation<?> getActivationById(Object activationId);
81 BatchTransformationRule<?, ?> getRuleByActivation(Activation<?> activation);
82 BatchTransformationRule<?, ?> getRuleByActivationId(Object activationId);
83
84 Collection<Object> getCurrentActivationIds();
85 Collection<Object> getUntraversedActivationIds();
86// TODO Object getArbitraryActivationId();
87// TODO Object getArbitraryUntraversedActivationId();
88
89 void executeAcitvationId(Object activationId);
90 boolean tryExecuteAcitvationId(Object activationId);
91 boolean executeRandomActivationId();
92 void executeTrajectory(Object[] activationIds);
93 void executeTrajectory(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex);
94 int executeTrajectoryByTrying(Object[] activationIds);
95 int executeTrajectoryByTrying(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex);
96 int executeTrajectoryWithoutStateCoding(Object[] activationIds);
97 int executeTrajectoryWithoutStateCoding(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex);
98 int executeTrajectoryByTryingWithoutStateCoding(Object[] activationIds);
99 int executeTrajectoryByTryingWithoutStateCoding(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex);
100 void executeTrajectoryWithMinimalBacktrack(Object[] trajectory);
101 void executeTrajectoryWithMinimalBacktrack(Object[] trajectory, int toExcludedIndex);
102 void executeTrajectoryWithMinimalBacktrackWithoutStateCoding(Object[] trajectory);
103 void executeTrajectoryWithMinimalBacktrackWithoutStateCoding(Object[] trajectory, int toExcludedIndex);
104
105 boolean backtrack();
106 // TODO int backtrack(int times);
107 void backtrackUntilLastCommonActivation(Object[] trajectory);
108 void backtrackUntilRoot();
109
110 Fitness calculateFitness();
111 Fitness getLastFitness();
112 boolean checkGlobalConstraints();
113 boolean isCurrentStateAlreadyTraversed();
114 // this needs states stored:
115 boolean isCurrentStateInTrajectory();
116
117}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/SingletonSetConflictResolver.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/SingletonSetConflictResolver.java
new file mode 100644
index 00000000..8c0a715a
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/SingletonSetConflictResolver.java
@@ -0,0 +1,53 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import org.eclipse.viatra.transformation.evm.api.RuleEngine;
12import org.eclipse.viatra.transformation.evm.api.resolver.ChangeableConflictSet;
13import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver;
14
15/**
16 *
17 * @author Andras Szabolcs Nagy
18 *
19 */
20public class SingletonSetConflictResolver implements ConflictResolver {
21
22 protected ChangeableConflictSet conflictSet;
23 protected ConflictResolver conflictResolver;
24 protected ConflictResolver prevConflictResolver;
25 protected RuleEngine ruleEngine;
26
27 public SingletonSetConflictResolver(ConflictResolver conflictResolver) {
28 this.conflictResolver = conflictResolver;
29 conflictSet = conflictResolver.createConflictSet();
30 }
31
32 @Override
33 public ChangeableConflictSet createConflictSet() {
34 return conflictSet;
35 }
36
37 public void changeConflictResolver(ConflictResolver conflictResolver) {
38 ConflictResolver tmp = this.conflictResolver;
39 this.conflictResolver = conflictResolver;
40 prevConflictResolver = tmp;
41 conflictSet = conflictResolver.createConflictSet();
42 ruleEngine.setConflictResolver(this);
43 }
44
45 public void changeConflictResolverBack() {
46 changeConflictResolver(prevConflictResolver);
47 }
48
49 public void setRuleEngine(RuleEngine ruleEngine) {
50 this.ruleEngine = ruleEngine;
51 ruleEngine.setConflictResolver(this);
52 }
53}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ThreadContext.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ThreadContext.java
new file mode 100644
index 00000000..b62442ce
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ThreadContext.java
@@ -0,0 +1,542 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.base;
10
11import java.util.ArrayList;
12import java.util.Collection;
13import java.util.List;
14import java.util.Set;
15import java.util.concurrent.atomic.AtomicBoolean;
16
17import org.apache.log4j.Logger;
18import org.eclipse.emf.common.notify.Notifier;
19import org.eclipse.emf.edit.domain.EditingDomain;
20import org.eclipse.viatra.dse.api.DSEException;
21import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
22import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategyFactory;
23import org.eclipse.viatra.dse.designspace.api.IDesignSpace;
24import org.eclipse.viatra.dse.designspace.api.TrajectoryInfo;
25import org.eclipse.viatra.dse.objectives.Fitness;
26import org.eclipse.viatra.dse.objectives.IGlobalConstraint;
27import org.eclipse.viatra.dse.objectives.IObjective;
28import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
29import org.eclipse.viatra.dse.solutionstore.SolutionStore;
30import org.eclipse.viatra.dse.statecode.IStateCoder;
31import org.eclipse.viatra.dse.util.EMFHelper;
32import org.eclipse.viatra.query.runtime.api.IPatternMatch;
33import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
34import org.eclipse.viatra.query.runtime.emf.EMFScope;
35import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
36import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
37import org.eclipse.viatra.transformation.evm.api.Activation;
38import org.eclipse.viatra.transformation.evm.api.RuleEngine;
39import org.eclipse.viatra.transformation.evm.api.RuleSpecification;
40import org.eclipse.viatra.transformation.evm.api.event.EventFilter;
41import org.eclipse.viatra.transformation.evm.api.resolver.ChangeableConflictSet;
42import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver;
43import org.eclipse.viatra.transformation.evm.api.resolver.ConflictSet;
44import org.eclipse.viatra.transformation.evm.specific.RuleEngines;
45import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
46
47/**
48 * This class holds all the information that is related to a single processing thread of the DesignSpaceExploration
49 * process. For any attributes related to the Design Space Exploration process as a whole, see {@link GlobalContext}.
50 *
51 * @author Miklos Foldenyi
52 *
53 */
54public class ThreadContext implements IDseStrategyContext{
55
56 private final GlobalContext globalContext;
57 private final IStrategy strategy;
58 private ExplorerThread explorerThread;
59 private RuleEngine ruleEngine;
60 private ViatraQueryEngine queryEngine;
61 private EditingDomain domain;
62 private Notifier model;
63 private DesignSpaceManager designSpaceManager;
64 private List<IObjective> objectives;
65 private List<IGlobalConstraint> globalConstraints;
66 private Fitness lastFitness;
67 private ObjectiveComparatorHelper objectiveComparatorHelper;
68 private IStateCoder stateCoder;
69 private DseConflictResolver dseConflictResolver;
70 private DseConflictSet dseConflictSet;
71 private ActivationCodesConflictSet activationCodesConflictSet;
72
73 /**
74 * This value is true after the {@link ThreadContext} has been initialized in it's own thread.
75 */
76 private AtomicBoolean inited = new AtomicBoolean(false);
77
78 private boolean isFirstThread = false;
79 private IObjective[][] leveledObjectives;
80
81 private static class GetRuleExecutionsImpl implements DseIdPoolHelper.IGetRuleExecutions {
82
83 private List<BatchTransformationRule<?, ?>> executedRules;
84
85 public GetRuleExecutionsImpl(List<BatchTransformationRule<?, ?>> executedRulesView) {
86 this.executedRules = executedRulesView;
87 }
88
89 @Override
90 public int getRuleExecutions(BatchTransformationRule<?, ?> rule) {
91 int nextId = 0;
92 for (BatchTransformationRule<?, ?> r : executedRules) {
93 if (r.equals(rule)) {
94 nextId ++;
95 }
96 }
97 return nextId;
98 }
99
100 }
101
102 public DseConflictResolver getConflictResolver() {
103 return dseConflictResolver;
104 }
105
106 public ConflictSet getConflictSet() {
107 return dseConflictSet;
108 }
109
110 /**
111 * Creates a {@link ThreadContext} and sets it up to be initialized on the given {@link TransactionalEditingDomain}
112 *
113 * @param globalContext
114 * @param strategyBase
115 * @param domain
116 * @param trajectoryInfoToClone
117 * @param parentGuidance
118 */
119 public ThreadContext(final GlobalContext globalContext, IStrategy strategy, Notifier model) {
120 Preconditions.checkArgument(model != null, "Cannot initialize ThreadContext on a null model.");
121 this.globalContext = globalContext;
122 this.strategy = strategy;
123 this.model = model;
124 }
125
126 /**
127 * Initializes the {@link ThreadContext} by initializing the underlying {@link ViatraQueryEngine} and
128 * {@link RuleEngine}. {@link Guidance} initialization is also happening within this method.
129 *
130 * @throws DSEException
131 */
132 public void init() {
133
134 AtomicBoolean isFirst = globalContext.getFirstThreadContextIniting();
135 AtomicBoolean isFirstReady = globalContext.getFirstThreadContextInited();
136 if (!isFirstReady.get()) {
137 if (!isFirst.compareAndSet(false, true)) {
138 try {
139 do {
140 Thread.sleep(5);
141 } while (!isFirstReady.get());
142 } catch (InterruptedException e) {
143 }
144 } else {
145 isFirstThread = true;
146 }
147 }
148 // prohibit re-initialization
149 Preconditions.checkArgument(!inited.getAndSet(true), "This Thread context has been initialized already!");
150
151 try {
152 // initialize query engine
153 final EMFScope scope = new EMFScope(model);
154 queryEngine = ViatraQueryEngine.on(scope);
155
156
157 stateCoder = getGlobalContext().getStateCoderFactory().createStateCoder();
158 stateCoder.init(model);
159 stateCoder.createStateCode();
160
161 ConflictResolver activationOrderingCconflictResolver = globalContext.getConflictResolver();
162 dseConflictResolver = new DseConflictResolver(activationOrderingCconflictResolver, stateCoder);
163
164 ruleEngine = RuleEngines.createViatraQueryRuleEngine(queryEngine);
165 ruleEngine.setConflictResolver(dseConflictResolver);
166 for (BatchTransformationRule<?, ?> tr : globalContext.getTransformations()) {
167 ruleEngine.addRule(tr.getRuleSpecification(), (EventFilter<IPatternMatch>) tr.getFilter());
168 }
169 dseConflictSet = dseConflictResolver.getLastCreatedConflictSet();
170 activationCodesConflictSet = dseConflictSet.getActivationCodesConflictSet();
171 activationCodesConflictSet.updateActivationCodes();
172
173
174 } catch (ViatraQueryException e) {
175 throw new DSEException("Failed to create unmanaged ViatraQueryEngine on the model.", e);
176 }
177
178 if (isFirstThread) {
179
180 objectives = globalContext.getObjectives();
181 leveledObjectives = globalContext.getLeveledObjectives();
182 globalConstraints = globalContext.getGlobalConstraints();
183
184 } else {
185 objectives = new ArrayList<IObjective>();
186
187 IObjective[][] leveledObjectivesToCopy = globalContext.getLeveledObjectives();
188 leveledObjectives = new IObjective[leveledObjectivesToCopy.length][];
189 for (int i = 0; i < leveledObjectivesToCopy.length; i++) {
190 leveledObjectives[i] = new IObjective[leveledObjectivesToCopy[i].length];
191 for (int j = 0; j < leveledObjectivesToCopy[i].length; j++) {
192 leveledObjectives[i][j] = leveledObjectivesToCopy[i][j].createNew();
193 objectives.add(leveledObjectives[i][j]);
194 }
195 }
196
197 globalConstraints = new ArrayList<IGlobalConstraint>();
198 for (IGlobalConstraint globalConstraint : globalContext.getGlobalConstraints()) {
199 globalConstraints.add(globalConstraint.createNew());
200 }
201
202 }
203 // create the thread specific DesignSpaceManager
204 this.domain = EMFHelper.createEditingDomain(model);
205 designSpaceManager = new DesignSpaceManager(this);
206
207 boolean isThereHardObjective = false;
208 for (IObjective objective : objectives) {
209 objective.init(this);
210 if (objective.isHardObjective()) {
211 isThereHardObjective = true;
212 }
213 }
214 if (!isThereHardObjective) {
215 Logger.getLogger(IStrategy.class).warn(
216 "No hard objective is specified: all reachable state is a solution. Use a dummy hard objective to be explicit.");
217 }
218
219 for (IGlobalConstraint globalConstraint : globalConstraints) {
220 globalConstraint.init(this);
221 }
222
223 DseIdPoolHelper.INSTANCE.registerRules(new GetRuleExecutionsImpl(getDesignSpaceManager().getTrajectoryInfo().getRules()), getRules());
224
225 globalContext.initVisualizersForThread(this);
226
227 if (isFirstThread) {
228 isFirstReady.set(true);
229 }
230
231 }
232
233 public Fitness calculateFitness() {
234 Fitness result = new Fitness();
235
236 boolean satisifiesHardObjectives = true;
237
238 for (IObjective objective : objectives) {
239 Double fitness = objective.getFitness(this);
240 result.put(objective.getName(), fitness);
241 if (objective.isHardObjective() && !objective.satisifiesHardObjective(fitness)) {
242 satisifiesHardObjectives = false;
243 }
244 }
245
246 result.setSatisifiesHardObjectives(satisifiesHardObjectives);
247
248 lastFitness = result;
249
250 return result;
251 }
252
253 public boolean checkGlobalConstraints() {
254 for (IGlobalConstraint globalConstraint : globalContext.getGlobalConstraints()) {
255 if (!globalConstraint.checkGlobalConstraint(this)) {
256 return false;
257 }
258 }
259 return true;
260 }
261
262 public RuleEngine getRuleEngine() {
263 return ruleEngine;
264 }
265
266 public GlobalContext getGlobalContext() {
267 return globalContext;
268 }
269
270 public DesignSpaceManager getDesignSpaceManager() {
271 return designSpaceManager;
272 }
273
274 public EditingDomain getEditingDomain() {
275 return domain;
276 }
277
278 public Notifier getModel() {
279 return model;
280 }
281
282 public ViatraQueryEngine getQueryEngine() {
283 return queryEngine;
284 }
285
286 public IStrategy getStrategy() {
287 return strategy;
288 }
289
290 public ExplorerThread getExplorerThread() {
291 return explorerThread;
292 }
293
294 public void setExplorerThread(ExplorerThread explorerThread) {
295 this.explorerThread = explorerThread;
296 }
297
298 public Fitness getLastFitness() {
299 return lastFitness;
300 }
301
302 public ObjectiveComparatorHelper getObjectiveComparatorHelper() {
303 if (objectiveComparatorHelper == null) {
304 objectiveComparatorHelper = new ObjectiveComparatorHelper(leveledObjectives);
305 }
306 return objectiveComparatorHelper;
307 }
308
309 public IObjective[][] getLeveledObjectives() {
310 return leveledObjectives;
311 }
312
313 public List<IObjective> getObjectives() {
314 return objectives;
315 }
316
317 public List<IGlobalConstraint> getGlobalConstraints() {
318 return globalConstraints;
319 }
320
321 @Override
322 public SolutionStore getSolutionStore() {
323 return globalContext.getSolutionStore();
324 }
325
326 @Override
327 public void newSolution() {
328 globalContext.getSolutionStore().newSolution(this);
329 }
330
331 @Override
332 public Object getSharedObject() {
333 return globalContext.getSharedObject();
334 }
335
336 @Override
337 public void setSharedObject(Object sharedObject) {
338 globalContext.setSharedObject(sharedObject);
339 }
340
341 @Override
342 public Set<BatchTransformationRule<?, ?>> getRules() {
343 return globalContext.getTransformations();
344 }
345
346 @Override
347 public BatchTransformationRule<?, ?> getRuleByRuleSpecification(RuleSpecification<?> ruleSpecification) {
348 return globalContext.getSpecificationRuleMap().get(ruleSpecification);
349 }
350
351 @Override
352 public ExplorerThread tryStartNewThread(IStrategy strategy) {
353 return globalContext.tryStartNewThread(this, strategy);
354 }
355
356 @Override
357 public ExplorerThread tryStartNewThreadWithoutModelClone(IStrategy strategy) {
358 return globalContext.tryStartNewThreadWithoutModelClone(this, strategy);
359 }
360
361 @Override
362 public void startAllThreads(IStrategyFactory strategyFactory) {
363 globalContext.startAllThreads(this, strategyFactory);
364 }
365
366 @Override
367 public IStateCoder getStateCoder() {
368 return stateCoder;
369 }
370
371 @Override
372 public IDesignSpace getDesignSpace() {
373 return globalContext.getDesignSpace();
374 }
375
376 @Override
377 public TrajectoryInfo getTrajectoryInfo() {
378 return designSpaceManager.getTrajectoryInfo();
379 }
380
381 @Override
382 public List<Object> getTrajectory() {
383 return designSpaceManager.getTrajectoryInfo().getTrajectory();
384 }
385
386 @Override
387 public List<Object> getTrajectoryCopied() {
388 return new ArrayList<Object>(getTrajectory());
389 }
390
391 @Override
392 public int getDepth() {
393 return designSpaceManager.getTrajectoryInfo().getDepth();
394 }
395
396 @Override
397 public Object getCurrentStateId() {
398 return designSpaceManager.getTrajectoryInfo().getCurrentStateId();
399 }
400
401 @Override
402 public Object getTransitionByActivation(Activation<?> activation) {
403 return designSpaceManager.getTransitionByActivation(activation);
404 }
405
406 @Override
407 public Activation<?> getActivationById(Object activationId) {
408 return designSpaceManager.getActivationById(activationId);
409 }
410
411 @Override
412 public BatchTransformationRule<?, ?> getRuleByActivation(Activation<?> activation) {
413 return designSpaceManager.getRuleByActivation(activation);
414 }
415
416 @Override
417 public BatchTransformationRule<?, ?> getRuleByActivationId(Object activationId) {
418 return designSpaceManager.getRuleByActivationId(activationId);
419 }
420
421 @Override
422 public Collection<Object> getCurrentActivationIds() {
423 return designSpaceManager.getTransitionsFromCurrentState();
424 }
425
426 @Override
427 public Collection<Object> getUntraversedActivationIds() {
428 return designSpaceManager.getUntraversedTransitionsFromCurrentState();
429 }
430
431 @Override
432 public void executeAcitvationId(Object activationId) {
433 designSpaceManager.fireActivation(activationId);
434 }
435
436 @Override
437 public boolean tryExecuteAcitvationId(Object activationId) {
438 return designSpaceManager.tryFireActivation(activationId);
439 }
440
441 @Override
442 public boolean executeRandomActivationId() {
443 return designSpaceManager.executeRandomActivationId();
444 }
445
446 @Override
447 public void executeTrajectory(Object[] activationIds) {
448 designSpaceManager.executeTrajectory(activationIds);
449 }
450
451 @Override
452 public void executeTrajectory(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex) {
453 designSpaceManager.executeTrajectory(activationIds, fromIncludedIndex, toExcludedIndex);
454 }
455
456 @Override
457 public int executeTrajectoryByTrying(Object[] activationIds) {
458 return designSpaceManager.executeTrajectoryByTrying(activationIds);
459 }
460
461 @Override
462 public int executeTrajectoryByTrying(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex) {
463 return designSpaceManager.executeTrajectoryByTrying(activationIds, fromIncludedIndex, toExcludedIndex);
464 }
465
466 @Override
467 public int executeTrajectoryWithoutStateCoding(Object[] activationIds) {
468 return designSpaceManager.executeTrajectoryWithoutStateCoding(activationIds);
469 }
470
471 @Override
472 public int executeTrajectoryWithoutStateCoding(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex) {
473 return designSpaceManager.executeTrajectoryWithoutStateCoding(activationIds, fromIncludedIndex, toExcludedIndex);
474 }
475
476 @Override
477 public int executeTrajectoryByTryingWithoutStateCoding(Object[] activationIds) {
478 return designSpaceManager.executeTrajectoryByTryingWithoutStateCoding(activationIds);
479 }
480
481 @Override
482 public int executeTrajectoryByTryingWithoutStateCoding(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex) {
483 return designSpaceManager.executeTrajectoryByTryingWithoutStateCoding(activationIds, fromIncludedIndex, toExcludedIndex);
484 }
485
486 @Override
487 public void executeTrajectoryWithMinimalBacktrack(Object[] trajectory) {
488 designSpaceManager.executeTrajectoryWithMinimalBacktrack(trajectory);
489 }
490
491 @Override
492 public void executeTrajectoryWithMinimalBacktrack(Object[] trajectory, int toExcludedIndex) {
493 designSpaceManager.executeTrajectoryWithMinimalBacktrack(trajectory, toExcludedIndex);
494 }
495
496 @Override
497 public void executeTrajectoryWithMinimalBacktrackWithoutStateCoding(Object[] trajectory) {
498 designSpaceManager.executeTrajectoryWithMinimalBacktrackWithoutStateCoding(trajectory);
499 }
500
501 @Override
502 public void executeTrajectoryWithMinimalBacktrackWithoutStateCoding(Object[] trajectory, int toExcludedIndex) {
503 designSpaceManager.executeTrajectoryWithMinimalBacktrackWithoutStateCoding(trajectory, toExcludedIndex);
504 }
505
506 @Override
507 public boolean backtrack() {
508 return designSpaceManager.undoLastTransformation();
509 }
510
511 @Override
512 public void backtrackUntilLastCommonActivation(Object[] trajectory) {
513 designSpaceManager.backtrackUntilLastCommonActivation(trajectory);
514 }
515
516 @Override
517 public void backtrackUntilRoot() {
518 designSpaceManager.undoUntilRoot();
519 }
520
521 @Override
522 public boolean isCurrentStateAlreadyTraversed() {
523 return designSpaceManager.isNewModelStateAlreadyTraversed();
524 }
525
526 @Override
527 public boolean isCurrentStateInTrajectory() {
528 return designSpaceManager.isCurentStateInTrajectory();
529 }
530
531 public ActivationCodesConflictSet getActivationCodesConflictSet() {
532 return activationCodesConflictSet;
533 }
534
535 public void changeActivationOrdering(ChangeableConflictSet activationOrderingConflictSet) {
536 this.dseConflictSet.changeActivationOrderingConflictSet(activationOrderingConflictSet);
537 }
538
539 public void changeActivationOrderingBack() {
540 this.dseConflictSet.changeActivationOrderingConflictSetBack();
541 }
542}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/DesignSpace.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/DesignSpace.java
new file mode 100644
index 00000000..bc0f08d4
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/DesignSpace.java
@@ -0,0 +1,106 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.designspace.api;
10
11import java.util.ArrayList;
12import java.util.Collection;
13import java.util.Collections;
14import java.util.HashMap;
15import java.util.HashSet;
16import java.util.List;
17import java.util.Map;
18import java.util.Random;
19import java.util.Set;
20
21public class DesignSpace implements IDesignSpace {
22
23 Set<Object> statesView;
24
25 Set<Object> rootStates;
26 Set<Object> rootStatesView;
27
28 Map<Object, List<Object>> statesAndActivations;
29
30 Random random = new Random();
31
32 public DesignSpace() {
33 rootStates = new HashSet<>();
34 rootStatesView = Collections.unmodifiableSet(rootStates);
35
36 statesAndActivations = new HashMap<>();
37 statesView = statesAndActivations.keySet();
38 }
39
40 @Override
41 public synchronized Collection<Object> getStates() {
42 return statesView;
43 }
44
45 @Override
46 public synchronized Collection<Object> getRoots() {
47 return rootStatesView;
48 }
49
50 @Override
51 public synchronized void addState(Object sourceStateId, Object firedActivationId, Object newStateId) {
52
53 List<Object> activationIds = statesAndActivations.get(newStateId);
54
55 if (activationIds == null) {
56 activationIds = new ArrayList<Object>();
57 statesAndActivations.put(newStateId, activationIds);
58
59 if (sourceStateId == null) {
60 rootStates.add(newStateId);
61 return;
62 }
63 }
64
65 activationIds = statesAndActivations.get(sourceStateId);
66
67 if (activationIds == null) {
68 activationIds = new ArrayList<Object>();
69 activationIds.add(firedActivationId);
70 statesAndActivations.put(sourceStateId, activationIds);
71 } else {
72 activationIds.add(firedActivationId);
73 }
74 }
75
76 public synchronized boolean isTraversed(Object stateId) {
77 return statesAndActivations.containsKey(stateId);
78 }
79
80 @Override
81 public synchronized Collection<Object> getActivationIds(Object stateId) {
82 return statesAndActivations.get(stateId);
83 }
84
85 @Override
86 public synchronized Object getRandomActivationId(Object stateId) {
87 List<Object> activations = statesAndActivations.get(stateId);
88 int index = random.nextInt(activations.size());
89 return activations.get(index);
90 }
91
92 @Override
93 public synchronized long getNumberOfStates() {
94 return statesAndActivations.size();
95 }
96
97 @Override
98 public synchronized long getNumberOfTransitions() {
99 int numberOfTransitions = 0;
100 for (List<Object> activations : statesAndActivations.values()) {
101 numberOfTransitions += activations.size();
102 }
103 return numberOfTransitions;
104 }
105
106}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IBacktrackListener.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IBacktrackListener.java
new file mode 100644
index 00000000..5c688276
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IBacktrackListener.java
@@ -0,0 +1,7 @@
1package org.eclipse.viatra.dse.designspace.api;
2
3public interface IBacktrackListener {
4 void forwardWorked(long nanos);
5
6 void backtrackWorked(long nanos);
7}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IDesignSpace.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IDesignSpace.java
new file mode 100644
index 00000000..a1d64bbf
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/IDesignSpace.java
@@ -0,0 +1,27 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.designspace.api;
10
11import java.util.Collection;
12
13public interface IDesignSpace {
14
15 Collection<Object> getStates();
16 Collection<Object> getRoots();
17 void addState(Object sourceStateId, Object firedActivationId, Object newStateId);
18
19 boolean isTraversed(Object stateId);
20
21 Collection<Object> getActivationIds(Object stateId);
22 Object getRandomActivationId(Object stateId);
23
24 long getNumberOfStates();
25 long getNumberOfTransitions();
26
27}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/TrajectoryInfo.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/TrajectoryInfo.java
new file mode 100644
index 00000000..acd88416
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/designspace/api/TrajectoryInfo.java
@@ -0,0 +1,154 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.designspace.api;
10
11import java.util.ArrayList;
12import java.util.Collections;
13import java.util.List;
14import java.util.Map;
15import java.util.Objects;
16
17import org.eclipse.viatra.dse.api.DSEException;
18import org.eclipse.viatra.dse.api.SolutionTrajectory;
19import org.eclipse.viatra.dse.base.DesignSpaceManager;
20import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
21import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
22
23public class TrajectoryInfo {
24
25 private final List<Object> trajectory;
26 private final List<Object> trajectoryView;
27 private final List<BatchTransformationRule<?, ?>> rules;
28 private final List<BatchTransformationRule<?, ?>> rulesView;
29 private final List<Object> stateIds;
30 private final List<Object> stateIdsView;
31 private final List<Map<String, Double>> measuredCosts;
32
33 public TrajectoryInfo(Object initialStateId) {
34 Objects.requireNonNull(initialStateId);
35
36 stateIds = new ArrayList<>();
37 stateIds.add(initialStateId);
38
39 trajectory = new ArrayList<>();
40 rules = new ArrayList<>();
41 measuredCosts = new ArrayList<>();
42
43 trajectoryView = Collections.unmodifiableList(trajectory);
44 stateIdsView = Collections.unmodifiableList(stateIds);
45 rulesView = Collections.unmodifiableList(rules);
46 }
47
48 /**
49 * Copy constructor
50 *
51 * @since 0.17
52 */
53 public TrajectoryInfo(TrajectoryInfo other) {
54 this(other.stateIds, other.trajectory, other.rules, other.measuredCosts);
55 }
56
57 protected TrajectoryInfo(List<Object> stateIds, List<Object> trajectory, List<BatchTransformationRule<?, ?>> rules, List<Map<String, Double>> measuredCosts) {
58
59 this.stateIds = new ArrayList<>(stateIds);
60 this.trajectory = new ArrayList<>(trajectory);
61 this.rules = new ArrayList<>(rules);
62 trajectoryView = Collections.unmodifiableList(trajectory);
63 stateIdsView = Collections.unmodifiableList(stateIds);
64 rulesView = Collections.unmodifiableList(rules);
65 this.measuredCosts = new ArrayList<>(measuredCosts);
66 }
67
68 public void addStep(Object activationId, BatchTransformationRule<?, ?> rule, Object newStateId, Map<String, Double> measuredCosts) {
69 stateIds.add(newStateId);
70 trajectory.add(activationId);
71 rules.add(rule);
72 this.measuredCosts.add(measuredCosts);
73 }
74
75 public void backtrack() {
76 int size = trajectory.size();
77
78 if (size == 0) {
79 throw new DSEException("Cannot step back any further!");
80 }
81
82 trajectory.remove(size - 1);
83 rules.remove(size - 1);
84 stateIds.remove(size);
85 measuredCosts.remove(size - 1);
86 }
87
88 public Object getInitialStateId() {
89 return stateIds.get(0);
90 }
91
92 public Object getCurrentStateId() {
93 return stateIds.get(stateIds.size() - 1);
94 }
95
96 public Object getLastActivationId() {
97 return trajectory.get(trajectory.size() - 1);
98 }
99
100 public List<Object> getTrajectory() {
101 return trajectoryView;
102 }
103
104 public List<Object> getStateTrajectory() {
105 return stateIdsView;
106 }
107
108 public List<BatchTransformationRule<?, ?>> getRules() {
109 return rulesView;
110 }
111
112 public int getDepth() {
113 return trajectory.size();
114 }
115
116 public List<Map<String, Double>> getMeasuredCosts() {
117 return measuredCosts;
118 }
119
120 public SolutionTrajectory createSolutionTrajectory(final IStateCoderFactory stateCoderFactory, final IBacktrackListener listener) {
121
122 List<Object> activationIds = new ArrayList<>(trajectory);
123 List<BatchTransformationRule<?, ?>> copiedRules = new ArrayList<>(rules);
124
125 return new SolutionTrajectory(activationIds, copiedRules, stateCoderFactory, listener);
126 }
127
128 public boolean canStepBack() {
129 return !trajectory.isEmpty();
130 }
131
132 @Override
133 public String toString() {
134 StringBuilder sb = new StringBuilder("Trajectory:\n");
135 for (Object activationId : trajectory) {
136 sb.append(activationId);
137 sb.append("\n");
138 }
139 return sb.toString();
140 }
141
142 /**
143 * This method is only used by the {@link DesignSpaceManager}.
144 * @param stateCode
145 * @return false if the initial state code is the last one, otherwise true.
146 */
147 public boolean modifyLastStateCode(Object stateCode) {
148 if (stateIds.size() == 1) {
149 return false;
150 }
151 stateIds.set(stateIds.size() - 1, stateCode);
152 return true;
153 }
154}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/multithreading/DSEThreadPool.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/multithreading/DSEThreadPool.java
new file mode 100644
index 00000000..17e96a75
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/multithreading/DSEThreadPool.java
@@ -0,0 +1,58 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.multithreading;
10
11import java.util.concurrent.RejectedExecutionException;
12import java.util.concurrent.SynchronousQueue;
13import java.util.concurrent.ThreadPoolExecutor;
14import java.util.concurrent.TimeUnit;
15
16import org.apache.log4j.Logger;
17import org.eclipse.viatra.dse.api.DesignSpaceExplorer;
18import org.eclipse.viatra.dse.base.ExplorerThread;
19
20/**
21 *
22 * @author Andras Szabolcs Nagy
23 *
24 */
25public class DSEThreadPool extends ThreadPoolExecutor {
26
27 private static final long THREAD_KEEP_ALIVE_IN_SECONDS = 60;
28
29 public DSEThreadPool() {
30 // Based on the Executors.newCachedThreadPool()
31 super(0, getProcNumber(), THREAD_KEEP_ALIVE_IN_SECONDS, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
32 }
33
34 // helper for constructor
35 private static int getProcNumber() {
36 return Runtime.getRuntime().availableProcessors();
37 }
38
39 public boolean tryStartNewStrategy(ExplorerThread strategy) {
40
41 if (!canStartNewThread()) {
42 return false;
43 }
44
45 try {
46 submit(strategy);
47 } catch (RejectedExecutionException e) {
48 Logger.getLogger(DesignSpaceExplorer.class).info("Couldn't start new thread.", e);
49 return false;
50 }
51
52 return true;
53 }
54
55 public boolean canStartNewThread() {
56 return getMaximumPoolSize() > getActiveCount();
57 }
58}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ActivationFitnessProcessor.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ActivationFitnessProcessor.java
new file mode 100644
index 00000000..c06d2916
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ActivationFitnessProcessor.java
@@ -0,0 +1,15 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import org.eclipse.viatra.query.runtime.api.IPatternMatch;
12
13public interface ActivationFitnessProcessor {
14 public double process(IPatternMatch match);
15} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Comparators.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Comparators.java
new file mode 100644
index 00000000..b1bd9349
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Comparators.java
@@ -0,0 +1,31 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import java.util.Comparator;
12
13/**
14 * This helper class holds comparators for objective implementations.
15 *
16 * @author Andras Szabolcs Nagy
17 *
18 */
19public class Comparators {
20
21 private Comparators() { /*Utility class constructor*/ }
22
23 public static final Comparator<Double> HIGHER_IS_BETTER = (o1, o2) -> o1.compareTo(o2);
24
25 public static final Comparator<Double> LOWER_IS_BETTER = (o1, o2) -> o2.compareTo(o1);
26
27 private static final Double ZERO = Double.valueOf(0);
28
29 public static final Comparator<Double> DIFFERENCE_TO_ZERO_IS_BETTER = (o1, o2) -> ZERO.compareTo(Math.abs(o1)-Math.abs(o2));
30
31}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Fitness.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Fitness.java
new file mode 100644
index 00000000..8beef3bd
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/Fitness.java
@@ -0,0 +1,29 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import java.util.HashMap;
12
13public class Fitness extends HashMap<String, Double>{
14
15 private boolean satisifiesHardObjectives;
16
17 public boolean isSatisifiesHardObjectives() {
18 return satisifiesHardObjectives;
19 }
20
21 public void setSatisifiesHardObjectives(boolean satisifiesHardObjectives) {
22 this.satisifiesHardObjectives = satisifiesHardObjectives;
23 }
24
25 @Override
26 public String toString() {
27 return super.toString() + " hardObjectives=" + satisifiesHardObjectives;
28 }
29}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IGlobalConstraint.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IGlobalConstraint.java
new file mode 100644
index 00000000..2f7f0347
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IGlobalConstraint.java
@@ -0,0 +1,58 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import org.eclipse.viatra.dse.base.ThreadContext;
12
13/**
14 *
15 * Implementation of this interface represents a global constraint of the DSE problem, which can halt an exploration
16 * continuing from a state which dissatisfies the global constraint.
17 * <p>
18 * Certain global constraints can have inner state for the validation. In this case a new instance is necessary for
19 * every new thread, and the {@code createNew} method should not return the same instance more than once.
20 *
21 * @author Andras Szabolcs Nagy
22 *
23 */
24public interface IGlobalConstraint {
25
26 /**
27 * Returns the name of the global constraint.
28 *
29 * @return The name of the global constraint.
30 */
31 String getName();
32
33 /**
34 * Checks whether the current state satisfies the global constraint.
35 *
36 * @param context
37 * The {@link ThreadContext} which contains the necessary information.
38 * @return True if the state is valid and exploration can be continued from the actual state.
39 */
40 boolean checkGlobalConstraint(ThreadContext context);
41
42 /**
43 * Initializes the global constraint. It is called exactly once for every thread starts.
44 *
45 * @param context
46 * The {@link ThreadContext}.
47 */
48 void init(ThreadContext context);
49
50 /**
51 * Returns an instance of the {@link IGlobalConstraint}. If it returns the same instance, all the methods has to be
52 * thread save as they are called concurrently.
53 *
54 * @return An instance of the global constraint.
55 */
56 IGlobalConstraint createNew();
57
58}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IObjective.java
new file mode 100644
index 00000000..849dd4e8
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/IObjective.java
@@ -0,0 +1,110 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import java.util.Comparator;
12
13import org.eclipse.viatra.dse.base.ThreadContext;
14
15/**
16 *
17 * Implementation of this interface represents a single objective of the DSE problem, which can assess a solution
18 * (trajectory) in a single number. It has a name and a comparator which orders two solution based on the calculated
19 * value.
20 * <p>
21 * Objectives can be either hard or soft objectives. Hard objectives can be satisfied or unsatisfied. If all of the hard
22 * objectives are satisfied on a single solution, then it is considered to be a valid (or goal) solution.
23 * <p>
24 * Certain objectives can have inner state for calculating the fitness value. In this case a new instance is necessary
25 * for every new thread, and the {@code createNew} method should not return the same instance more than once.
26 *
27 * @author Andras Szabolcs Nagy
28 *
29 */
30public interface IObjective {
31
32 /**
33 * Returns the name of the objective.
34 *
35 * @return The name of the objective.
36 */
37 String getName();
38
39 /**
40 * Sets the {@link Comparator} which is used to compare fitness (doubles). It determines whether the objective is to
41 * minimize or maximize (or minimize or maximize a delta from a given number).
42 *
43 * @param comparator The comparator.
44 */
45 void setComparator(Comparator<Double> comparator);
46
47 /**
48 * Returns a {@link Comparator} which is used to compare fitness (doubles). It determines whether the objective is
49 * to minimize or maximize (or minimize or maximize a delta from a given number).
50 *
51 * @return The comparator.
52 */
53 Comparator<Double> getComparator();
54
55 /**
56 * Calculates the value of the objective on a given solution (trajectory).
57 *
58 * @param context
59 * The {@link ThreadContext}
60 * @return The objective value in double.
61 */
62 Double getFitness(ThreadContext context);
63
64 /**
65 * Initializes the objective. It is called exactly once for every thread starts.
66 *
67 * @param context
68 * The {@link ThreadContext}.
69 */
70 void init(ThreadContext context);
71
72 /**
73 * Returns an instance of the {@link IObjective}. If it returns the same instance, all the methods has to be thread
74 * save as they are called concurrently.
75 *
76 * @return An instance of the objective.
77 */
78 IObjective createNew();
79
80 /**
81 * Returns true if the objective is a hard objective. In such a case the method
82 * {@link IObjective#satisifiesHardObjective(Double)} is called.
83 *
84 * @return True if the objective is a hard objective.
85 * @see IObjective#satisifiesHardObjective(Double)
86 * @see IObjective
87 */
88 boolean isHardObjective();
89
90 /**
91 * Determines if the given fitness value satisfies the hard objective.
92 *
93 * @param fitness
94 * The fitness value of a solution.
95 * @return True if it satisfies the hard objective or it is a soft constraint.
96 * @see IObjective
97 */
98 boolean satisifiesHardObjective(Double fitness);
99
100 /**
101 * Set the level of the objective.
102 */
103 void setLevel(int level);
104
105 /**
106 * Gets the level of the objective.
107 */
108 int getLevel();
109
110}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/LeveledObjectivesHelper.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/LeveledObjectivesHelper.java
new file mode 100644
index 00000000..2d81629b
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/LeveledObjectivesHelper.java
@@ -0,0 +1,114 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import java.util.ArrayList;
12import java.util.Arrays;
13import java.util.Comparator;
14import java.util.List;
15
16public class LeveledObjectivesHelper {
17
18 private List<IObjective> objectives = new ArrayList<IObjective>();
19 private IObjective[][] leveledObjectives;
20
21 public LeveledObjectivesHelper(List<IObjective> objectives) {
22 this.objectives = objectives;
23 }
24
25 public IObjective[][] initLeveledObjectives() {
26 if (objectives.isEmpty()) {
27 leveledObjectives = new IObjective[0][0];
28 return leveledObjectives;
29 }
30
31 int level = objectives.get(0).getLevel();
32 boolean oneLevelOnly = true;
33 for (IObjective objective : objectives) {
34 if (objective.getLevel() != level) {
35 oneLevelOnly = false;
36 break;
37 }
38 }
39
40 if (oneLevelOnly) {
41 leveledObjectives = new IObjective[1][objectives.size()];
42 for (int i = 0; i < objectives.size(); i++) {
43 leveledObjectives[0][i] = objectives.get(i);
44 }
45 return leveledObjectives;
46 }
47
48 IObjective[] objectivesArray = getSortedByLevelObjectives(objectives);
49
50 int numberOfLevels = getNumberOfObjectiveLevels(objectivesArray);
51
52 leveledObjectives = new IObjective[numberOfLevels][];
53
54 fillLeveledObjectives(objectivesArray);
55
56 return leveledObjectives;
57 }
58
59 private void fillLeveledObjectives(IObjective[] objectivesArray) {
60 int actLevel = objectivesArray[0].getLevel();
61 int levelIndex = 0;
62 int lastIndex = 0;
63 int corrigationForLastLevel = 0;
64 boolean oneObjectiveAtLastLevel = false;
65 for (int i = 0; i < objectivesArray.length; i++) {
66 if (i == objectivesArray.length - 1) {
67 corrigationForLastLevel = 1;
68 if (objectivesArray[i - 1].getLevel() != objectivesArray[i].getLevel()) {
69 oneObjectiveAtLastLevel = true;
70 corrigationForLastLevel = 0;
71 }
72 }
73 if (objectivesArray[i].getLevel() != actLevel || corrigationForLastLevel == 1 || oneObjectiveAtLastLevel) {
74 leveledObjectives[levelIndex] = new IObjective[i - lastIndex + corrigationForLastLevel];
75 for (int j = lastIndex; j < i + corrigationForLastLevel; j++) {
76 leveledObjectives[levelIndex][j - lastIndex] = objectivesArray[j];
77 }
78 if (oneObjectiveAtLastLevel) {
79 leveledObjectives[levelIndex + 1] = new IObjective[1];
80 leveledObjectives[levelIndex + 1][0] = objectivesArray[i];
81 }
82 actLevel = objectivesArray[i].getLevel();
83 levelIndex++;
84 lastIndex = i;
85 }
86 }
87 }
88
89 private int getNumberOfObjectiveLevels(IObjective[] objectivesArray) {
90
91 int actLevel = objectivesArray[0].getLevel();
92 int numberOfLevels = 1;
93
94 for (int i = 1; i < objectivesArray.length; i++) {
95 if (objectivesArray[i].getLevel() != actLevel) {
96 numberOfLevels++;
97 actLevel = objectivesArray[i].getLevel();
98 }
99 }
100
101 return numberOfLevels;
102 }
103
104 private IObjective[] getSortedByLevelObjectives(List<IObjective> objectives) {
105 IObjective[] objectivesArray = objectives.toArray(new IObjective[objectives.size()]);
106 Arrays.sort(objectivesArray, Comparator.comparingInt(IObjective::getLevel));
107 return objectivesArray;
108 }
109
110 public IObjective[][] getLeveledObjectives() {
111 return leveledObjectives;
112 }
113
114}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ObjectiveComparatorHelper.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ObjectiveComparatorHelper.java
new file mode 100644
index 00000000..39139bb0
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/ObjectiveComparatorHelper.java
@@ -0,0 +1,217 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import java.util.ArrayList;
12import java.util.Arrays;
13import java.util.HashMap;
14import java.util.List;
15import java.util.Map;
16import java.util.Random;
17
18import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
19
20/**
21 * This class is responsible to compare and sort fitness values. {@link TrajectoryFitness} instances can be added to an
22 * instance of this class, that it can sort them.
23 *
24 * @author András Szabolcs Nagy
25 */
26public class ObjectiveComparatorHelper {
27
28 private IObjective[][] leveledObjectives;
29 private List<TrajectoryFitness> trajectoryFitnesses = new ArrayList<TrajectoryFitness>();
30 private Random random = new Random();
31 private boolean computeCrowdingDistance = false;
32
33 public ObjectiveComparatorHelper(IObjective[][] leveledObjectives) {
34 this.leveledObjectives = leveledObjectives;
35 }
36
37 public void setComputeCrowdingDistance(boolean computeCrowdingDistance) {
38 this.computeCrowdingDistance = computeCrowdingDistance;
39 }
40
41 /**
42 * Compares two fitnesses based on hierarchical dominance. Returns -1 if the second parameter {@code o2} is a better
43 * solution ({@code o2} dominates {@code o1}), 1 if the first parameter {@code o1} is better ({@code o1} dominates
44 * {@code o2}) and returns 0 if they are non-dominating each other.
45 */
46 public int compare(Fitness o1, Fitness o2) {
47
48 levelsLoop: for (int i = 0; i < leveledObjectives.length; i++) {
49
50 boolean o1HasBetterFitness = false;
51 boolean o2HasBetterFitness = false;
52
53 for (IObjective objective : leveledObjectives[i]) {
54 String objectiveName = objective.getName();
55 int sgn = objective.getComparator().compare(o1.get(objectiveName), o2.get(objectiveName));
56
57 if (sgn < 0) {
58 o2HasBetterFitness = true;
59 }
60 if (sgn > 0) {
61 o1HasBetterFitness = true;
62 }
63 if (o1HasBetterFitness && o2HasBetterFitness) {
64 continue levelsLoop;
65 }
66 }
67 if (o2HasBetterFitness && !o1HasBetterFitness) {
68 return -1;
69 } else if (!o2HasBetterFitness && o1HasBetterFitness) {
70 return 1;
71 }
72 }
73
74 return 0;
75
76 }
77
78 /**
79 * Adds a {@link TrajectoryFitness} to an inner list to compare later.
80 *
81 * @param trajectoryFitness
82 */
83 public void addTrajectoryFitness(TrajectoryFitness trajectoryFitness) {
84 trajectoryFitnesses.add(trajectoryFitness);
85 }
86
87 /**
88 * Clears the inner {@link TrajectoryFitness} list.
89 */
90 public void clearTrajectoryFitnesses() {
91 trajectoryFitnesses.clear();
92 }
93
94 /**
95 * Returns the inner {@link TrajectoryFitness} list.
96 */
97 public List<TrajectoryFitness> getTrajectoryFitnesses() {
98 return trajectoryFitnesses;
99 }
100
101 /**
102 * Returns a random {@link TrajectoryFitness} from the pareto front.
103 */
104 public TrajectoryFitness getRandomBest() {
105 List<TrajectoryFitness> paretoFront = getParetoFront();
106 int randomIndex = random.nextInt(paretoFront.size());
107 return paretoFront.get(randomIndex);
108 }
109
110 /**
111 * Returns the pareto front of the previously added {@link TrajectoryFitness}.
112 */
113 public List<TrajectoryFitness> getParetoFront() {
114 return getFronts().get(0);
115 }
116
117 /**
118 * Returns the previously added {@link TrajectoryFitness} instances in fronts.
119 */
120 public List<? extends List<TrajectoryFitness>> getFronts() {
121 Preconditions.checkArgument(!trajectoryFitnesses.isEmpty(), "No trajectory fitnesses were added.");
122 List<ArrayList<TrajectoryFitness>> fronts = new ArrayList<ArrayList<TrajectoryFitness>>();
123
124 Map<TrajectoryFitness, ArrayList<TrajectoryFitness>> dominatedInstances = new HashMap<TrajectoryFitness, ArrayList<TrajectoryFitness>>();
125 Map<TrajectoryFitness, Integer> dominatingInstances = new HashMap<TrajectoryFitness, Integer>();
126
127 // calculate dominations
128 for (TrajectoryFitness TrajectoryFitnessP : trajectoryFitnesses) {
129 dominatedInstances.put(TrajectoryFitnessP, new ArrayList<TrajectoryFitness>());
130 dominatingInstances.put(TrajectoryFitnessP, 0);
131
132 for (TrajectoryFitness TrajectoryFitnessQ : trajectoryFitnesses) {
133 int dominates = compare(TrajectoryFitnessP.fitness, TrajectoryFitnessQ.fitness);
134 if (dominates > 0) {
135 dominatedInstances.get(TrajectoryFitnessP).add(TrajectoryFitnessQ);
136 } else if (dominates < 0) {
137 dominatingInstances.put(TrajectoryFitnessP, dominatingInstances.get(TrajectoryFitnessP) + 1);
138 }
139 }
140
141 if (dominatingInstances.get(TrajectoryFitnessP) == 0) {
142 // p belongs to the first front
143 TrajectoryFitnessP.rank = 1;
144 if (fronts.isEmpty()) {
145 ArrayList<TrajectoryFitness> firstDominationFront = new ArrayList<TrajectoryFitness>();
146 firstDominationFront.add(TrajectoryFitnessP);
147 fronts.add(firstDominationFront);
148 } else {
149 List<TrajectoryFitness> firstDominationFront = fronts.get(0);
150 firstDominationFront.add(TrajectoryFitnessP);
151 }
152 }
153 }
154
155 // create fronts
156 int i = 1;
157 while (fronts.size() == i) {
158 ArrayList<TrajectoryFitness> nextDominationFront = new ArrayList<TrajectoryFitness>();
159 for (TrajectoryFitness TrajectoryFitnessP : fronts.get(i - 1)) {
160 for (TrajectoryFitness TrajectoryFitnessQ : dominatedInstances.get(TrajectoryFitnessP)) {
161 dominatingInstances.put(TrajectoryFitnessQ, dominatingInstances.get(TrajectoryFitnessQ) - 1);
162 if (dominatingInstances.get(TrajectoryFitnessQ) == 0) {
163 TrajectoryFitnessQ.rank = i + 1;
164 nextDominationFront.add(TrajectoryFitnessQ);
165 }
166 }
167 }
168 i++;
169 if (!nextDominationFront.isEmpty()) {
170 if (computeCrowdingDistance) {
171 crowdingDistanceAssignment(nextDominationFront, leveledObjectives);
172 }
173 fronts.add(nextDominationFront);
174 }
175 }
176
177 return fronts;
178 }
179
180 /**
181 * Executes the crowding distance assignment for the specified front.
182 *
183 * @param front
184 */
185 public static void crowdingDistanceAssignment(List<TrajectoryFitness> front, IObjective[][] leveledObjectives) {
186
187 for (TrajectoryFitness InstanceData : front) {
188 // initialize crowding distance
189 InstanceData.crowdingDistance = 0;
190 }
191
192 for (final IObjective[] objectives : leveledObjectives) {
193 for (final IObjective objective : objectives) {
194
195 final String m = objective.getName();
196 TrajectoryFitness[] sortedFront = front.toArray(new TrajectoryFitness[0]);
197 // sort using m-th objective value
198 Arrays.sort(sortedFront, (o1, o2) -> objective.getComparator().compare(o1.fitness.get(m), o2.fitness.get(m)));
199 // so that boundary points are always selected
200 sortedFront[0].crowdingDistance = Double.POSITIVE_INFINITY;
201 sortedFront[sortedFront.length - 1].crowdingDistance = Double.POSITIVE_INFINITY;
202 // If minimal and maximal fitness value for this objective are
203 // equal, then do not change crowding distance
204 if (sortedFront[0].fitness.get(m) != sortedFront[sortedFront.length - 1].fitness.get(m)) {
205 for (int i = 1; i < sortedFront.length - 1; i++) {
206 double newCrowdingDistance = sortedFront[i].crowdingDistance;
207 newCrowdingDistance += (sortedFront[i + 1].fitness.get(m) - sortedFront[i - 1].fitness.get(m))
208 / (sortedFront[sortedFront.length - 1].fitness.get(m) - sortedFront[0].fitness.get(m));
209
210 sortedFront[i].crowdingDistance = newCrowdingDistance;
211 }
212 }
213 }
214 }
215 }
216
217}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/TrajectoryFitness.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/TrajectoryFitness.java
new file mode 100644
index 00000000..f783afac
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/TrajectoryFitness.java
@@ -0,0 +1,84 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives;
10
11import java.util.Arrays;
12import java.util.List;
13
14import org.eclipse.viatra.dse.designspace.api.TrajectoryInfo;
15
16/**
17 * This class represents a trajectory and its fitness.
18 * @author Andras Szabolcs Nagy
19 *
20 */
21public class TrajectoryFitness {
22
23 public Object[] trajectory;
24 public Fitness fitness;
25
26 public int rank;
27 public double crowdingDistance;
28
29 private int hash;
30
31 public int survive;
32
33 /**
34 * Creates a {@link TrajectoryFitness} with the full trajectory.
35 * @param trajectory The trajectory.
36 * @param fitness The fitness.
37 */
38 public TrajectoryFitness(Object[] trajectory, Fitness fitness) {
39 this.fitness = fitness;
40 this.trajectory = trajectory;
41 }
42
43 /**
44 * Creates a {@link TrajectoryFitness} with the full trajectory.
45 * @param trajectoryInfo The trajectory.
46 * @param fitness The fitness.
47 */
48 public TrajectoryFitness(TrajectoryInfo trajectoryInfo, Fitness fitness) {
49 this.fitness = fitness;
50 List<Object> fullTraj = trajectoryInfo.getTrajectory();
51 trajectory = fullTraj.toArray(new Object[fullTraj.size()]);
52 }
53
54 /**
55 * Creates a {@link TrajectoryFitness} with the given activation id}
56 * @param transition The transition.
57 * @param fitness The fitness.
58 */
59 public TrajectoryFitness(Object transition, Fitness fitness) {
60 this.fitness = fitness;
61 trajectory = new Object[] {transition};
62 }
63
64 @Override
65 public boolean equals(Object obj) {
66 if (obj instanceof TrajectoryFitness) {
67 return Arrays.equals(trajectory, ((TrajectoryFitness) obj).trajectory);
68 }
69 return false;
70 }
71
72 @Override
73 public int hashCode() {
74 if (hash == 0 && trajectory.length > 0) {
75 hash = Arrays.hashCode(trajectory);
76 }
77 return hash;
78 }
79
80 @Override
81 public String toString() {
82 return Arrays.toString(trajectory) + fitness.toString();
83 }
84}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/AlwaysSatisfiedDummyHardObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/AlwaysSatisfiedDummyHardObjective.java
new file mode 100644
index 00000000..9898a3b5
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/AlwaysSatisfiedDummyHardObjective.java
@@ -0,0 +1,52 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import org.eclipse.viatra.dse.base.ThreadContext;
12import org.eclipse.viatra.dse.objectives.IObjective;
13
14/**
15 * This hard objective is fulfilled in any circumstances. Use it if all states should be regarded as a valid solution.
16 *
17 * @author Andras Szabolcs Nagy
18 *
19 */
20public class AlwaysSatisfiedDummyHardObjective extends BaseObjective {
21
22 private static final String DEFAULT_NAME = "AlwaysSatisfiedDummyHardObjective";
23
24 public AlwaysSatisfiedDummyHardObjective() {
25 super(DEFAULT_NAME);
26 }
27
28 public AlwaysSatisfiedDummyHardObjective(String name) {
29 super(name);
30 }
31
32 @Override
33 public Double getFitness(ThreadContext context) {
34 return 0d;
35 }
36
37 @Override
38 public boolean isHardObjective() {
39 return true;
40 }
41
42 @Override
43 public boolean satisifiesHardObjective(Double fitness) {
44 return true;
45 }
46
47 @Override
48 public IObjective createNew() {
49 return this;
50 }
51
52}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/BaseObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/BaseObjective.java
new file mode 100644
index 00000000..0a1de875
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/BaseObjective.java
@@ -0,0 +1,150 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import java.util.Comparator;
12import java.util.Objects;
13
14import org.eclipse.viatra.dse.base.ThreadContext;
15import org.eclipse.viatra.dse.objectives.Comparators;
16import org.eclipse.viatra.dse.objectives.IObjective;
17
18/**
19 * This abstract class implements the basic functionality of an objective ({@link IObjective} namely its name,
20 * comparator, level and fitness hard constraint.
21 *
22 * @author Andras Szabolcs Nagy
23 *
24 */
25public abstract class BaseObjective implements IObjective {
26
27 protected final String name;
28 protected Comparator<Double> comparator = Comparators.HIGHER_IS_BETTER;
29 protected int level = 0;
30
31 protected double fitnessConstraint;
32 protected boolean isThereFitnessConstraint = false;
33 protected Comparator<Double> fitnessConstraintComparator;
34
35 public BaseObjective(String name) {
36 Objects.requireNonNull(name, "Name of the objective cannot be null.");
37 this.name = name;
38 }
39
40 @Override
41 public String getName() {
42 return name;
43 }
44
45 @Override
46 public void setComparator(Comparator<Double> comparator) {
47 this.comparator = comparator;
48 }
49
50 @Override
51 public Comparator<Double> getComparator() {
52 return comparator;
53 }
54
55 @Override
56 public void setLevel(int level) {
57 this.level = level;
58 }
59
60 @Override
61 public int getLevel() {
62 return level;
63 }
64
65 public BaseObjective withLevel(int level) {
66 setLevel(level);
67 return this;
68 }
69
70 public BaseObjective withComparator(Comparator<Double> comparator) {
71 setComparator(comparator);
72 return this;
73 }
74
75 /**
76 * Adds a hard constraint on the fitness value. For example, the fitness value must be better than 10 to accept the
77 * current state as a solution.
78 *
79 * @param fitnessConstraint
80 * Solutions should be better than this value.
81 * @param fitnessConstraintComparator
82 * {@link Comparator} to determine if the current state is better than the given value.
83 * @return The actual instance to enable builder pattern like usage.
84 */
85 public BaseObjective withHardConstraintOnFitness(double fitnessConstraint,
86 Comparator<Double> fitnessConstraintComparator) {
87 this.fitnessConstraint = fitnessConstraint;
88 this.fitnessConstraintComparator = fitnessConstraintComparator;
89 this.isThereFitnessConstraint = true;
90 return this;
91 }
92
93 /**
94 * Adds a hard constraint on the fitness value. For example, the fitness value must be better than 10 to accept the
95 * current state as a solution. The provided comparator will be used.
96 *
97 * @param fitnessConstraint
98 * Solutions should be better than this value.
99 * @return The actual instance to enable builder pattern like usage.
100 */
101 public BaseObjective withHardConstraintOnFitness(double fitnessConstraint) {
102 return withHardConstraintOnFitness(fitnessConstraint, null);
103 }
104
105 @Override
106 public void init(ThreadContext context) {
107 if (fitnessConstraintComparator == null) {
108 fitnessConstraintComparator = comparator;
109 }
110 }
111
112 @Override
113 public boolean isHardObjective() {
114 return isThereFitnessConstraint;
115 }
116
117 @Override
118 public boolean satisifiesHardObjective(Double fitness) {
119 if (isThereFitnessConstraint) {
120 int compare = fitnessConstraintComparator.compare(fitness, fitnessConstraint);
121 if (compare < 0) {
122 return false;
123 }
124 }
125 return true;
126 }
127
128 @Override
129 public int hashCode() {
130 return name.hashCode();
131 }
132
133 @Override
134 public boolean equals(Object obj) {
135 if (this == obj) {
136 return true;
137 }
138 if (obj instanceof BaseObjective) {
139 BaseObjective baseObjective = (BaseObjective) obj;
140 return name.equals(baseObjective.getName());
141 }
142 return false;
143 }
144
145 @Override
146 public String toString() {
147 return name;
148 }
149
150}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/CompositeObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/CompositeObjective.java
new file mode 100644
index 00000000..cc48d22e
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/CompositeObjective.java
@@ -0,0 +1,137 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import java.util.ArrayList;
12import java.util.List;
13import java.util.Objects;
14
15import org.eclipse.viatra.dse.base.ThreadContext;
16import org.eclipse.viatra.dse.objectives.IObjective;
17import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
18
19/**
20 * This objective collects a list of other objectives. It returns the weighted sum of the objectives.
21 *
22 * @author Andras Szabolcs Nagy
23 *
24 */
25public class CompositeObjective extends BaseObjective {
26
27 public static final String DEFAULT_NAME = "CompositeObjective";
28 protected List<IObjective> objectives;
29 protected List<Double> weights;
30 protected boolean hardObjective;
31
32 public CompositeObjective(String name, List<IObjective> objectives, List<Double> weights) {
33 super(name);
34 Objects.requireNonNull(objectives, "The list of objectives cannot be null.");
35 Objects.requireNonNull(weights, "The list of weights cannot be null.");
36 Preconditions.checkState(objectives.size() == weights.size(), "The size of the objectives and weights must match.");
37 this.objectives = objectives;
38 this.weights = weights;
39 }
40
41 public CompositeObjective(List<IObjective> objectives, List<Double> weights) {
42 this(DEFAULT_NAME, objectives, weights);
43 }
44
45 public CompositeObjective(String name) {
46 this(name, new ArrayList<IObjective>(), new ArrayList<Double>());
47 }
48
49 public CompositeObjective() {
50 this(DEFAULT_NAME, new ArrayList<IObjective>(), new ArrayList<Double>());
51 }
52
53 /**
54 * Adds a new objective.
55 *
56 * @param objective
57 * @return The actual instance to enable builder pattern like usage.
58 */
59 public CompositeObjective withObjective(IObjective objective) {
60 objectives.add(objective);
61 weights.add(1d);
62 return this;
63 }
64
65 /**
66 * Adds a new objective.
67 *
68 * @param objective
69 * @return The actual instance to enable builder pattern like usage.
70 */
71 public CompositeObjective withObjective(IObjective objective, double weight) {
72 objectives.add(objective);
73 weights.add(weight);
74 return this;
75 }
76
77 @Override
78 public Double getFitness(ThreadContext context) {
79
80 double result = 0;
81
82 for (int i = 0; i < objectives.size(); i++) {
83 IObjective objective = objectives.get(i);
84 Double weight = weights.get(i);
85 result += objective.getFitness(context) * weight;
86 }
87 return result;
88 }
89
90 @Override
91 public void init(ThreadContext context) {
92 super.init(context);
93 hardObjective = false;
94 for (IObjective objective : objectives) {
95 objective.init(context);
96 if (objective.isHardObjective()) {
97 hardObjective = true;
98 }
99 }
100 }
101
102 @Override
103 public IObjective createNew() {
104
105 List<IObjective> newObjectives = new ArrayList<IObjective>();
106
107 for (IObjective objective : objectives) {
108 newObjectives.add(objective.createNew());
109 }
110
111 CompositeObjective objective = new CompositeObjective(name, newObjectives, weights);
112 if (isThereFitnessConstraint) {
113 objective.withHardConstraintOnFitness(fitnessConstraint, fitnessConstraintComparator);
114 }
115
116 return objective.withComparator(comparator).withLevel(level);
117 }
118
119 @Override
120 public boolean isHardObjective() {
121 return hardObjective;
122 }
123
124 @Override
125 public boolean satisifiesHardObjective(Double fitness) {
126
127 boolean hardObjectiveSatisfied = true;
128
129 for (IObjective objective : objectives) {
130 hardObjectiveSatisfied = objective.satisifiesHardObjective(fitness) ? hardObjectiveSatisfied : false;
131 }
132
133 hardObjectiveSatisfied = super.satisifiesHardObjective(fitness) ? hardObjectiveSatisfied : false;
134
135 return hardObjectiveSatisfied;
136 }
137}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ConstraintsObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ConstraintsObjective.java
new file mode 100644
index 00000000..77d416f5
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ConstraintsObjective.java
@@ -0,0 +1,316 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import java.util.ArrayList;
12import java.util.List;
13import java.util.Objects;
14
15import org.eclipse.viatra.dse.api.DSEException;
16import org.eclipse.viatra.dse.base.ThreadContext;
17import org.eclipse.viatra.dse.objectives.IObjective;
18import org.eclipse.viatra.query.runtime.api.IPatternMatch;
19import org.eclipse.viatra.query.runtime.api.IQuerySpecification;
20import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
21import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher;
22import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
23
24/**
25 * This objective serves as soft and as hard objective at the same time by defining two lists of VIATRA Query
26 * specifications.
27 *
28 * As a soft objective, it collects a list of VIATRA Query specifications, which have predefined weights. Then the
29 * fitness value of an arbitrary solution is calculated in the following way:
30 * <p>
31 * <code>fitness = sum( pattern[i].countMatches() * weight[i] )</code>
32 * <p>
33 * As a hard objective it collects a separate list of VIATRA Query specifications. If every one of them has a match the
34 * hard constraint is considered to be fulfilled.
35 *
36 * @author Andras Szabolcs Nagy
37 * @see IObjective
38 *
39 */
40public class ConstraintsObjective extends BaseObjective {
41
42 public static final String DEFAULT_NAME = "ConstraintsObjective";
43
44 public static class QueryConstraint {
45 public final String name;
46 public final IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> query;
47 public final Double weight;
48 public final ModelQueryType type;
49
50 public QueryConstraint(String name,
51 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> query, Double weight,
52 ModelQueryType type) {
53 this.name = name;
54 this.query = query;
55 this.weight = weight;
56 this.type = type;
57 }
58
59 public QueryConstraint(String name,
60 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> query, Double weight) {
61 this(name, query, weight, ModelQueryType.MUST_HAVE_MATCH);
62 }
63
64 public QueryConstraint(String name,
65 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> query, ModelQueryType type) {
66 this(name, query, 0d, type);
67 }
68 }
69
70 protected List<QueryConstraint> softConstraints;
71 protected List<QueryConstraint> hardConstraints;
72
73 protected List<ViatraQueryMatcher<? extends IPatternMatch>> softMatchers;
74 protected List<ViatraQueryMatcher<? extends IPatternMatch>> hardMatchers;
75 protected List<Integer> softMatches;
76 protected List<Integer> hardMatches;
77
78 public ConstraintsObjective(String name, List<QueryConstraint> softConstraints,
79 List<QueryConstraint> hardConstraints) {
80 super(name);
81 Objects.requireNonNull(softConstraints, "The list of soft constraints cannot be null.");
82 Objects.requireNonNull(hardConstraints, "The list of hard constraints cannot be null.");
83
84 this.softConstraints = softConstraints;
85 this.hardConstraints = hardConstraints;
86 }
87
88 public ConstraintsObjective(String name, List<QueryConstraint> hardConstraints) {
89 this(name, new ArrayList<QueryConstraint>(), hardConstraints);
90 }
91
92 public ConstraintsObjective(List<QueryConstraint> hardConstraints) {
93 this(DEFAULT_NAME, new ArrayList<QueryConstraint>(), hardConstraints);
94 }
95
96 public ConstraintsObjective(String name) {
97 this(name, new ArrayList<QueryConstraint>(), new ArrayList<QueryConstraint>());
98 }
99
100 public ConstraintsObjective() {
101 this(DEFAULT_NAME, new ArrayList<QueryConstraint>(), new ArrayList<QueryConstraint>());
102 }
103
104 /**
105 * Adds a new soft constraint.
106 *
107 * @param name
108 * A name for the soft constraint.
109 * @param softConstraint
110 * A VIATRA Query pattern specification.
111 * @param weight
112 * The weight of the pattern.
113 * @return The actual instance to enable builder pattern like usage.
114 */
115 public ConstraintsObjective withSoftConstraint(String name,
116 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> softConstraint, double weight) {
117 softConstraints.add(new QueryConstraint(name, softConstraint, weight));
118 return this;
119 }
120
121 /**
122 * Adds a new soft constraint with the name of the query specification's fully qualified name.
123 *
124 * @param softConstraint
125 * A VIATRA Query pattern specification.
126 * @param weight
127 * The weight of the pattern.
128 * @return The actual instance to enable builder pattern like usage.
129 */
130 public ConstraintsObjective withSoftConstraint(
131 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> softConstraint, double weight) {
132 return withSoftConstraint(softConstraint.getFullyQualifiedName(), softConstraint, weight);
133 }
134
135 /**
136 * Adds a new hard constraint.
137 *
138 * @param name
139 * A name for the hard constraint.
140 * @param softConstraint
141 * A VIATRA Query pattern specification.
142 * @param type
143 * {@link ModelQueryType}, which determines whether the constraint should have at least one match or none
144 * at all.
145 * @return The actual instance to enable builder pattern like usage.
146 */
147 public ConstraintsObjective withHardConstraint(String name,
148 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hardConstraint,
149 ModelQueryType type) {
150 hardConstraints.add(new QueryConstraint(name, hardConstraint, type));
151 return this;
152 }
153
154 /**
155 * Adds a new hard constraint with the default {@link ModelQueryType#MUST_HAVE_MATCH}.
156 *
157 * @param name
158 * A name for the hard constraint.
159 * @param softConstraint
160 * A VIATRA Query pattern specification.
161 * @return The actual instance to enable builder pattern like usage.
162 */
163 public ConstraintsObjective withHardConstraint(String name,
164 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hardConstraint) {
165 hardConstraints.add(new QueryConstraint(name, hardConstraint, ModelQueryType.MUST_HAVE_MATCH));
166 return this;
167 }
168
169 /**
170 * Adds a new hard constraint with the name of the query specification's fully qualified name and the default
171 * {@link ModelQueryType#MUST_HAVE_MATCH}.
172 *
173 * @param softConstraint
174 * A VIATRA Query pattern specification.
175 * @return The actual instance to enable builder pattern like usage.
176 */
177 public ConstraintsObjective withHardConstraint(
178 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hardConstraint) {
179 return withHardConstraint(hardConstraint.getFullyQualifiedName(), hardConstraint,
180 ModelQueryType.MUST_HAVE_MATCH);
181 }
182
183 /**
184 * Adds a new hard constraint with the name of the query specification's fully qualified name.
185 *
186 * @param softConstraint
187 * A VIATRA Query pattern specification.
188 * @param type
189 * {@link ModelQueryType}, which determines whether the constraint should have at least one match or none
190 * at all.
191 * @return The actual instance to enable builder pattern like usage.
192 */
193 public ConstraintsObjective withHardConstraint(
194 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> hardConstraint,
195 ModelQueryType type) {
196 return withHardConstraint(hardConstraint.getFullyQualifiedName(), hardConstraint, type);
197 }
198
199 @Override
200 public Double getFitness(ThreadContext context) {
201
202 if (softConstraints.isEmpty()) {
203 return 0d;
204 }
205
206 double result = 0;
207
208 for (int i = 0; i < softConstraints.size(); i++) {
209 int countMatches = softMatchers.get(i).countMatches();
210 result += countMatches * softConstraints.get(i).weight;
211 softMatches.set(i, Integer.valueOf(countMatches));
212 }
213
214 return result;
215 }
216
217 @Override
218 public void init(ThreadContext context) {
219
220 super.init(context);
221
222 softMatches = new ArrayList<Integer>(softConstraints.size());
223 softMatchers = new ArrayList<ViatraQueryMatcher<? extends IPatternMatch>>(softConstraints.size());
224 hardMatches = new ArrayList<Integer>(hardConstraints.size());
225 hardMatchers = new ArrayList<ViatraQueryMatcher<? extends IPatternMatch>>(hardConstraints.size());
226 for (int i = 0; i < softConstraints.size(); i++) {
227 softMatches.add(0);
228 }
229 for (int i = 0; i < hardConstraints.size(); i++) {
230 hardMatches.add(0);
231 }
232
233 try {
234 ViatraQueryEngine queryEngine = context.getQueryEngine();
235
236 for (QueryConstraint qc : softConstraints) {
237 softMatchers.add(qc.query.getMatcher(queryEngine));
238 }
239
240 for (QueryConstraint qc : hardConstraints) {
241 hardMatchers.add(qc.query.getMatcher(queryEngine));
242 }
243
244 } catch (ViatraQueryException e) {
245 throw new DSEException("Couldn't initialize the VIATRA Query matcher, see inner exception", e);
246 }
247 }
248
249 @Override
250 public IObjective createNew() {
251 new ArrayList<Double>(softConstraints.size());
252 ConstraintsObjective result = new ConstraintsObjective(name, softConstraints, hardConstraints);
253 if (isThereFitnessConstraint) {
254 result.withHardConstraintOnFitness(fitnessConstraint, fitnessConstraintComparator);
255 }
256 return result.withComparator(comparator).withLevel(level);
257 }
258
259 @Override
260 public boolean isHardObjective() {
261 return !hardConstraints.isEmpty() || super.isHardObjective();
262 }
263
264 @Override
265 public boolean satisifiesHardObjective(Double fitness) {
266
267 boolean result = true;
268
269 for (int i = 0; i < hardConstraints.size(); i++) {
270 ModelQueryType type = hardConstraints.get(i).type;
271 int countMatches = hardMatchers.get(i).countMatches();
272 hardMatches.set(i, Integer.valueOf(countMatches));
273 if ((type.equals(ModelQueryType.MUST_HAVE_MATCH) && countMatches <= 0)
274 || (type.equals(ModelQueryType.NO_MATCH) && countMatches > 0)) {
275 result = false;
276 }
277 }
278
279 result = super.satisifiesHardObjective(fitness) ? result : false;
280
281 return result;
282 }
283
284 public List<QueryConstraint> getSoftConstraints() {
285 return softConstraints;
286 }
287
288 public List<QueryConstraint> getHardConstraints() {
289 return hardConstraints;
290 }
291
292 public String getSoftName(int index) {
293 return softConstraints.get(index).name;
294 }
295
296 public String getHardName(int index) {
297 return hardConstraints.get(index).name;
298 }
299
300 public List<Integer> getSoftMatches() {
301 return softMatches;
302 }
303
304 public List<Integer> getHardMatches() {
305 return hardMatches;
306 }
307
308 public List<String> getSoftNames() {
309 List<String> softNames = new ArrayList<>(softConstraints.size());
310 for (QueryConstraint qc : softConstraints) {
311 softNames.add(qc.name);
312 }
313 return softNames;
314 }
315
316}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/DepthHardObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/DepthHardObjective.java
new file mode 100644
index 00000000..b21da397
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/DepthHardObjective.java
@@ -0,0 +1,89 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import org.eclipse.viatra.dse.base.ThreadContext;
12import org.eclipse.viatra.dse.objectives.IObjective;
13
14/**
15 * This hard objective is fulfilled if the trajectory is in the specified interval (inclusive).
16 *
17 * @author Andras Szabolcs Nagy
18 *
19 */
20public class DepthHardObjective extends BaseObjective {
21
22 private static final String DEFAULT_NAME = "DepthHardObjective";
23 protected int minDepth;
24 protected int maxDepth;
25 private ThreadContext context;
26
27 public DepthHardObjective() {
28 this(DEFAULT_NAME, 0, Integer.MAX_VALUE);
29 }
30
31 public DepthHardObjective(String name) {
32 this(name, 0, Integer.MAX_VALUE);
33 }
34
35 public DepthHardObjective(int minDepth) {
36 this(DEFAULT_NAME, minDepth, Integer.MAX_VALUE);
37 }
38
39 public DepthHardObjective(String name, int minDepth) {
40 this(name, minDepth, Integer.MAX_VALUE);
41 }
42
43 public DepthHardObjective(int minDepth, int maxDepth) {
44 this(DEFAULT_NAME, minDepth, maxDepth);
45 }
46
47 public DepthHardObjective(String name, int minDepth, int maxDepth) {
48 super(name);
49 this.minDepth = minDepth;
50 this.maxDepth = maxDepth;
51 }
52
53 public DepthHardObjective withMinDepth(int minDepth) {
54 this.minDepth = minDepth;
55 return this;
56 }
57
58 public DepthHardObjective withMaxDepth(int maxDepth) {
59 this.maxDepth = maxDepth;
60 return this;
61 }
62
63 @Override
64 public void init(ThreadContext context) {
65 super.init(context);
66 this.context = context;
67 }
68
69 @Override
70 public Double getFitness(ThreadContext context) {
71 return 0d;
72 }
73
74 @Override
75 public boolean isHardObjective() {
76 return true;
77 }
78
79 @Override
80 public boolean satisifiesHardObjective(Double fitness) {
81 return minDepth <= context.getDepth() && context.getDepth() <= maxDepth;
82 }
83
84 @Override
85 public IObjective createNew() {
86 return new DepthHardObjective(name, minDepth, maxDepth);
87 }
88
89}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueriesGlobalConstraint.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueriesGlobalConstraint.java
new file mode 100644
index 00000000..7616b4a2
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueriesGlobalConstraint.java
@@ -0,0 +1,116 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import java.util.ArrayList;
12import java.util.List;
13import java.util.Objects;
14
15import org.eclipse.viatra.dse.api.DSEException;
16import org.eclipse.viatra.dse.base.ThreadContext;
17import org.eclipse.viatra.dse.objectives.IGlobalConstraint;
18import org.eclipse.viatra.query.runtime.api.IPatternMatch;
19import org.eclipse.viatra.query.runtime.api.IQuerySpecification;
20import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
21import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher;
22import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
23
24/**
25 * This global constraint collects a list of VIATRA Query pattern and checks if any of them has a match on along a trajectory.
26 * If any of the patterns has a match then it is unsatisfied and the exploration should backtrack.
27 *
28 * @author Andras Szabolcs Nagy
29 *
30 */
31public class ModelQueriesGlobalConstraint implements IGlobalConstraint {
32
33 public static final String GLOBAL_CONSTRAINT = "GlobalConstraint";
34 protected String name;
35 protected List<IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> constraints;
36 protected List<ViatraQueryMatcher<? extends IPatternMatch>> matchers = new ArrayList<ViatraQueryMatcher<? extends IPatternMatch>>();
37 protected ModelQueryType type = ModelQueryType.NO_MATCH;
38
39 public ModelQueriesGlobalConstraint(String name,
40 List<IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> constraints) {
41 Objects.requireNonNull(name, "Name of the global constraint cannot be null.");
42 Objects.requireNonNull(constraints, "The list of constraints cannot be null.");
43
44 this.name = name;
45 this.constraints = constraints;
46 }
47
48 public ModelQueriesGlobalConstraint(
49 List<IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> constraints) {
50 this(GLOBAL_CONSTRAINT, constraints);
51 }
52
53 public ModelQueriesGlobalConstraint(String name) {
54 this(name, new ArrayList<IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>>());
55 }
56
57 public ModelQueriesGlobalConstraint() {
58 this(GLOBAL_CONSTRAINT,
59 new ArrayList<IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>>());
60 }
61
62 /**
63 * Adds a new VIATRA Query pattern.
64 *
65 * @param constraint
66 * A VIATRA Query pattern.
67 * @return The actual instance to enable builder pattern like usage.
68 */
69 public ModelQueriesGlobalConstraint withConstraint(
70 IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> constraint) {
71 constraints.add(constraint);
72 return this;
73 }
74
75 public ModelQueriesGlobalConstraint withType(ModelQueryType type) {
76 this.type = type;
77 return this;
78 }
79
80 @Override
81 public String getName() {
82 return name;
83 }
84
85 @Override
86 public boolean checkGlobalConstraint(ThreadContext context) {
87 for (ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) {
88 if ((type.equals(ModelQueryType.NO_MATCH) && matcher.countMatches() > 0)
89 || (type.equals(ModelQueryType.MUST_HAVE_MATCH) && matcher.countMatches() == 0)) {
90 return false;
91 }
92 }
93 return true;
94 }
95
96 @Override
97 public void init(ThreadContext context) {
98 try {
99 ViatraQueryEngine queryEngine = context.getQueryEngine();
100
101 for (IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification : constraints) {
102 ViatraQueryMatcher<? extends IPatternMatch> matcher = querySpecification.getMatcher(queryEngine);
103 matchers.add(matcher);
104 }
105
106 } catch (ViatraQueryException e) {
107 throw new DSEException("Couldn't get the VIATRA Query matcher, see inner exception", e);
108 }
109 }
110
111 @Override
112 public IGlobalConstraint createNew() {
113 return new ModelQueriesGlobalConstraint(name, constraints);
114 }
115
116}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueryType.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueryType.java
new file mode 100644
index 00000000..76390352
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/ModelQueryType.java
@@ -0,0 +1,14 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11public enum ModelQueryType {
12 MUST_HAVE_MATCH,
13 NO_MATCH
14}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NeverSatisfiedDummyHardObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NeverSatisfiedDummyHardObjective.java
new file mode 100644
index 00000000..27cf139c
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NeverSatisfiedDummyHardObjective.java
@@ -0,0 +1,52 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import org.eclipse.viatra.dse.base.ThreadContext;
12import org.eclipse.viatra.dse.objectives.IObjective;
13
14/**
15 * This hard objective is never fulfilled. Use it if all states should be regarded as an invalid solution.
16 *
17 * @author Andras Szabolcs Nagy
18 *
19 */
20public class NeverSatisfiedDummyHardObjective extends BaseObjective {
21
22 private static final String DEFAULT_NAME = "NeverSatisfiedDummyHardObjective";
23
24 public NeverSatisfiedDummyHardObjective() {
25 super(DEFAULT_NAME);
26 }
27
28 public NeverSatisfiedDummyHardObjective(String name) {
29 super(name);
30 }
31
32 @Override
33 public Double getFitness(ThreadContext context) {
34 return 0d;
35 }
36
37 @Override
38 public boolean isHardObjective() {
39 return true;
40 }
41
42 @Override
43 public boolean satisifiesHardObjective(Double fitness) {
44 return false;
45 }
46
47 @Override
48 public IObjective createNew() {
49 return this;
50 }
51
52}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NoRuleActivationsHardObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NoRuleActivationsHardObjective.java
new file mode 100644
index 00000000..756d94ec
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/NoRuleActivationsHardObjective.java
@@ -0,0 +1,59 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import org.eclipse.viatra.dse.base.ThreadContext;
12import org.eclipse.viatra.dse.objectives.IObjective;
13
14/**
15 * This hard objective is satisfied if there are no rule activations from the current state (returning 1 in this case).
16 *
17 * @author Andras Szabolcs Nagy
18 *
19 */
20public class NoRuleActivationsHardObjective extends BaseObjective {
21
22 protected static final String DEFAULT_NAME = "NoMoreActivationHardObjective";
23 private ThreadContext context;
24
25 public NoRuleActivationsHardObjective(String name) {
26 super(name);
27 }
28
29 public NoRuleActivationsHardObjective() {
30 this(DEFAULT_NAME);
31 }
32
33 @Override
34 public Double getFitness(ThreadContext context) {
35 return 0d;
36 }
37
38 @Override
39 public void init(ThreadContext context) {
40 super.init(context);
41 this.context = context;
42 }
43
44 @Override
45 public IObjective createNew() {
46 return new NoRuleActivationsHardObjective(name);
47 }
48
49 @Override
50 public boolean isHardObjective() {
51 return true;
52 }
53
54 @Override
55 public boolean satisifiesHardObjective(Double fitness) {
56 return context.getConflictSet().getNextActivations().isEmpty();
57 }
58
59}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/TrajectoryCostSoftObjective.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/TrajectoryCostSoftObjective.java
new file mode 100644
index 00000000..25ff45ae
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/objectives/impl/TrajectoryCostSoftObjective.java
@@ -0,0 +1,148 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.objectives.impl;
10
11import java.util.HashMap;
12import java.util.List;
13import java.util.Map;
14import java.util.Map.Entry;
15import java.util.Objects;
16
17import org.eclipse.viatra.dse.base.DesignSpaceManager;
18import org.eclipse.viatra.dse.base.ThreadContext;
19import org.eclipse.viatra.dse.designspace.api.TrajectoryInfo;
20import org.eclipse.viatra.dse.objectives.ActivationFitnessProcessor;
21import org.eclipse.viatra.dse.objectives.Comparators;
22import org.eclipse.viatra.dse.objectives.IObjective;
23import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
24import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule;
25
26/**
27 * This soft objective calculates a fitness value based on the length of the trajectory. Costs to the rules can be
28 * assigned.
29 *
30 * @author Andras Szabolcs Nagy
31 *
32 */
33public class TrajectoryCostSoftObjective extends BaseObjective {
34
35 public static final String DEFAULT_NAME = "TrajectoryCostObjective";
36 protected Map<BatchTransformationRule<?, ?>, Double> fixCosts;
37 protected Map<BatchTransformationRule<?, ?>, ActivationFitnessProcessor> activationCostProcessors;
38 protected double trajectoryLengthWeight = 0.0;
39 protected boolean calculateTrajectoryLengthWeight;
40
41 public TrajectoryCostSoftObjective(String name) {
42 super(name);
43 comparator = Comparators.LOWER_IS_BETTER;
44 }
45
46 public TrajectoryCostSoftObjective() {
47 this(DEFAULT_NAME);
48 }
49
50 /**
51 * Sets the cost of a rule.
52 *
53 * @param rule
54 * @param cost
55 * @return The actual instance to enable builder pattern like usage.
56 */
57 public TrajectoryCostSoftObjective withRuleCost(BatchTransformationRule<?, ?> rule, double cost) {
58 Objects.requireNonNull(rule);
59 if (fixCosts == null) {
60 fixCosts = new HashMap<BatchTransformationRule<?, ?>, Double>();
61 }
62 Preconditions.checkArgument(!fixCosts.containsKey(rule));
63 fixCosts.put(rule, cost);
64 return this;
65 }
66
67 /**
68 * Sets an activation processor for a rule.
69 *
70 * @param rule
71 * @param activationCostProcessor
72 * @return The actual instance to enable builder pattern like usage.
73 */
74 public TrajectoryCostSoftObjective withActivationCost(BatchTransformationRule<?, ?> rule,
75 ActivationFitnessProcessor activationCostProcessor) {
76 Objects.requireNonNull(rule);
77 Objects.requireNonNull(activationCostProcessor);
78 if (activationCostProcessors == null) {
79 activationCostProcessors = new HashMap<BatchTransformationRule<?, ?>, ActivationFitnessProcessor>();
80 }
81 Preconditions.checkArgument(!activationCostProcessors.containsKey(rule));
82 activationCostProcessors.put(rule, activationCostProcessor);
83 return this;
84 }
85
86 /**
87 * The length of the trajectory multiplied with given parameter will be added to the fitness value.
88 *
89 * @param trajectoryLengthWeight
90 * The weight of a transformation rule application.
91 * @return The actual instance to enable builder pattern like usage.
92 */
93 public TrajectoryCostSoftObjective withTrajectoryLengthWeight(double trajectoryLengthWeight) {
94 this.trajectoryLengthWeight = trajectoryLengthWeight;
95 this.calculateTrajectoryLengthWeight = true;
96 return this;
97 }
98
99 @Override
100 public Double getFitness(ThreadContext context) {
101
102 DesignSpaceManager dsm = context.getDesignSpaceManager();
103 TrajectoryInfo trajectoryInfo = dsm.getTrajectoryInfo();
104 List<Object> trajectory = trajectoryInfo.getTrajectory();
105 List<BatchTransformationRule<?, ?>> rules = trajectoryInfo.getRules();
106
107 double result = 0;
108
109 for (int i = 0; i < trajectory.size(); i++) {
110 BatchTransformationRule<?, ?> rule = rules.get(i);
111
112 Double cost = fixCosts.get(rule);
113 if (cost != null) {
114 result += cost;
115 }
116
117 Map<String, Double> costs = trajectoryInfo.getMeasuredCosts().get(i);
118 if (costs != null) {
119 cost = costs.get(name);
120 if (cost != null) {
121 result += cost;
122 }
123 }
124 }
125
126 if (calculateTrajectoryLengthWeight) {
127 result += trajectory.size() * trajectoryLengthWeight;
128 }
129
130 return result;
131 }
132
133 @Override
134 public void init(ThreadContext context) {
135 super.init(context);
136 DesignSpaceManager dsm = context.getDesignSpaceManager();
137 if (activationCostProcessors != null) {
138 for (Entry<BatchTransformationRule<?, ?>, ActivationFitnessProcessor> entry : activationCostProcessors.entrySet()) {
139 dsm.registerActivationCostProcessor(name, entry.getKey(), entry.getValue());
140 }
141 }
142 }
143
144 @Override
145 public IObjective createNew() {
146 return this;
147 }
148}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionFoundHandler.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionFoundHandler.java
new file mode 100644
index 00000000..8d74e856
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionFoundHandler.java
@@ -0,0 +1,40 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11import org.eclipse.viatra.dse.api.SolutionTrajectory;
12import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
13import org.eclipse.viatra.dse.base.ThreadContext;
14import org.eclipse.viatra.dse.solutionstore.SolutionStore.ISolutionSaver;
15
16/**
17 * Contains callback methods which are called when a solution is found by the exploration {@link IStrategy}.
18 *
19 * @author Andras Szabolcs Nagy
20 *
21 */
22public interface ISolutionFoundHandler {
23
24 /**
25 * Called when a solution is saved by the {@link ISolutionSaver}. Later, this solution can be omitted from the final
26 * set of solutions.
27 *
28 * @param context
29 * @param trajectory
30 */
31 void solutionFound(ThreadContext context, SolutionTrajectory trajectory);
32
33 /**
34 * Called when the exploration found a solution but it was not saved because of certain conditions.
35 *
36 * @param context
37 * @param trajectory
38 */
39 void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory);
40} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionNameProvider.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionNameProvider.java
new file mode 100644
index 00000000..36e6b5b7
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionNameProvider.java
@@ -0,0 +1,18 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11/**
12 * Provides file name when a model is searialzed.
13 * @author Andras Szabolcs Nagy
14 *
15 */
16public interface ISolutionNameProvider {
17 String getName();
18} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/IdBasedSolutionNameProvider.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/IdBasedSolutionNameProvider.java
new file mode 100644
index 00000000..43460015
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/IdBasedSolutionNameProvider.java
@@ -0,0 +1,37 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11/**
12 * Provides file name with a String <code>[prefix][id].[extension]</code> pattern.
13 * @author Andras Szabolcs Nagy
14 *
15 */
16public class IdBasedSolutionNameProvider implements ISolutionNameProvider {
17
18 private int id = 1;
19 private String prefix;
20 private String extension;
21
22 public IdBasedSolutionNameProvider(String prefix, String extension) {
23 this.extension = extension;
24 this.prefix = prefix;
25
26 }
27
28 @Override
29 public String getName() {
30 StringBuilder sb = new StringBuilder(prefix);
31 sb.append(id++);
32 sb.append('.');
33 sb.append(extension);
34 return sb.toString();
35 }
36
37} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/LogSolutionHandler.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/LogSolutionHandler.java
new file mode 100644
index 00000000..118f0c75
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/LogSolutionHandler.java
@@ -0,0 +1,28 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11import org.apache.log4j.Logger;
12import org.eclipse.viatra.dse.api.SolutionTrajectory;
13import org.eclipse.viatra.dse.base.ThreadContext;
14
15public class LogSolutionHandler implements ISolutionFoundHandler {
16
17 Logger logger = Logger.getLogger(LogSolutionHandler.class);
18
19 @Override
20 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
21 logger.info("Solution registered: " + trajectory.toPrettyString());
22 }
23
24 @Override
25 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
26 logger.debug("Not good enough solution: " + trajectory.toPrettyString());
27 }
28} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ModelSaverSolutionFoundHandler.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ModelSaverSolutionFoundHandler.java
new file mode 100644
index 00000000..bbbe60de
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ModelSaverSolutionFoundHandler.java
@@ -0,0 +1,55 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11import java.util.HashSet;
12
13import org.eclipse.emf.common.notify.Notifier;
14import org.eclipse.viatra.dse.api.SolutionTrajectory;
15import org.eclipse.viatra.dse.base.ThreadContext;
16import org.eclipse.viatra.dse.util.EMFHelper;
17
18public class ModelSaverSolutionFoundHandler implements ISolutionFoundHandler {
19
20 private HashSet<Object> savedSolutions = new HashSet<Object>();
21 private ISolutionNameProvider solutionNameProvider;
22
23 public ModelSaverSolutionFoundHandler() {
24 solutionNameProvider = new IdBasedSolutionNameProvider("solution", "xmi");
25 }
26
27 public ModelSaverSolutionFoundHandler(String extension) {
28 solutionNameProvider = new IdBasedSolutionNameProvider("solution", extension);
29 }
30
31 public ModelSaverSolutionFoundHandler(String prefix, String extension) {
32 solutionNameProvider = new IdBasedSolutionNameProvider(prefix, extension);
33 }
34
35 public ModelSaverSolutionFoundHandler(ISolutionNameProvider solutionNameProvider) {
36 this.solutionNameProvider = solutionNameProvider;
37 }
38
39 @Override
40 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
41 }
42
43 @Override
44 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
45 Object stateCode = trajectory.getSolution().getStateCode();
46
47 if (savedSolutions.contains(stateCode)) {
48 return;
49 }
50
51 savedSolutions.add(stateCode);
52 Notifier clonedModel = EMFHelper.clone(context.getModel());
53 EMFHelper.saveModel(clonedModel, solutionNameProvider.getName());
54 }
55} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/SolutionStore.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/SolutionStore.java
new file mode 100644
index 00000000..578ae277
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/SolutionStore.java
@@ -0,0 +1,311 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11import java.util.ArrayList;
12import java.util.Collection;
13import java.util.HashMap;
14import java.util.List;
15import java.util.Map;
16import java.util.Map.Entry;
17import java.util.concurrent.atomic.AtomicBoolean;
18import java.util.concurrent.atomic.AtomicInteger;
19
20import org.apache.log4j.Level;
21import org.apache.log4j.Logger;
22import org.eclipse.emf.common.notify.Notifier;
23import org.eclipse.viatra.dse.api.DSEException;
24import org.eclipse.viatra.dse.api.Solution;
25import org.eclipse.viatra.dse.api.SolutionTrajectory;
26import org.eclipse.viatra.dse.base.DesignSpaceManager;
27import org.eclipse.viatra.dse.base.ThreadContext;
28import org.eclipse.viatra.dse.objectives.Fitness;
29import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
30import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
31import org.eclipse.viatra.dse.util.EMFHelper;
32import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
33
34/**
35 *
36 * @author Andras Szabolcs Nagy
37 *
38 */
39public class SolutionStore {
40
41 public interface ISolutionSaver {
42 void setSolutionsCollection(Map<Object, Solution> solutions);
43 boolean saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory);
44 }
45
46 public interface IEnoughSolutions extends ISolutionFoundHandler {
47 boolean enoughSolutions();
48 }
49
50 public static class ANumberOfEnoughSolutions implements IEnoughSolutions {
51
52 private final AtomicInteger foundSolutions;
53 private final AtomicBoolean foundEnoughSolutions;
54
55 public ANumberOfEnoughSolutions(int number) {
56 foundSolutions = new AtomicInteger(number);
57 foundEnoughSolutions = new AtomicBoolean(false);
58 }
59
60 @Override
61 public boolean enoughSolutions() {
62 return foundEnoughSolutions.get();
63 }
64
65 @Override
66 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
67 int solutionsToFind = foundSolutions.decrementAndGet();
68 if (solutionsToFind == 0) {
69 foundEnoughSolutions.set(true);
70 }
71 }
72
73 @Override
74 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
75 }
76 }
77
78 public static class SimpleSolutionSaver implements ISolutionSaver {
79
80 private Map<Object, Solution> solutions;
81
82 @Override
83 public void setSolutionsCollection(Map<Object, Solution> solutions) {
84 this.solutions = solutions;
85 }
86
87 @Override
88 public boolean saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
89 Solution solution = solutions.get(id);
90 if (solution != null) {
91 if (solution.getTrajectories().contains(solutionTrajectory)) {
92 return false;
93 } else {
94 solution.addTrajectory(solutionTrajectory);
95 solutionTrajectory.setSolution(solution);
96 }
97 } else {
98 solution = new Solution(id, solutionTrajectory);
99 solutions.put(id, solution);
100 solutionTrajectory.setSolution(solution);
101 }
102 return true;
103 }
104 }
105
106 public static class BestSolutionSaver implements ISolutionSaver {
107
108 private Map<Object, Solution> solutions;
109 private Map<SolutionTrajectory, Fitness> trajectories = new HashMap<>();
110
111 @Override
112 public void setSolutionsCollection(Map<Object, Solution> solutions) {
113 this.solutions = solutions;
114 }
115
116 @Override
117 public boolean saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
118
119 Fitness lastFitness = context.getLastFitness();
120 ObjectiveComparatorHelper comparatorHelper = context.getObjectiveComparatorHelper();
121
122 List<SolutionTrajectory> dominatedTrajectories = new ArrayList<>();
123
124 for (Entry<SolutionTrajectory, Fitness> entry : trajectories.entrySet()) {
125 int isLastFitnessBetter = comparatorHelper.compare(lastFitness, entry.getValue());
126 if (isLastFitnessBetter < 0) {
127 return false;
128 }
129 if (isLastFitnessBetter > 0) {
130 dominatedTrajectories.add(entry.getKey());
131 }
132 }
133
134 boolean solutionSaved = false;
135
136 Solution solution = solutions.get(id);
137 if (solution != null) {
138 if (!solution.getTrajectories().contains(solutionTrajectory)) {
139 solution.addTrajectory(solutionTrajectory);
140 solutionTrajectory.setSolution(solution);
141 solutionSaved = true;
142 trajectories.put(solutionTrajectory, lastFitness);
143 }
144 } else {
145 solution = new Solution(id, solutionTrajectory);
146 solutions.put(id, solution);
147 solutionTrajectory.setSolution(solution);
148 solutionSaved = true;
149 trajectories.put(solutionTrajectory, lastFitness);
150 }
151
152 for (SolutionTrajectory st : dominatedTrajectories) {
153 trajectories.remove(st);
154 Solution s = st.getSolution();
155 if (!s.getTrajectories().remove(st)) {
156 throw new DSEException("Should not happen.");
157 }
158 if (s.getTrajectories().isEmpty()) {
159 Object stateCode = s.getStateCode();
160 solutions.remove(stateCode);
161 }
162 }
163
164 return solutionSaved;
165 }
166
167 }
168
169 protected boolean acceptOnlyGoalSolutions = true;
170 protected final Map<Object, Solution> solutions = new HashMap<Object, Solution>();
171 protected ISolutionSaver solutionSaver = new SimpleSolutionSaver();
172 protected List<ISolutionFoundHandler> solutionFoundHandlers = new ArrayList<ISolutionFoundHandler>(1);
173
174 protected final IEnoughSolutions enoughSolutions;
175
176 public SolutionStore() {
177 this(new IEnoughSolutions() {
178 @Override
179 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
180 }
181
182 @Override
183 public boolean enoughSolutions() {
184 return false;
185 }
186
187 @Override
188 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
189 }
190 });
191 }
192
193 public SolutionStore(int numOfSolutionsToFind) {
194 this(new ANumberOfEnoughSolutions(numOfSolutionsToFind));
195 }
196
197 public SolutionStore(IEnoughSolutions enoughSolutionsImpl) {
198 enoughSolutions = enoughSolutionsImpl;
199 }
200
201 public synchronized void newSolution(ThreadContext context) {
202 solutionSaver.setSolutionsCollection(solutions);
203 Fitness fitness = context.getLastFitness();
204 DesignSpaceManager dsm = context.getDesignSpaceManager();
205 Object id = dsm.getCurrentState();
206 IStateCoderFactory stateCoderFactory = context.getGlobalContext().getStateCoderFactory();
207 SolutionTrajectory solutionTrajectory = dsm.getTrajectoryInfo().createSolutionTrajectory(stateCoderFactory, context.getDesignSpaceManager());
208 solutionTrajectory.setFitness(fitness);
209
210 if (acceptOnlyGoalSolutions && !fitness.isSatisifiesHardObjectives()) {
211 unsavedSolutionCallbacks(context, solutionTrajectory);
212 return;
213 }
214
215 boolean solutionSaved = solutionSaver.saveSolution(context, id, solutionTrajectory);
216
217 if (solutionSaved) {
218 enoughSolutions.solutionFound(context, solutionTrajectory);
219
220 savedSolutionCallbacks(context, solutionTrajectory);
221
222 if (enoughSolutions.enoughSolutions()) {
223 context.getGlobalContext().stopAllThreads();
224 }
225 } else {
226 unsavedSolutionCallbacks(context, solutionTrajectory);
227 }
228 }
229
230 private void unsavedSolutionCallbacks(ThreadContext context, SolutionTrajectory solutionTrajectory) {
231 for (ISolutionFoundHandler handler : solutionFoundHandlers) {
232 handler.solutionTriedToSave(context, solutionTrajectory);
233 }
234 }
235
236 private void savedSolutionCallbacks(ThreadContext context, SolutionTrajectory solutionTrajectory) {
237 for (ISolutionFoundHandler handler : solutionFoundHandlers) {
238 handler.solutionFound(context, solutionTrajectory);
239 }
240 }
241
242 public synchronized Collection<Solution> getSolutions() {
243 return solutions.values();
244 }
245
246 public synchronized void registerSolutionFoundHandler(ISolutionFoundHandler handler) {
247 if (solutionFoundHandlers == null) {
248 solutionFoundHandlers = new ArrayList<ISolutionFoundHandler>(1);
249 }
250 solutionFoundHandlers.add(handler);
251 }
252
253 public SolutionStore logSolutionsWhenFound() {
254 registerSolutionFoundHandler(new LogSolutionHandler());
255 Logger.getLogger(LogSolutionHandler.class).setLevel(Level.INFO);
256 return this;
257 }
258
259 public SolutionStore saveModelWhenFound() {
260 registerSolutionFoundHandler(new ModelSaverSolutionFoundHandler());
261 return this;
262 }
263
264 public SolutionStore saveModelWhenFound(String extension) {
265 registerSolutionFoundHandler(new ModelSaverSolutionFoundHandler(extension));
266 return this;
267 }
268
269 public SolutionStore saveModelWhenFound(String prefix, String extension) {
270 registerSolutionFoundHandler(new ModelSaverSolutionFoundHandler(prefix, extension));
271 return this;
272 }
273
274 public SolutionStore saveModelWhenFound(ISolutionNameProvider solutionNameProvider) {
275 registerSolutionFoundHandler(new ModelSaverSolutionFoundHandler(solutionNameProvider));
276 return this;
277 }
278
279 public SolutionStore acceptGoalSolutionsOnly() {
280 acceptOnlyGoalSolutions = true;
281 return this;
282 }
283
284 public SolutionStore acceptAnySolutions() {
285 acceptOnlyGoalSolutions = false;
286 return this;
287 }
288
289 public SolutionStore withSolutionSaver(ISolutionSaver solutionSaver) {
290 this.solutionSaver = solutionSaver;
291 return this;
292 }
293
294 public SolutionStore storeBestSolutionsOnly() {
295 this.solutionSaver = new BestSolutionSaver();
296 return this;
297 }
298
299 public void saveModels(Notifier model, ISolutionNameProvider solutionNameProvider) {
300 try {
301 for (Solution solution : solutions.values()) {
302 SolutionTrajectory trajectory = solution.getArbitraryTrajectory();
303 trajectory.doTransformationUndoable(model);
304 EMFHelper.saveModel(model, solutionNameProvider.getName());
305 trajectory.undoTransformation();
306 }
307 } catch (ViatraQueryException e) {
308 Logger.getLogger(SolutionStore.class).error("Exception happened during model saving.", e);
309 }
310 }
311}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoder.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoder.java
new file mode 100644
index 00000000..f163f1a5
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoder.java
@@ -0,0 +1,82 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecode;
10
11import org.eclipse.emf.common.notify.Notifier;
12import org.eclipse.viatra.query.runtime.api.IPatternMatch;
13
14/**
15 * <p>
16 * To be able to efficiently explore a design space, a state that has been explored before through an other trajectory
17 * needs to be recognized and ignored accordingly.
18 * </p>
19 *
20 * <p>
21 * This is done by generating a pseudo-unique value (object) that is only depended on the relevant parts of the model's
22 * internal state, that is, the values of two states can only be equal if the states themselves can be considered equal.
23 * </p>
24 *
25 * <p>
26 * The processing engine however assumes, that any two states that share this pseudo-unique value has the same
27 * characteristics, meaning they have the same amount and type of outgoing transitions available, and firing the
28 * appropriate transitions from both states also result in states that share their pseudo-unique identifier. If this
29 * condition is not satisfied, the exploration process's result will be non-deterministic, and in consequence, solutions
30 * can be lost.
31 * </p>
32 *
33 * <p>
34 * In addition to providing pseudo-unique identifiers to model states, the state coder must provide pseud-unique
35 * identifiers to the outgoing transitions as well, but they only need to be unique on the scope of the particular
36 * state, not globally. Global addressing thus can be achieved by considering the pseudo-unique identifier of the state
37 * and the pseudo-unique identifier of the transition together if needed.
38 * </p>
39 *
40 * <p>
41 * Both identifiers can be arbitrary objects, and equality is checked by calling {@link Object#equals(Object)} on the
42 * two identifiers.
43 * </p>
44 *
45 * <p>
46 * For any particular implementation an {@link IStateCoderFactory} implementation must also be supplied that handles the
47 * creation of {@link IStateCoder} instances.
48 * </p>
49 *
50 * <p>
51 * Usually it is unnecessary to represent everything from the model in a state code, only the parts which are modified
52 * by the transformation rules.
53 * </p>
54 *
55 * @author Miklos Foldenyi, Andras Szabolcs Nagy
56 *
57 */
58public interface IStateCoder {
59
60 /**
61 * Initializes the state coder on the given model.
62 *
63 * @param notifier
64 */
65 void init(Notifier notifier);
66
67 /**
68 * Returns a pseudo-unique identifier that describes the underlying model's current internal state.
69 *
70 * @return an arbitrary {@link Object} that can be used as the identifier.
71 */
72 Object createStateCode();
73
74 /**
75 * Returns a pseudo-unique identifier that describes the given {@link IPatternMatch} in the context of the
76 * underlying model's current internal state.
77 *
78 * @return an arbitrary {@link Object} that can be used as the identifier in the given state.
79 */
80 Object createActivationCode(IPatternMatch match);
81
82}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoderFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoderFactory.java
new file mode 100644
index 00000000..cf8bdf8d
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecode/IStateCoderFactory.java
@@ -0,0 +1,29 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecode;
10
11/**
12 * Interface for a factory class that creates instances of {@link IStateCoder} objects. This is required because state
13 * coders have to be created on-demand if the design space exploration process decides that a new thread is to be
14 * spawned. Since each thread requires it's own working model instance and a state coder is linked to the underlying
15 * model, a new {@link IStateCoder} needs to be created per processing thread.
16 *
17 * @author Miklos Foldenyi, Andras Szabolcs Nagy
18 *
19 */
20public interface IStateCoderFactory {
21
22 /**
23 * Creates a new {@link IStateCoder} instance specific to this {@link IStateCoderFactory}.
24 *
25 * @return the new {@link IStateCoder} instance specific to this working model.
26 */
27 IStateCoder createStateCoder();
28
29}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProvider.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProvider.java
new file mode 100644
index 00000000..afcba7b6
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProvider.java
@@ -0,0 +1,45 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11import java.util.Collection;
12
13import org.eclipse.emf.common.notify.Notifier;
14import org.eclipse.emf.ecore.EClass;
15import org.eclipse.emf.ecore.EObject;
16
17/**
18 * Implementation of this interface is responsible to provide {@link EObject}s of a given {@link EClass} for
19 * {@link TheStateCoder}
20 *
21 * @author Andras Szabolcs Nagy
22 *
23 */
24public interface IObjectsProvider {
25
26 /**
27 * Initialize the {@link IObjectsProvider} on a given model and {@link StatecodingDependencyGraph}.
28 *
29 * @param notifier
30 * The root of the model.
31 * @param statecodingDependencyGraph
32 * The state coding dependency graph.
33 */
34 void init(Notifier notifier, StatecodingDependencyGraph statecodingDependencyGraph);
35
36 /**
37 * Returns the instances of an {@link EClass} in a model.
38 *
39 * @param eClass
40 * The class of the objects.
41 * @return The collection of the instances.
42 */
43 Collection<EObject> getEObjects(EClass eClass);
44
45}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProviderFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProviderFactory.java
new file mode 100644
index 00000000..931eb1a2
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProviderFactory.java
@@ -0,0 +1,25 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11/**
12 * Interface for creating {@link IObjectsProvider} instances.
13 *
14 * @author Andras Szabolcs Nagy
15 */
16public interface IObjectsProviderFactory {
17
18 /**
19 * Creates an {@link IObjectsProvider} implementation.
20 *
21 * @return The newly created {@link IObjectsProvider}.
22 */
23 IObjectsProvider createObjectsProvider();
24
25}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProvider.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProvider.java
new file mode 100644
index 00000000..e38d45d3
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProvider.java
@@ -0,0 +1,60 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11import java.util.Collection;
12import java.util.HashSet;
13import java.util.Set;
14
15import org.apache.log4j.Logger;
16import org.eclipse.emf.common.notify.Notifier;
17import org.eclipse.emf.ecore.EClass;
18import org.eclipse.emf.ecore.EObject;
19import org.eclipse.viatra.dse.api.DSEException;
20import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
21import org.eclipse.viatra.query.runtime.base.api.IndexingLevel;
22import org.eclipse.viatra.query.runtime.base.api.NavigationHelper;
23import org.eclipse.viatra.query.runtime.emf.EMFScope;
24import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
25
26public class IncrementalObjectProvider implements IObjectsProvider {
27
28 private Logger logger = Logger.getLogger(getClass());
29 private NavigationHelper baseIndex;
30
31 @Override
32 public void init(Notifier notifier, StatecodingDependencyGraph statecodingDependencyGraph) {
33
34 try {
35 EMFScope scope = new EMFScope(notifier);
36 ViatraQueryEngine queryEngine = ViatraQueryEngine.on(scope);
37
38 Set<EClass> classes = new HashSet<EClass>();
39// Set<EReference> references = new HashSet<EReference>();
40 for (StatecodingNode node : statecodingDependencyGraph.getNodes()) {
41 classes.add(node.getClazz());
42// for (StatecodingDependency dependency : node.getStatecodingDependencies()) {
43// // TODO inverse reference
44// references.add(dependency.eReference);
45// }
46 }
47 baseIndex = EMFScope.extractUnderlyingEMFIndex(queryEngine);
48 baseIndex.registerEClasses(classes, IndexingLevel.FULL);
49 } catch (ViatraQueryException e) {
50 logger.error("Failed to initialize VIATRA Query engine on the given notifier", e);
51 throw new DSEException("Failed to initialize VIATRA Query engine on the given notifier");
52 }
53 }
54
55 @Override
56 public Collection<EObject> getEObjects(EClass eClass) {
57 return baseIndex.getAllInstances(eClass);
58 }
59
60}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProviderFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProviderFactory.java
new file mode 100644
index 00000000..97011436
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProviderFactory.java
@@ -0,0 +1,18 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11public class IncrementalObjectProviderFactory implements IObjectsProviderFactory {
12
13 @Override
14 public IncrementalObjectProvider createObjectsProvider() {
15 return new IncrementalObjectProvider();
16 }
17
18}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependency.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependency.java
new file mode 100644
index 00000000..67b1982d
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependency.java
@@ -0,0 +1,33 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11import org.eclipse.emf.ecore.EReference;
12
13public class StatecodingDependency {
14
15 protected EReference eReference;
16 protected StatecodingNode node;
17 protected boolean isContained;
18 protected StatecodingDependencyType type;
19
20 public StatecodingDependency(EReference eReference, StatecodingNode node, boolean isContained,
21 StatecodingDependencyType type) {
22 super();
23 this.eReference = eReference;
24 this.node = node;
25 this.isContained = isContained;
26 this.type = type;
27 }
28
29 public StatecodingDependency(EReference eReference, StatecodingNode node) {
30 this(eReference, node, false, StatecodingDependencyType.NORMAL);
31 }
32
33} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyGraph.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyGraph.java
new file mode 100644
index 00000000..6f7255a3
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyGraph.java
@@ -0,0 +1,44 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11import java.util.ArrayList;
12import java.util.List;
13
14import org.eclipse.emf.ecore.EClass;
15
16public class StatecodingDependencyGraph {
17
18 private List<StatecodingNode> nodes = new ArrayList<StatecodingNode>();
19
20 public StatecodingNode createNode(EClass clazz) {
21 StatecodingNode node = new StatecodingNode(clazz);
22 node.setGraph(this);
23 addNode(node);
24 return node;
25 }
26
27 public void addNode(StatecodingNode node) {
28 nodes.add(node);
29 }
30
31 public StatecodingNode getNodeByClass(EClass eClass) {
32 for (StatecodingNode node : nodes) {
33 if (node.getClazz().equals(eClass)) {
34 return node;
35 }
36 }
37 return null;
38 }
39
40 public List<StatecodingNode> getNodes() {
41 return nodes;
42 }
43
44}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyType.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyType.java
new file mode 100644
index 00000000..bdd4677d
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyType.java
@@ -0,0 +1,15 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11public enum StatecodingDependencyType {
12
13 NORMAL,
14 INVERSE
15}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNode.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNode.java
new file mode 100644
index 00000000..91fc28cf
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNode.java
@@ -0,0 +1,100 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11import java.util.ArrayList;
12import java.util.Comparator;
13import java.util.List;
14import java.util.Set;
15import java.util.TreeSet;
16
17import org.eclipse.emf.ecore.EAttribute;
18import org.eclipse.emf.ecore.EClass;
19import org.eclipse.emf.ecore.EReference;
20
21public class StatecodingNode {
22
23 private StatecodingDependencyGraph graph;
24
25 private final EClass clazz;
26 private Set<EAttribute> attributes = new TreeSet<EAttribute>(Comparator.comparing(EAttribute::getName));
27 private List<StatecodingDependency> dependencies = new ArrayList<StatecodingDependency>();
28 private boolean stateCodeIsId = false;
29 private StatecodingNodeType statecodingNodeType = StatecodingNodeType.CREATE_AND_DELETE;
30
31 public StatecodingNode(EClass clazz) {
32 this.clazz = clazz;
33 }
34
35 public StatecodingNode withAttribute(EAttribute attribute) {
36 attributes.add(attribute);
37 return this;
38 }
39
40 public StatecodingNode withType(StatecodingNodeType type) {
41 statecodingNodeType = type;
42 return this;
43 }
44
45 public StatecodingNode withUniqueness() {
46 stateCodeIsId = true;
47 return this;
48 }
49
50 public StatecodingNode withDependency(EReference reference, StatecodingNode node) {
51 dependencies.add(new StatecodingDependency(reference, node));
52 return this;
53 }
54
55 public StatecodingNode withInverseDependency(EReference reference, StatecodingNode node) {
56 dependencies.add(new StatecodingDependency(reference, node, false, StatecodingDependencyType.INVERSE));
57 return this;
58 }
59
60 public void addDependency(StatecodingDependency statecodingDependency) {
61 dependencies.add(statecodingDependency);
62 }
63
64 public EClass getClazz() {
65 return clazz;
66 }
67
68 public boolean isStateCodeIsId() {
69 return stateCodeIsId;
70 }
71
72 public void setStateCodeIsId(boolean stateCodeIsId) {
73 this.stateCodeIsId = stateCodeIsId;
74 }
75
76 public StatecodingNodeType getStatecodingNodeType() {
77 return statecodingNodeType;
78 }
79
80 public void setStatecodingNodeType(StatecodingNodeType statecodingNodeType) {
81 this.statecodingNodeType = statecodingNodeType;
82 }
83
84 public Set<EAttribute> getAttributes() {
85 return attributes;
86 }
87
88 public List<StatecodingDependency> getStatecodingDependencies() {
89 return dependencies;
90 }
91
92 public StatecodingDependencyGraph getGraph() {
93 return graph;
94 }
95
96 public void setGraph(StatecodingDependencyGraph graph) {
97 this.graph = graph;
98 }
99
100}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNodeType.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNodeType.java
new file mode 100644
index 00000000..c902a7a6
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNodeType.java
@@ -0,0 +1,17 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11public enum StatecodingNodeType {
12
13 FIXED,
14 ONLY_CREATE,
15 ONLY_DELETE,
16 CREATE_AND_DELETE
17}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoder.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoder.java
new file mode 100644
index 00000000..4601ff08
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoder.java
@@ -0,0 +1,215 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11import java.util.Arrays;
12import java.util.Collection;
13import java.util.List;
14import java.util.Set;
15
16import org.eclipse.emf.common.notify.Notifier;
17import org.eclipse.emf.common.util.EList;
18import org.eclipse.emf.ecore.EAttribute;
19import org.eclipse.emf.ecore.EObject;
20import org.eclipse.viatra.dse.api.DSEException;
21import org.eclipse.viatra.dse.statecode.IStateCoder;
22import org.eclipse.viatra.query.runtime.api.IPatternMatch;
23
24public class TheStateCoder implements IStateCoder {
25
26 private StatecodingDependencyGraph sdg;
27 private IObjectsProvider objectProvider;
28
29 public TheStateCoder(StatecodingDependencyGraph sdg, IObjectsProvider objectProvider) {
30 this.sdg = sdg;
31 this.objectProvider = objectProvider;
32 }
33
34 @Override
35 public void init(Notifier notifier) {
36 // TODO checks
37 // TODO node sorting based on traversal - in factory
38
39 // this.notifier = notifier;
40 // try {
41 // EMFScope scope = new EMFScope(notifier);
42 // queryEngine = ViatraQueryEngine.on(scope);
43 // } catch (ViatraQueryException e1) {
44 // logger.error("Failed to initialize VIATRA Query engine on the given notifier", e1);
45 // throw new DSEException("Failed to initialize VIATRA Query engine on the given notifier");
46 // }
47
48 objectProvider.init(notifier, sdg);
49 }
50
51 @Override
52 public String createStateCode() {
53
54 StringBuilder sb = new StringBuilder();
55
56 // TODO sort
57 for (StatecodingNode node : sdg.getNodes()) {
58 sb.append(node.getClazz().getName());
59 sb.append(':');
60 sb.append(addStateCode(node));
61 sb.append('|');
62 }
63 sb.deleteCharAt(sb.length() - 1);
64
65 return sb.toString();
66
67 }
68
69 @Override
70 public Object createActivationCode(IPatternMatch match) {
71 // TODO root object
72 // TODO parameterless?
73
74 int i = 0;
75 StringBuilder sb = new StringBuilder();
76 Object object;
77 do {
78 object = match.get(i++);
79 if (object != null) {
80 if (object instanceof EObject) {
81 EObject eObject = (EObject) object;
82 sb.append(addStateCode(sdg.getNodeByClass(eObject.eClass()), eObject));
83 } else {
84 // TODO toString or not to toString
85 }
86 }
87 } while (object != null);
88
89 return sb.toString();
90 }
91
92 public String addStateCode(StatecodingNode node, EObject eObject) {
93 StringBuilder sb = new StringBuilder();
94
95 Set<EAttribute> attributes = node.getAttributes();
96 if (!attributes.isEmpty()) {
97 for (EAttribute eAttribute : attributes) {
98 // attributes are sorted
99 // TODO handle collection
100 sb.append(eObject.eGet(eAttribute));
101 sb.append(';');
102 }
103 sb.deleteCharAt(sb.length() - 1);
104 }
105
106 List<StatecodingDependency> dependencies = node.getStatecodingDependencies();
107 int dependenciesSize = dependencies.size();
108 if (dependenciesSize > 0) {
109 String[] codeParts = new String[dependenciesSize];
110 int i = 0;
111 for (StatecodingDependency dependency : dependencies) {
112 String code = addStateCodeFromDependency(dependency, eObject);
113 codeParts[i++] = code;
114 }
115 Arrays.sort(codeParts);
116
117 sb.append("(");
118 sb.append(codeParts[0]);
119 for (i = 1; i < codeParts.length; i++) {
120 sb.append(';');
121 sb.append(codeParts[i]);
122 }
123 sb.append(")");
124 }
125 return sb.toString();
126 }
127
128 public String addStateCode(StatecodingNode node) {
129 Collection<EObject> eObjects = objectProvider.getEObjects(node.getClazz());
130 int size = eObjects.size();
131
132 if (size > 0) {
133 String[] codeParts = new String[size];
134 int i = 0;
135 for (EObject eObject : eObjects) {
136 String code = addStateCode(node, eObject);
137 codeParts[i++] = code;
138 }
139 Arrays.sort(codeParts);
140
141 StringBuilder sb = new StringBuilder();
142 sb.append(codeParts[0]);
143 for (i = 1; i < codeParts.length; i++) {
144 sb.append(';');
145 sb.append(codeParts[i]);
146 }
147 return sb.toString();
148 }
149
150 return "";
151 }
152
153 public String addStateCodeFromDependency(StatecodingDependency sd, EObject eObject) {
154
155 if (sd.type.equals(StatecodingDependencyType.NORMAL)) {
156
157 Object eReferred = eObject.eGet(sd.eReference);
158 if (eReferred == null) {
159 return "";
160 } else if (eReferred instanceof EList<?>) {
161 EList<?> refferedList = (EList<?>) eReferred;
162 // TODO test
163 if (!refferedList.isEmpty()) {
164
165 String[] codeParts = new String[refferedList.size()];
166 int i = 0;
167 for (Object referredEObject : refferedList) {
168 String code = addStateCode(sd.node, (EObject) referredEObject);
169 codeParts[i++] = code;
170 }
171 Arrays.sort(codeParts);
172
173 StringBuilder sb = new StringBuilder();
174 sb.append('[');
175 sb.append(codeParts[0]);
176 for (i = 1; i < codeParts.length; i++) {
177 sb.append(';');
178 sb.append(codeParts[i]);
179 }
180 sb.append(']');
181 return sb.toString();
182
183 }
184 } else if (eReferred instanceof EObject) {
185 return addStateCode(sd.node, (EObject) eReferred);
186 } else {
187 throw new DSEException("The EObject " + eObject.toString() + " does not have a feature "
188 + eReferred.toString() + ".");
189 }
190
191 } else {
192 for (EObject dependentEObject : objectProvider.getEObjects(sd.node.getClazz())) {
193 Object eReferred = dependentEObject.eGet(sd.eReference);
194 if (eReferred == null) {
195 continue;
196 } else if (eReferred instanceof EList<?>) {
197 // TODO this is slow, use VIATRA Query
198 for (Object referredEObject : ((EList<?>) eReferred)) {
199 if (referredEObject.equals(eObject)) {
200 return addStateCode(sd.node, (EObject) dependentEObject);
201 }
202 }
203 } else if (eReferred.equals(eObject)) {
204 // Probably never happens?
205 return addStateCode(sd.node, (EObject) dependentEObject);
206 } else {
207 throw new DSEException("The EObject " + eObject.toString() + " does not have a feature "
208 + eReferred.toString() + ".");
209 }
210 }
211 }
212
213 return "";
214 }
215}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoderFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoderFactory.java
new file mode 100644
index 00000000..eeb6e48f
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoderFactory.java
@@ -0,0 +1,40 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding;
10
11import org.eclipse.viatra.dse.statecode.IStateCoder;
12import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
13
14public class TheStateCoderFactory implements IStateCoderFactory {
15
16 private StatecodingDependencyGraph sdg;
17 private IObjectsProviderFactory objectProviderFactory;
18
19 public TheStateCoderFactory(StatecodingDependencyGraph sdg) {
20 this(sdg, new IncrementalObjectProviderFactory());
21 }
22
23 public TheStateCoderFactory(StatecodingDependencyGraph sdg, IObjectsProviderFactory objectProviderFactory) {
24 this.sdg = sdg;
25 this.objectProviderFactory = objectProviderFactory;
26
27 // TODO cyclic dependency? - exception
28
29 // TODO make plan for traversal
30
31 // TODO If the type is FIXED and all dependency is FIXED then do not create state code for it (them)
32 // This is not true :( e.g. matchmaking - they are fixed, but the references must be encoded
33 }
34
35 @Override
36 public IStateCoder createStateCoder() {
37 return new TheStateCoder(sdg, objectProviderFactory.createObjectsProvider());
38 }
39
40}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder.java
new file mode 100644
index 00000000..0f0759ae
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder.java
@@ -0,0 +1,250 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding.simple;
10
11import java.util.Arrays;
12import java.util.Collection;
13import java.util.HashMap;
14import java.util.HashSet;
15import java.util.List;
16import java.util.Map;
17import java.util.Set;
18
19import org.eclipse.emf.common.notify.Notifier;
20import org.eclipse.emf.ecore.EAttribute;
21import org.eclipse.emf.ecore.EClass;
22import org.eclipse.emf.ecore.EObject;
23import org.eclipse.emf.ecore.EReference;
24import org.eclipse.emf.ecore.EStructuralFeature;
25import org.eclipse.emf.ecore.EStructuralFeature.Setting;
26import org.eclipse.viatra.dse.api.DSEException;
27import org.eclipse.viatra.dse.statecode.IStateCoder;
28import org.eclipse.viatra.dse.util.EMFHelper.MetaModelElements;
29import org.eclipse.viatra.dse.util.ValueComparableEObjectStringMap;
30import org.eclipse.viatra.query.runtime.api.IPatternMatch;
31import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
32import org.eclipse.viatra.query.runtime.base.api.FeatureListener;
33import org.eclipse.viatra.query.runtime.base.api.IndexingLevel;
34import org.eclipse.viatra.query.runtime.base.api.InstanceListener;
35import org.eclipse.viatra.query.runtime.base.api.NavigationHelper;
36import org.eclipse.viatra.query.runtime.emf.EMFBaseIndexWrapper;
37import org.eclipse.viatra.query.runtime.emf.EMFScope;
38import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
39
40/**
41 *
42 * @author Andras Szabolcs Nagy
43 *
44 */
45public class SimpleStateCoder implements IStateCoder {
46
47 private Set<EClass> classes;
48 private Set<EStructuralFeature> features;
49 private NavigationHelper navigationHelper;
50
51 private Map<EClass, Map<EObject, String>> objectCodes;
52 private int maxDepth;
53
54 private Set<EObject> changedOrNewEObjects = new HashSet<EObject>();
55 private Set<EObject> deletedClasses = new HashSet<EObject>();
56
57 public SimpleStateCoder(MetaModelElements metaModelElements) {
58 this.maxDepth = 1;
59
60 classes = metaModelElements.classes;
61 features = new HashSet<EStructuralFeature>(metaModelElements.attributes);
62 features.addAll(metaModelElements.references);
63 }
64
65 @Override
66 public void init(Notifier notifier) {
67 try {
68 EMFScope scope = new EMFScope(notifier);
69 ViatraQueryEngine queryEngine = ViatraQueryEngine.on(scope);
70 EMFBaseIndexWrapper baseIndex = (EMFBaseIndexWrapper) queryEngine.getBaseIndex();
71 navigationHelper = baseIndex.getNavigationHelper();
72 navigationHelper.registerObservedTypes(classes, null, features, IndexingLevel.FULL);
73 } catch (ViatraQueryException e) {
74 throw new DSEException(e);
75 }
76
77 objectCodes = new HashMap<EClass, Map<EObject, String>>();
78 for (EClass eClass : classes) {
79 Map<EObject, String> codes = new ValueComparableEObjectStringMap();
80
81 objectCodes.put(eClass, codes);
82
83 for (EObject eObject : navigationHelper.getDirectInstances(eClass)) {
84 codes.put(eObject, createObjectCodeWithDepth(eObject, maxDepth));
85 }
86 }
87
88 navigationHelper.addFeatureListener(features, new FeatureListener() {
89
90 @Override
91 public void featureInserted(EObject host, EStructuralFeature feature, Object value) {
92 changedOrNewEObjects.add(host);
93 }
94
95 @Override
96 public void featureDeleted(EObject host, EStructuralFeature feature, Object value) {
97 changedOrNewEObjects.add(host);
98 if (value instanceof EObject) {
99 changedOrNewEObjects.add((EObject) value);
100 }
101 }
102 });
103
104 navigationHelper.addInstanceListener(classes, new InstanceListener() {
105
106 @Override
107 public void instanceInserted(EClass clazz, EObject instance) {
108 changedOrNewEObjects.add(instance);
109 }
110
111 @Override
112 public void instanceDeleted(EClass clazz, EObject instance) {
113 deletedClasses.add(instance);
114 }
115 });
116 }
117
118 private String createObjectCodeWithDepth(EObject eObject, int depth) {
119
120 StringBuilder sb = new StringBuilder();
121
122 Collection<EAttribute> attributes = eObject.eClass().getEAllAttributes();
123 for (EAttribute eAttribute : attributes) {
124 Object value = eObject.eGet(eAttribute);
125 sb.append(value);
126 sb.append(',');
127 }
128 if (!attributes.isEmpty()) {
129 sb.deleteCharAt(sb.length() - 1);
130 }
131 if (depth > 0) {
132 sb.append('-');
133 Collection<EReference> eReferences = eObject.eClass().getEAllReferences();
134 for (EReference eReference : eReferences) {
135 Object value = eObject.eGet(eReference);
136 if (value == null) {
137 sb.append("null,");
138 } else if (value instanceof EObject) {
139 sb.append(createObjectCodeWithDepth((EObject) value, depth - 1));
140 sb.append(',');
141 } else {
142 List<EObject> referencedEObjects = (List<EObject>) value;
143 if (!referencedEObjects.isEmpty()) {
144
145 String[] codes = new String[referencedEObjects.size()];
146 int index = 0;
147 for (EObject referencedEObject : referencedEObjects) {
148 codes[index++] = createObjectCodeWithDepth(referencedEObject, depth - 1);
149 }
150 Arrays.sort(codes);
151 sb.append('(');
152 for (String code : codes) {
153 sb.append(code);
154 }
155 sb.append("),");
156 }
157 }
158 }
159 sb.deleteCharAt(sb.length() - 1);
160 }
161 return sb.toString();
162 }
163
164 @Override
165 public Object createStateCode() {
166
167 refreshObjectCodes();
168
169 StringBuilder sb = new StringBuilder();
170
171 for (EClass eClass : classes) {
172
173 Set<EObject> instances = navigationHelper.getDirectInstances(eClass);
174
175 if (!instances.isEmpty()) {
176
177 sb.append(eClass.getName());
178 sb.append(':');
179
180 String[] codesToSort = new String[instances.size()];
181 int index = 0;
182 Map<EObject, String> codes = objectCodes.get(eClass);
183 for (EObject eObject : instances) {
184 codesToSort[index++] = codes.get(eObject);
185 }
186 Arrays.sort(codesToSort);
187 for (String string : codesToSort) {
188 sb.append(string);
189 sb.append(';');
190 }
191 sb.deleteCharAt(sb.length() - 1);
192 sb.append('|');
193 }
194 }
195 if (sb.length() != 0) {
196 sb.deleteCharAt(sb.length() - 1);
197 }
198 return sb.toString();
199 }
200
201 private void refreshObjectCodes() {
202 for (EObject eObject : deletedClasses) {
203 EClass eClass = eObject.eClass();
204 objectCodes.get(eClass).remove(eObject);
205 }
206 deletedClasses.clear();
207
208 Set<EObject> objectsToRecode = new HashSet<EObject>();
209 for (EObject eObject : changedOrNewEObjects) {
210 objectsToRecode.add(eObject);
211 for (Setting setting : navigationHelper.getInverseReferences(eObject)) {
212 objectsToRecode.add(setting.getEObject());
213 }
214 }
215
216 for (EObject eObject : objectsToRecode) {
217 EClass eClass = eObject.eClass();
218 objectCodes.get(eClass).put(eObject, createObjectCodeWithDepth(eObject, maxDepth));
219 }
220 changedOrNewEObjects.clear();
221 }
222
223 @Override
224 public Object createActivationCode(IPatternMatch match) {
225
226 StringBuilder sb = new StringBuilder();
227 String[] tokens = match.specification().getFullyQualifiedName().split("\\.");
228 sb.append(tokens[tokens.length - 1]);
229 sb.append(':');
230 Object param;
231 for (int i = 0; (param = match.get(i)) != null; i++) {
232 EObject eObject = (EObject) param;
233
234 Collection<EAttribute> attributes = eObject.eClass().getEAllAttributes();
235 for (EAttribute eAttribute : attributes) {
236 Object value = eObject.eGet(eAttribute);
237 sb.append(value);
238 sb.append(',');
239 }
240 if (!attributes.isEmpty()) {
241 sb.deleteCharAt(sb.length() - 1);
242 }
243
244 sb.append('|');
245 }
246 sb.deleteCharAt(sb.length() - 1);
247 return sb.toString().intern();
248 }
249
250}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoderFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoderFactory.java
new file mode 100644
index 00000000..d776e8a8
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoderFactory.java
@@ -0,0 +1,38 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.statecoding.simple;
10
11import java.util.Collection;
12import java.util.HashSet;
13
14import org.eclipse.emf.ecore.EPackage;
15import org.eclipse.viatra.dse.statecode.IStateCoder;
16import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
17import org.eclipse.viatra.dse.util.EMFHelper;
18import org.eclipse.viatra.dse.util.EMFHelper.MetaModelElements;
19
20/**
21 *
22 * @author Andras Szabolcs Nagy
23 *
24 */
25public class SimpleStateCoderFactory implements IStateCoderFactory {
26
27 private MetaModelElements metaModelElements;
28
29 public SimpleStateCoderFactory(Collection<EPackage> metaModelPackages) {
30 metaModelElements = EMFHelper.getAllMetaModelElements(new HashSet<EPackage>(metaModelPackages));
31 }
32
33 @Override
34 public IStateCoder createStateCoder() {
35 return new SimpleStateCoder(metaModelElements);
36 }
37
38}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/EMFHelper.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/EMFHelper.java
new file mode 100644
index 00000000..14b3acfb
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/EMFHelper.java
@@ -0,0 +1,424 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.util;
10
11import java.io.IOException;
12import java.util.Collections;
13import java.util.Comparator;
14import java.util.HashMap;
15import java.util.HashSet;
16import java.util.List;
17import java.util.Map;
18import java.util.Objects;
19import java.util.Set;
20import java.util.TreeSet;
21
22import org.apache.log4j.Logger;
23import org.eclipse.emf.common.command.BasicCommandStack;
24import org.eclipse.emf.common.notify.Notifier;
25import org.eclipse.emf.common.util.EList;
26import org.eclipse.emf.common.util.URI;
27import org.eclipse.emf.ecore.EAttribute;
28import org.eclipse.emf.ecore.EClass;
29import org.eclipse.emf.ecore.EClassifier;
30import org.eclipse.emf.ecore.ENamedElement;
31import org.eclipse.emf.ecore.EObject;
32import org.eclipse.emf.ecore.EPackage;
33import org.eclipse.emf.ecore.EReference;
34import org.eclipse.emf.ecore.resource.Resource;
35import org.eclipse.emf.ecore.resource.ResourceSet;
36import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
37import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
38import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
39import org.eclipse.emf.edit.command.AddCommand;
40import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
41import org.eclipse.emf.edit.domain.EditingDomain;
42import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
43
44/**
45 * This class contains static helper methods.
46 * @author Andras Szabolcs Nagy
47 */
48public final class EMFHelper {
49
50 private static final Logger logger = Logger.getLogger(EMFHelper.class);
51
52 private EMFHelper() {
53 }
54
55 public static class EmfHelperException extends RuntimeException {
56 private static final long serialVersionUID = 7635796550669616626L;
57
58 public EmfHelperException(String string) {
59 super(string);
60 }
61 public EmfHelperException(String string, Throwable e) {
62 super(string, e);
63 }
64 }
65
66 /**
67 * Gets the {@link EditingDomain} of either an {@link EObject}, {@link Resource} or {@link ResourceSet}.
68 * @param notifier The {@link Notifier}.
69 * @return The EditingDomain.
70 */
71 public static EditingDomain getEditingDomain(Notifier notifier) {
72 Objects.requireNonNull(notifier);
73 if (notifier instanceof EObject) {
74 EObject eObject = (EObject) notifier;
75 return AdapterFactoryEditingDomain.getEditingDomainFor(eObject);
76 } else if (notifier instanceof Resource) {
77 Resource resource = (Resource) notifier;
78 EList<EObject> contents = resource.getContents();
79 if (contents.isEmpty()) {
80 return null;
81 }
82 return AdapterFactoryEditingDomain.getEditingDomainFor(contents.get(0));
83 } else if (notifier instanceof ResourceSet) {
84 ResourceSet resourceSet = (ResourceSet) notifier;
85 if (resourceSet.getResources().isEmpty()) {
86 return null;
87 }
88 return getEditingDomain(resourceSet.getResources().get(0));
89 }
90
91 return null;
92 }
93
94 /**
95 * Creates (or gets if already exists) an {@link EditingDomain} over the given {@link Notifier},
96 * either an {@link EObject}, {@link Resource} or {@link ResourceSet}.
97 * @param notifier The {@link Notifier}.
98 * @return The EditingDomain.
99 */
100 public static EditingDomain createEditingDomain(Notifier notifier) {
101
102 EditingDomain domain = getEditingDomain(notifier);
103 if (domain != null) {
104 return domain;
105 }
106
107 registerExtensionForXmiSerializer("dummyext");
108
109 if (notifier instanceof EObject) {
110 EObject eObject = (EObject) notifier;
111
112 domain = new AdapterFactoryEditingDomain(null, new BasicCommandStack());
113 Resource resource = domain.getResourceSet().createResource(URI.createFileURI("dummy.dummyext"));
114 domain.getCommandStack().execute(new AddCommand(domain, resource.getContents(), eObject));
115
116 return domain;
117
118 } else if (notifier instanceof Resource) {
119 Resource resource = (Resource) notifier;
120
121 ResourceSet resourceSet = resource.getResourceSet();
122 if (resourceSet != null) {
123 return new AdapterFactoryEditingDomain(null, new BasicCommandStack(), resourceSet);
124 } else {
125 domain = new AdapterFactoryEditingDomain(null, new BasicCommandStack(), (ResourceSet) null);
126 resourceSet = domain.getResourceSet();
127 domain.getCommandStack().execute(new AddCommand(domain, resourceSet.getResources(), resource));
128 return domain;
129 }
130
131 } else if (notifier instanceof ResourceSet) {
132 return new AdapterFactoryEditingDomain(null, new BasicCommandStack(), (ResourceSet) notifier);
133 } else {
134 throw new EmfHelperException("Not supported argument type.");
135 }
136 }
137
138 /**
139 * Saves the EMF model (EObject or Resource) into the given file. An {@link XMIResourceFactoryImpl} will be
140 * registered if not already.
141 *
142 * Doesn't throw exception but logs an error if the save was unsuccessful.
143 *
144 * @param model Can be an {@link EObject} or a {@link Resource}.
145 * @param fileName
146 */
147 public static void saveModel(Notifier model, String fileName) {
148
149 Objects.requireNonNull(model);
150 Preconditions.checkArgument(fileName != null && !fileName.isEmpty(), "File name is null or empty.");
151
152 int extensionIndex = fileName.lastIndexOf('.');
153
154 Preconditions.checkState(extensionIndex > -1 && extensionIndex != fileName.length() - 1, "Bad file extension.");
155
156 String ext = fileName.substring(extensionIndex + 1);
157
158 registerExtensionForXmiSerializer(ext);
159
160 URI uri = URI.createFileURI(fileName);
161 Resource resource;
162
163 if (model instanceof ResourceSet) {
164 throw new EmfHelperException("Unsupported type: ResourceSet");
165 } else if (model instanceof Resource) {
166 resource = (Resource) model;
167 } else if (model instanceof EObject) {
168 EObject root = (EObject) model;
169 ResourceSet resSet = new ResourceSetImpl();
170 resource = resSet.createResource(uri);
171 resource.getContents().add(root);
172 } else {
173 throw new EmfHelperException("Unkown type: " + model.getClass());
174 }
175
176 resource.setURI(uri);
177 saveResource(resource);
178 }
179
180 private static void saveResource(Resource resource) {
181 try {
182 resource.save(Collections.emptyMap());
183 } catch (IOException e) {
184 logger.error(e);
185 }
186 }
187
188 /**
189 * Loads a model as a {@link Resource}. In headless mode, don't forget to call XYZPackage.eINSTANCE.
190 */
191 public static Resource loadModel(String fileName) throws IOException {
192 Preconditions.checkArgument(fileName != null && !fileName.isEmpty(), "File name is null or empty.");
193 int extensionIndex = fileName.lastIndexOf('.');
194 Preconditions.checkState(extensionIndex > -1 && extensionIndex != fileName.length() - 1, "Bad file extension.");
195
196 String ext = fileName.substring(extensionIndex + 1);
197 registerExtensionForXmiSerializer(ext);
198
199 ResourceSetImpl rSet = new ResourceSetImpl();
200 URI fileUri = URI.createFileURI(fileName);
201 Resource resource = rSet.createResource(fileUri);
202
203 resource.load(null);
204 return resource;
205 }
206
207 /**
208 * Retrieves the root EObject from a Resource or ResourceSet.
209 * <ul>
210 * <li>Returns null if there is no content.</li>
211 * <li>Returns the notifier itself if it is an EObject.</li>
212 * <li>Logs a warn if there are multiple roots.</li>
213 * </ul>
214 *
215 * @param notifier
216 * @return The root EObject or null.
217 */
218 public static EObject getRootEObject(Notifier notifier) {
219 if (notifier instanceof EObject) {
220 return (EObject) notifier;
221 } else if (notifier instanceof Resource) {
222 Resource resource = (Resource) notifier;
223 List<EObject> contents = resource.getContents();
224 if (contents.size() > 1) {
225 logger.warn("Resource has more than one root.");
226 }
227 if (contents.isEmpty()) {
228 return null;
229 } else {
230 return contents.get(0);
231 }
232 } else if (notifier instanceof ResourceSet) {
233 ResourceSet resourceSet = (ResourceSet) notifier;
234 List<Resource> resources = resourceSet.getResources();
235 if (resources.size() > 1) {
236 logger.warn("ResourceSet has more than one resources.");
237 }
238 if (resources.isEmpty()) {
239 return null;
240 } else {
241 return getRootEObject(resources.get(0));
242 }
243 } else {
244 throw new EmfHelperException("Unkown type: " + notifier.getClass());
245 }
246 }
247
248 /**
249 * Registers an {@link XMIResourceFactoryImpl} for the given extension.
250 * @param ext The extension as a String.
251 */
252 public static void registerExtensionForXmiSerializer(String ext) {
253 Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
254 Map<String, Object> m = reg.getExtensionToFactoryMap();
255 m.computeIfAbsent(ext, e -> new XMIResourceFactoryImpl());
256 }
257
258 /**
259 * Clones the given model. Either an {@link EObject}, {@link Resource} or {@link ResourceSet}.
260 * @param notifier The root container of the model.
261 * @return The cloned model.
262 */
263 public static Notifier clone(Notifier notifier) {
264 Copier copier = new Copier();
265 Notifier clonedModel = clone(notifier, copier, null);
266 copier.copyReferences();
267 return clonedModel;
268 }
269
270 private static Notifier clone(Notifier notifier, Copier copier, ResourceSet resourceSetToCloneTo) {
271 Objects.requireNonNull(copier);
272
273 if (notifier instanceof EObject) {
274 EObject eObject = (EObject) notifier;
275 return copier.copy(eObject);
276 } else if (notifier instanceof Resource) {
277 Resource resource = (Resource) notifier;
278 ResourceSet rSetTemp = resourceSetToCloneTo;
279 if (resourceSetToCloneTo == null) {
280 rSetTemp = new ResourceSetImpl();
281 }
282 Resource clonedResource = rSetTemp.createResource(URI.createFileURI("dummy.dummyext"));
283
284 for (EObject eObject : resource.getContents()) {
285 EObject clonedEObject = copier.copy(eObject);
286 clonedResource.getContents().add(clonedEObject);
287 }
288
289 return clonedResource;
290 } else if (notifier instanceof ResourceSet) {
291 ResourceSet resourceSet = (ResourceSet) notifier;
292 ResourceSetImpl clonedResourceSet = new ResourceSetImpl();
293
294 for (Resource resource : resourceSet.getResources()) {
295 clone(resource, copier, clonedResourceSet);
296 }
297
298 return clonedResourceSet;
299 } else {
300 throw new EmfHelperException("Not supported argument type.");
301 }
302 }
303
304 public static class ENamedElementComparator implements Comparator<ENamedElement> {
305 @Override
306 public int compare(ENamedElement eClass1, ENamedElement eClass2) {
307 return eClass1.getName().compareTo(eClass2.getName());
308 }
309 }
310
311 /**
312 * This class is used to store
313 * <ul>
314 * <li>{@link EClass}es,</li>
315 * <li>{@link EAttribute}s,</li>
316 * <li>{@link EReference}s,</li>
317 * <li>EAttributes by EClasses,</li>
318 * <li>EReferences by EClasses</li>
319 * </ul>
320 * for a given set of {@link EPackage}s.
321 *
322 */
323 public static class MetaModelElements {
324 public Set<EPackage> metaModelPackages;
325 public Set<EClass> classes;
326 public Set<EAttribute> attributes;
327 public Set<EReference> references;
328 public Map<EClass, Set<EAttribute>> attributesOfClass;
329 public Map<EClass, Set<EReference>> referencesOfClass;
330 }
331
332 /**
333 * Traverses the full metamodel on the given {@link EPackage}s and returns all the classes, attributes and
334 * references it contains.
335 *
336 * @param metaModelPackages
337 * The set of {@link EPackage}s.
338 * @return A {@link MetaModelElements} instance containing the metamodel elements.
339 */
340 public static MetaModelElements getAllMetaModelElements(Set<EPackage> metaModelPackages) {
341 return getMetaModelElements(metaModelPackages, true, true, true);
342 }
343
344 /**
345 * Return a {@link MetaModelElements} instance populated with its {@link MetaModelElements#classes}.
346 *
347 * @param metaModelPackages
348 * The set of {@link EPackage}s.
349 * @return AA {@link MetaModelElements} instance.
350 */
351 public static MetaModelElements getClasses(Set<EPackage> metaModelPackages) {
352 return getMetaModelElements(metaModelPackages, true, false, false);
353 }
354
355 /**
356 * Return a {@link MetaModelElements} instance populated with its {@link MetaModelElements#references} and
357 * {@link MetaModelElements#referencesOfClass}.
358 *
359 * @param metaModelPackages
360 * The set of {@link EPackage}s.
361 * @return AA {@link MetaModelElements} instance.
362 */
363 public static MetaModelElements getReferences(Set<EPackage> metaModelPackages) {
364 return getMetaModelElements(metaModelPackages, false, true, false);
365 }
366
367 /**
368 * Return a {@link MetaModelElements} instance populated with its {@link MetaModelElements#attributes} and
369 * {@link MetaModelElements#attributesOfClass}.
370 *
371 * @param metaModelPackages
372 * The set of {@link EPackage}s.
373 * @return AA {@link MetaModelElements} instance.
374 */
375 public static MetaModelElements getAttrbiutes(Set<EPackage> metaModelPackages) {
376 return getMetaModelElements(metaModelPackages, false, false, true);
377 }
378
379 private static MetaModelElements getMetaModelElements(Set<EPackage> metaModelPackages, boolean getClasses,
380 boolean getReferences, boolean getAttrbiutes) {
381
382 Comparator<ENamedElement> comparator = new ENamedElementComparator();
383
384 MetaModelElements result = new MetaModelElements();
385 result.metaModelPackages = metaModelPackages;
386 if (getClasses) {
387 result.classes = new TreeSet<EClass>(comparator);
388 }
389 if (getReferences) {
390 result.references = new HashSet<EReference>();
391 result.referencesOfClass = new HashMap<EClass, Set<EReference>>();
392 }
393 if (getAttrbiutes) {
394 result.attributes = new HashSet<EAttribute>();
395 result.attributesOfClass = new HashMap<EClass, Set<EAttribute>>();
396 }
397 for (EPackage ePackage : metaModelPackages) {
398 for (EClassifier eClassifier : ePackage.getEClassifiers()) {
399 if (eClassifier instanceof EClass) {
400 EClass eClass = ((EClass) eClassifier);
401 if (getClasses) {
402 result.classes.add(eClass);
403 }
404 if (getReferences) {
405 result.referencesOfClass.put(eClass, new TreeSet<EReference>(comparator));
406 for (EReference eReference : eClass.getEAllReferences()) {
407 result.references.add(eReference);
408 result.referencesOfClass.get(eClass).add(eReference);
409 }
410 }
411 if (getAttrbiutes) {
412 result.attributesOfClass.put(eClass, new TreeSet<EAttribute>(comparator));
413 for (EAttribute eAttribute : eClass.getEAllAttributes()) {
414 result.attributes.add(eAttribute);
415 result.attributesOfClass.get(eClass).add(eAttribute);
416 }
417 }
418 }
419 }
420 }
421 return result;
422 }
423
424}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/Hasher.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/Hasher.java
new file mode 100644
index 00000000..0c5d7eba
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/Hasher.java
@@ -0,0 +1,86 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.util;
10
11import java.math.BigInteger;
12import java.security.MessageDigest;
13import java.security.NoSuchAlgorithmException;
14
15import org.eclipse.viatra.dse.api.DSEException;
16
17/**
18 * Utility class that encapsulates a {@link MessageDigest} instance to aid calculating hash values more easily, and to
19 * reuse a {@link MessageDigest} instance.
20 *
21 */
22public final class Hasher {
23 private MessageDigest md;
24
25 private static final int HEX = 16;
26
27 private Hasher(MessageDigest md) {
28 this.md = md;
29 }
30
31 /**
32 * Calculates and returns a hash value.
33 *
34 * @param data
35 * the data to be hashed in a {@link String}.
36 * @return the hash value in some {@link String} representation.
37 */
38 public String hash(String data) {
39 md.update(data.getBytes(), 0, data.length());
40 return new String(md.digest());
41 }
42
43 @SuppressWarnings("unused")
44 private String alternateHashBest(String data) {
45 md.update(data.getBytes(), 0, data.length());
46 return new String(md.digest());
47 }
48
49 @SuppressWarnings("unused")
50 private String alternateHashSecondBest(String data) {
51 md.update(data.getBytes(), 0, data.length());
52 return new BigInteger(1, md.digest()).toString(HEX);
53 }
54
55 @SuppressWarnings("unused")
56 private String alternateHashThirdBest(String data) {
57 md.update(data.getBytes(), 0, data.length());
58 byte[] array = md.digest();
59 StringBuilder sb = new StringBuilder();
60 for (int i = 0; i < array.length; i++) {
61 sb.append(Integer.toHexString((int) array[i]));
62 }
63 return sb.toString();
64 }
65
66 /**
67 * Returns a {@link Hasher} with an internal {@link MessageDigest} that is based on the protocol named
68 * {@code protocoll}.
69 *
70 * @param protocoll
71 * the name of the hash algorythm.
72 * @return the initialized {@link Hasher}
73 *
74 * @throws DSEException
75 * on initialization failure.
76 */
77 public static Hasher getHasher(String protocoll) {
78 try {
79 return new Hasher(MessageDigest.getInstance(protocoll));
80 } catch (NoSuchAlgorithmException e) {
81 throw new DSEException(e);
82 }
83 }
84
85 public static final String SHA1_PROTOCOLL = "SHA-1";
86}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/ValueComparableEObjectStringMap.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/ValueComparableEObjectStringMap.java
new file mode 100644
index 00000000..49af05d1
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/util/ValueComparableEObjectStringMap.java
@@ -0,0 +1,63 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.util;
10
11import java.util.Comparator;
12import java.util.HashMap;
13import java.util.Map;
14import java.util.TreeMap;
15
16import org.eclipse.emf.ecore.EObject;
17
18import com.google.common.base.Functions;
19import com.google.common.collect.Ordering;
20
21/**
22 *
23 * This custom {@link TreeMap} implementation enables to store {@link EObject}-{@link String} pairs sorted by values
24 * (strings). It works as expected if the map is modified in any way, hence the map will still be sorted by values on
25 * the new set of entries.
26 *
27 * It is allowed to have two entries with the same EObject key (and also with same values).
28 *
29 * The short coming of the class is that EObjects are compared to each other by their
30 * {@link System#identityHashCode(Object)}, which may lead to unexpected errors.
31 *
32 * @author Andras Szabolcs Nagy
33 *
34 */
35public class ValueComparableEObjectStringMap extends TreeMap<EObject, String> {
36
37 private static final class EObjectComparator implements Comparator<EObject> {
38 @Override
39 public int compare(EObject o1, EObject o2) {
40 return Integer.valueOf(System.identityHashCode(o1)).compareTo(Integer.valueOf(System.identityHashCode(o2)));
41 }
42 }
43
44 private final Map<EObject, String> innerMap;
45
46 public ValueComparableEObjectStringMap() {
47 this(new HashMap<EObject, String>());
48 }
49
50 private ValueComparableEObjectStringMap(Map<EObject, String> innerMap) {
51 super(Ordering.natural().onResultOf(Functions.forMap(innerMap)).compound(new EObjectComparator()));
52 this.innerMap = innerMap;
53 }
54
55 @Override
56 public String put(EObject keyEObject, String stringValue) {
57 if (innerMap.containsKey(keyEObject)) {
58 remove(keyEObject);
59 }
60 innerMap.put(keyEObject, stringValue);
61 return super.put(keyEObject, stringValue);
62 }
63}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/DesignSpaceVisualizerOptions.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/DesignSpaceVisualizerOptions.java
new file mode 100644
index 00000000..bb8000d5
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/DesignSpaceVisualizerOptions.java
@@ -0,0 +1,56 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.visualizer;
10
11public class DesignSpaceVisualizerOptions {
12
13 public boolean showExplorationTrace = true;
14 public boolean showStateCodes = true;
15 public boolean showTransitionCodes = true;
16
17 public DesignSpaceVisualizerOptions withOutExploraionTrace() {
18 showExplorationTrace = false;
19 return this;
20 }
21
22 public DesignSpaceVisualizerOptions withOutstateCodes() {
23 showStateCodes = false;
24 return this;
25 }
26
27 public DesignSpaceVisualizerOptions withOutTransitionCodes() {
28 showTransitionCodes = false;
29 return this;
30 }
31
32 public boolean isShowExplorationTrace() {
33 return showExplorationTrace;
34 }
35
36 public void setShowExplorationTrace(boolean showExplorationTrace) {
37 this.showExplorationTrace = showExplorationTrace;
38 }
39
40 public boolean isShowStateCodes() {
41 return showStateCodes;
42 }
43
44 public void setShowStateCodes(boolean showStateCodes) {
45 this.showStateCodes = showStateCodes;
46 }
47
48 public boolean isShowTransitionCodes() {
49 return showTransitionCodes;
50 }
51
52 public void setShowTransitionCodes(boolean showTransitionCodes) {
53 this.showTransitionCodes = showTransitionCodes;
54 }
55
56}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IDesignSpaceVisualizer.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IDesignSpaceVisualizer.java
new file mode 100644
index 00000000..da598b91
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IDesignSpaceVisualizer.java
@@ -0,0 +1,39 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.visualizer;
10
11import org.eclipse.viatra.dse.api.DesignSpaceExplorer;
12import org.eclipse.viatra.dse.base.ThreadContext;
13
14/**
15 *
16 * An implementation of this interface is notified about the traversal of the design space from every traversing thread,
17 * if registered to the {@link DesignSpaceExplorer}. Its purpose is to able to visualize the design space (a directed
18 * graph with IDs of the nodes and transitions) and to able to visualize the order of the exploration (the trace of a
19 * thread).
20 *
21 * @author Andras Szabolcs Nagy
22 *
23 */
24public interface IDesignSpaceVisualizer extends IExploreEventHandler {
25
26 /**
27 * Initializes the instance with a starting thread's context. Can be called multiple times and concurrently.
28 *
29 * @see DesignSpaceVisualizerOptions
30 * @param context
31 */
32 void init(ThreadContext context);
33
34 /**
35 * Saves the captured data.
36 */
37 void save();
38
39}
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IExploreEventHandler.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IExploreEventHandler.java
new file mode 100644
index 00000000..9f902f31
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/visualizer/IExploreEventHandler.java
@@ -0,0 +1,40 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.visualizer;
10
11import org.eclipse.viatra.dse.base.DesignSpaceManager;
12
13/**
14 * An implementation of this interface is notified about every move in the design space (firing a rule activation or
15 * undoing it) of a single thread, if registered to the corresponding {@link DesignSpaceManager}. Its methods are called
16 * synchronously, therefore the implementation can have an impact on the performance. Also note, if the same instance is
17 * registered to multiple threads ({@link DesignSpaceManager}), it has to be thread safe.
18 *
19 * @author Andras Szabolcs Nagy
20 *
21 */
22public interface IExploreEventHandler {
23
24 /**
25 * Called by the {@link DesignSpaceManager}, after a rule activation (transition) is fired. Multiple calls with the
26 * same transition can occur.
27 *
28 * @param transition The fired transition.
29 */
30 void transitionFired(Object transition);
31
32 /**
33 * Called by the {@link DesignSpaceManager}, after undoing the previously fired rule activation (transition).
34 * Multiple calls with the same transition can occur.
35 *
36 * @param transition The undone transition.
37 */
38 void undo(Object transition);
39
40}