From 60f01f46ba232ed6416054f0a6115cb2a9b70b4e Mon Sep 17 00:00:00 2001 From: OszkarSemerath Date: Sat, 10 Jun 2017 19:05:05 +0200 Subject: Migrating Additional projects --- .../patterns/RelationDeclarationIndexer.xtend | 154 +++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDeclarationIndexer.xtend (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDeclarationIndexer.xtend') 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 new file mode 100644 index 00000000..e6d92cc6 --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDeclarationIndexer.xtend @@ -0,0 +1,154 @@ +package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns + +import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.UpperMultiplicityAssertion +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeReference +import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem +import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality +import java.util.HashMap +import java.util.List +import java.util.Map +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery + +import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* + +class RelationDeclarationIndexer { + val PatternGenerator base; + + new(PatternGenerator base) { + this.base = base + } + + public def generateRelationIndexers(LogicProblem problem, Iterable relations, Map fqn2PQuery) { + val upperMultiplicities = new HashMap + problem.annotations.filter(UpperMultiplicityAssertion).forEach[ + upperMultiplicities.put(it.relation,it.upper) + ] + + return ''' + «FOR relation : relations» + «IF base.isDerived(relation)» + «generateDerivedMustRelation(problem,relation,base.getDerivedDefinition(relation).patternFullyQualifiedName.lookup(fqn2PQuery))» + «generateDerivedMayRelation(problem,relation,base.getDerivedDefinition(relation).patternFullyQualifiedName.lookup(fqn2PQuery))» + «ELSE» + «generateMustRelation(problem,relation)» + «generateMayRelation(problem,relation,upperMultiplicities,base.getContainments(problem),base.getInverseRelations(problem),fqn2PQuery)» + «ENDIF» + «ENDFOR» + ''' + } + + def private patternName(RelationDeclaration r, Modality modality) { + '''«modality.name.toLowerCase»InRelation«base.canonizeName(r.name)»''' + } + + public def referRelation( + RelationDeclaration referred, + String sourceVariable, + String targetVariable, + Modality modality) + '''find «referred.patternName(modality)»(problem,interpretation,«sourceVariable»,«targetVariable»);''' + + def generateMustRelation(LogicProblem problem, RelationDeclaration relation) ''' + /** + * Matcher for detecting tuples t where []«relation.name»(source,target) + */ + private pattern «relation.patternName(Modality.MUST)»( + problem:LogicProblem, interpretation:PartialInterpretation, + source: DefinedElement, target:DefinedElement) + { + find interpretation(problem,interpretation); + PartialInterpretation.partialrelationinterpretation(interpretation,relationIterpretation); + PartialRelationInterpretation.interpretationOf.name(relationIterpretation,"«relation.name»"); + PartialRelationInterpretation.relationlinks(relationIterpretation,link); + BinaryElementRelationLink.param1(link,source); + BinaryElementRelationLink.param2(link,target); + } + ''' + def generateMayRelation(LogicProblem problem, RelationDeclaration relation, + Map upperMultiplicities, + List containments, + HashMap inverseRelations, + Map fqn2PQuery) + { + return ''' + /** + * Matcher for detecting tuples t where <>«relation.name»(source,target) + */ + private pattern «relation.patternName(Modality.MAY)»( + problem:LogicProblem, interpretation:PartialInterpretation, + source: DefinedElement, target:DefinedElement) + { + find interpretation(problem,interpretation); + // The two endpoint of the link have to exist + find mayExist(problem, interpretation, source); + find mayExist(problem, interpretation, target); + // Type consistency + «transformTypeConsistency(relation.parameters.get(0),"source")» + «transformTypeConsistency(relation.parameters.get(1),"target")» + «IF upperMultiplicities.containsKey(relation)» + // There are "numberOfExistingReferences" currently existing instances of the reference from the source, + // the upper bound of the multiplicity should be considered. + numberOfExistingReferences == count «referRelation(relation,"source","_",Modality.MUST)» + check(numberOfExistingReferences < «upperMultiplicities.get(relation)»); + «ENDIF» + «IF inverseRelations.containsKey(relation) && upperMultiplicities.containsKey(inverseRelations.get(relation))» + // There are "numberOfExistingReferences" currently existing instances of the reference to the target, + // the upper bound of the opposite reference multiplicity should be considered. + numberOfExistingOppositeReferences == count «base.referRelation(inverseRelations.get(relation),"target","_",Modality.MUST,fqn2PQuery)» + check(numberOfExistingOppositeReferences < «upperMultiplicities.get(inverseRelations.get(relation))»); + «ENDIF» + «IF containments.contains(relation)» + // The reference is containment, then a new reference cannot be create if: + // 1. Multiple parents + neg «base.containmentIndexer.referMustContaint("_","target")» + // 2. Circle in the containment hierarchy + neg «base.containmentIndexer.referTransitiveMustContains("target","source")» + «ENDIF» + «IF inverseRelations.containsKey(relation) && containments.contains(inverseRelations.get(relation))» + // The eOpposite of the reference is containment, then a referene cannot be created if + // 1. Multiple parents + neg «base.containmentIndexer.referMustContaint("source","_")» + // 2. Circle in the containment hierarchy + neg «base.containmentIndexer.referTransitiveMustContains("source","target")» + «ENDIF» + } or { + «relation.referRelation("source","target",Modality.MUST)» + } + ''' + } + + def generateDerivedMustRelation(LogicProblem problem, RelationDeclaration relation, PQuery definition) ''' + /** + * Matcher for detecting tuples t where []«relation.name»(source,target) + */ + private pattern «relation.patternName(Modality.MUST)»( + problem:LogicProblem, interpretation:PartialInterpretation, + source: DefinedElement, target:DefinedElement) + { + «base.relationDefinitionIndexer.referPattern(definition,#["source","target"],Modality::MUST,true,false)» + } + ''' + def generateDerivedMayRelation(LogicProblem problem, RelationDeclaration relation, PQuery definition) ''' + /** + * Matcher for detecting tuples t where []«relation.name»(source,target) + */ + private pattern «relation.patternName(Modality.MAY)»( + problem:LogicProblem, interpretation:PartialInterpretation, + source: DefinedElement, target:DefinedElement) + { + «base.relationDefinitionIndexer.referPattern(definition,#["source","target"],Modality::MAY,true,false)» + } + ''' + + protected def CharSequence transformTypeConsistency(TypeReference reference, String name) { + if(reference instanceof ComplexTypeReference) { + this.base.typeIndexer.referInstanceOf(reference.referred,Modality.MAY,name) + } else { + return '''// Primitive type of «name» is already enforced''' + } + + } +} \ No newline at end of file -- cgit v1.2.3-54-g00ecf