From 7c7e26beb80073d049eb5e4b896fa290c016b0c9 Mon Sep 17 00:00:00 2001 From: Oszkar Semerath Date: Fri, 1 May 2020 01:45:22 +0200 Subject: missing commit --- .../rules/RefinementRuleProvider.xtend | 459 +++++++++++++++++---- 1 file changed, 376 insertions(+), 83 deletions(-) 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..013da873 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,71 +1,94 @@ package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules +import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.InverseRelationAssertion +import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.LowerMultiplicityAssertion +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntTypeReference import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.LogiclanguageFactory +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.PrimitiveTypeReference +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference 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.StringTypeReference import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type +import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.ObjectCreationPrecondition +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialBooleanInterpretation import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialIntegerInterpretation import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRealInterpretation import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialStringInterpretation +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory +import java.util.HashMap import java.util.LinkedHashMap +import java.util.LinkedList +import java.util.List +import java.util.Map import org.eclipse.viatra.query.runtime.api.GenericPatternMatch import org.eclipse.viatra.query.runtime.api.IQuerySpecification import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRuleFactory +import org.eclipse.xtend.lib.annotations.Data +import org.eclipse.xtext.xbase.lib.Functions.Function0 class RefinementRuleProvider { - private extension BatchTransformationRuleFactory factory = new BatchTransformationRuleFactory - private extension PartialinterpretationFactory factory2 = PartialinterpretationFactory.eINSTANCE - private extension LogiclanguageFactory factory3 = LogiclanguageFactory.eINSTANCE + val extension BatchTransformationRuleFactory factory = new BatchTransformationRuleFactory + val extension PartialinterpretationFactory factory2 = PartialinterpretationFactory.eINSTANCE + val extension LogiclanguageFactory factory3 = LogiclanguageFactory.eINSTANCE def canonizeName(String name) { return name.replace(' ','_') } - def LinkedHashMap>> - createObjectRefinementRules( + def LinkedHashMap>> createObjectRefinementRules( + LogicProblem p, + PartialInterpretation i, GeneratedPatterns patterns, ScopePropagator scopePropagator, boolean nameNewElement, ModelGenerationStatistics statistics ) - { + { val res = new LinkedHashMap + val recursiveObjectCreation = recursiveObjectCreation(p,i) for(LHSEntry: patterns.refineObjectQueries.entrySet) { val containmentRelation = LHSEntry.key.containmentRelation val inverseRelation = LHSEntry.key.inverseContainment val type = LHSEntry.key.newType val lhs = LHSEntry.value as IQuerySpecification> - val rule = createObjectCreationRule(containmentRelation,inverseRelation,type,lhs,nameNewElement,scopePropagator,statistics) + val rule = createObjectCreationRule(p,containmentRelation,inverseRelation,type,recursiveObjectCreation.get(type),lhs,nameNewElement,scopePropagator,statistics) res.put(LHSEntry.key,rule) } return res } def private createObjectCreationRule( + LogicProblem p, Relation containmentRelation, Relation inverseRelation, Type type, + List recursiceObjectCreations, IQuerySpecification> lhs, boolean nameNewElement, ScopePropagator scopePropagator, ModelGenerationStatistics statistics) { val name = '''addObject_«type.name.canonizeName»« - IF containmentRelation!=null»_by_«containmentRelation.name.canonizeName»«ENDIF»''' - //println("Rule created: " + name + "> " + lhs.fullyQualifiedName) + IF containmentRelation!==null»_by_«containmentRelation.name.canonizeName»«ENDIF»''' val ruleBuilder = factory.createRule .name(name) .precondition(lhs) - if(containmentRelation != null) { - if(inverseRelation!= null) { + if(containmentRelation !== null) { + if(inverseRelation!== null) { ruleBuilder.action[match | //println(name) val startTime = System.nanoTime @@ -76,30 +99,17 @@ class RefinementRuleProvider { val typeInterpretation = match.get(4) as PartialComplexTypeInterpretation val container = match.get(5) as DefinedElement - val newElement = createDefinedElement - if(nameNewElement) { - newElement.name = '''new «interpretation.newElements.size»''' - } - - // Existence - interpretation.newElements+=newElement - /*interpretation.maxNewElements=interpretation.maxNewElements-1 - if(interpretation.minNewElements > 0) { - interpretation.minNewElements=interpretation.minNewElements-1 - }*/ - - // Types - typeInterpretation.elements += newElement - typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] - // ContainmentRelation - val newLink1 = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] - relationInterpretation.relationlinks+=newLink1 - // Inverse Containment - val newLink2 = factory2.createBinaryElementRelationLink => [it.param1 = newElement it.param2 = container] - inverseRelationInterpretation.relationlinks+=newLink2 - - // Scope propagation - scopePropagator.propagateAdditionToType(typeInterpretation) + createObjectActionWithContainmentAndInverse( + nameNewElement, + interpretation, + typeInterpretation, + container, + relationInterpretation, + inverseRelationInterpretation, + [createDefinedElement], + recursiceObjectCreations, + scopePropagator + ) statistics.addExecutionTime(System.nanoTime-startTime) ] @@ -113,27 +123,16 @@ class RefinementRuleProvider { val typeInterpretation = match.get(3) as PartialComplexTypeInterpretation val container = match.get(4) as DefinedElement - val newElement = createDefinedElement - if(nameNewElement) { - newElement.name = '''new «interpretation.newElements.size»''' - } - - // Existence - interpretation.newElements+=newElement - /*interpretation.maxNewElements=interpretation.maxNewElements-1 - if(interpretation.minNewElements > 0) { - interpretation.minNewElements=interpretation.minNewElements-1 - }*/ - - // Types - typeInterpretation.elements += newElement - typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] - // ContainmentRelation - val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] - relationInterpretation.relationlinks+=newLink - - // Scope propagation - scopePropagator.propagateAdditionToType(typeInterpretation) + createObjectActionWithContainment( + nameNewElement, + interpretation, + typeInterpretation, + container, + relationInterpretation, + [createDefinedElement], + recursiceObjectCreations, + scopePropagator + ) statistics.addExecutionTime(System.nanoTime-startTime) ] @@ -145,25 +144,14 @@ class RefinementRuleProvider { val interpretation = match.get(1) as PartialInterpretation val typeInterpretation = match.get(2) as PartialComplexTypeInterpretation - val newElement = createDefinedElement - if(nameNewElement) { - newElement.name = '''new «interpretation.newElements.size»''' - } - - // Existence - interpretation.newElements+=newElement - /* - interpretation.maxNewElements=interpretation.maxNewElements-1 - if(interpretation.minNewElements > 0) { - interpretation.minNewElements=interpretation.minNewElements-1 - }*/ - - // Types - typeInterpretation.elements += newElement - typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] - - // Scope propagation - scopePropagator.propagateAdditionToType(typeInterpretation) + createObjectAction( + nameNewElement, + interpretation, + typeInterpretation, + [createDefinedElement], + recursiceObjectCreations, + scopePropagator + ) statistics.addExecutionTime(System.nanoTime-startTime) ] @@ -171,6 +159,137 @@ class RefinementRuleProvider { return ruleBuilder.build } + def private recursiveObjectCreation(LogicProblem p, PartialInterpretation i) + { + val Map> recursiveObjectCreation = new HashMap + for(type : p.types) { + recursiveObjectCreation.put(type,new LinkedList) + } + + val containmentReferences = p.containmentHierarchies.head.containmentRelations + + for(relationInterpretation : i.partialrelationinterpretation) { + val relation = relationInterpretation.interpretationOf + val lowermultiplicities = p.annotations.filter(LowerMultiplicityAssertion).filter[it.relation === relation] + if((!lowermultiplicities.empty)) { + val number = lowermultiplicities.head.lower + if(number > 0) { + val sourceTypeInterpretation = getTypeInterpretation(i, relation, 0) as PartialComplexTypeInterpretation + + if(containmentReferences.contains(relation)) { + val targetTypeInterpretation = getTypeInterpretation(i, relation, 1) + + val inverseAnnotation = p.assertions.filter(InverseRelationAssertion).filter[it.inverseA === relation || it.inverseB === relation] + if(!inverseAnnotation.empty) { + val onlyInverseAnnotation = if(inverseAnnotation.head.inverseA===relation) { + inverseAnnotation.head.inverseB + } else { + inverseAnnotation.head.inverseA + } + val inverseRelationInterpretation = i.partialrelationinterpretation.filter[it.interpretationOf === onlyInverseAnnotation].head + for(var times=0; times getTypeConstructor(PartialComplexTypeInterpretation reference) { [createDefinedElement] } + private dispatch def Function0 getTypeConstructor(PartialBooleanInterpretation reference) { [createBooleanElement] } + private dispatch def Function0 getTypeConstructor(PartialIntegerInterpretation reference) { [createIntegerElement] } + private dispatch def Function0 getTypeConstructor(PartialRealInterpretation reference) { [createRealElement] } + private dispatch def Function0 getTypeConstructor(PartialStringInterpretation reference) { [createStringElement] } + + def createRelationRefinementRules(GeneratedPatterns patterns, ModelGenerationStatistics statistics) { val res = new LinkedHashMap for(LHSEntry: patterns.refinerelationQueries.entrySet) { @@ -186,11 +305,11 @@ class RefinementRuleProvider { def private BatchTransformationRule> createRelationRefinementRule(RelationDeclaration declaration, Relation inverseRelation, IQuerySpecification> lhs, ModelGenerationStatistics statistics) { - val name = '''addRelation_«declaration.name.canonizeName»«IF inverseRelation != null»_and_«inverseRelation.name.canonizeName»«ENDIF»''' + val name = '''addRelation_«declaration.name.canonizeName»«IF inverseRelation !== null»_and_«inverseRelation.name.canonizeName»«ENDIF»''' val ruleBuilder = factory.createRule .name(name) .precondition(lhs) - if (inverseRelation == null) { + if (inverseRelation === null) { ruleBuilder.action [ match | val startTime = System.nanoTime //println(name) @@ -199,8 +318,7 @@ class RefinementRuleProvider { val relationInterpretation = match.get(2) as PartialRelationInterpretation val src = match.get(3) as DefinedElement val trg = match.get(4) as DefinedElement - val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] - relationInterpretation.relationlinks += link + createRelationLinkAction(src, trg, relationInterpretation) statistics.addExecutionTime(System.nanoTime-startTime) ] } else { @@ -213,14 +331,189 @@ class RefinementRuleProvider { val inverseInterpretation = match.get(3) as PartialRelationInterpretation val src = match.get(4) as DefinedElement val trg = match.get(5) as DefinedElement - val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] - relationInterpretation.relationlinks += link - val inverseLink = createBinaryElementRelationLink => [it.param1 = trg it.param2 = src] - inverseInterpretation.relationlinks += inverseLink + createRelationLinkWithInverse(src, trg, relationInterpretation, inverseInterpretation) statistics.addExecutionTime(System.nanoTime-startTime) ] } return ruleBuilder.build } + + ///////////////////////// + // Actions + ///////////////////////// + + protected def void createObjectAction(boolean nameNewElement, ObjectCreationInterpretationData data, DefinedElement container, ScopePropagator scopePropagator) { + if(data.containerInterpretation !== null) { + if(data.containerInverseInterpretation !== null) { + createObjectActionWithContainmentAndInverse( + nameNewElement, + data.interpretation, + data.typeInterpretation, + container, + data.containerInterpretation, + data.containerInverseInterpretation, + data.constructor, + data.recursiveConstructors, + scopePropagator + ) + } else { + createObjectActionWithContainment( + nameNewElement, + data.interpretation, + data.typeInterpretation, + container, + data.containerInterpretation, + data.constructor, + data.recursiveConstructors, + scopePropagator + ) + } + } else { + createObjectAction( + nameNewElement, + data.interpretation, + data.typeInterpretation, + data.constructor, + data.recursiveConstructors, + scopePropagator + ) + } + + } + + protected def createObjectActionWithContainmentAndInverse( + boolean nameNewElement, + PartialInterpretation interpretation, + PartialTypeInterpratation typeInterpretation, + DefinedElement container, + PartialRelationInterpretation relationInterpretation, + PartialRelationInterpretation inverseRelationInterpretation, + Function0 constructor, + List recursiceObjectCreations, + ScopePropagator scopePropagator + ) { + val newElement = constructor.apply + if(nameNewElement) { + newElement.name = '''new «interpretation.newElements.size»''' + } + + // Existence + interpretation.newElements+=newElement + + // Types + typeInterpretation.elements += newElement + if(typeInterpretation instanceof PartialComplexTypeInterpretation) { + typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] + } + // ContainmentRelation + val newLink1 = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] + relationInterpretation.relationlinks+=newLink1 + // Inverse Containment + val newLink2 = factory2.createBinaryElementRelationLink => [it.param1 = newElement it.param2 = container] + inverseRelationInterpretation.relationlinks+=newLink2 + + // Do recursive object creation + for(newConstructor : recursiceObjectCreations) { + createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) + } + + // Scope propagation + scopePropagator.propagateAdditionToType(typeInterpretation) + + return newElement + } + + protected def createObjectActionWithContainment( + boolean nameNewElement, + PartialInterpretation interpretation, + PartialTypeInterpratation typeInterpretation, + DefinedElement container, + PartialRelationInterpretation relationInterpretation, + Function0 constructor, + List recursiceObjectCreations, + ScopePropagator scopePropagator + ) { + val newElement = constructor.apply + if(nameNewElement) { + newElement.name = '''new «interpretation.newElements.size»''' + } + + // Existence + interpretation.newElements+=newElement + + // Types + typeInterpretation.elements += newElement + if(typeInterpretation instanceof PartialComplexTypeInterpretation) { + typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] + } + // ContainmentRelation + val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] + relationInterpretation.relationlinks+=newLink + + // Do recursive object creation + for(newConstructor : recursiceObjectCreations) { + createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) + } + + // Scope propagation + scopePropagator.propagateAdditionToType(typeInterpretation) + + return newElement + } + + protected def createObjectAction( + boolean nameNewElement, + PartialInterpretation interpretation, + PartialTypeInterpratation typeInterpretation, + Function0 constructor, + List recursiceObjectCreations, + ScopePropagator scopePropagator) + { + val newElement = constructor.apply + if(nameNewElement) { + newElement.name = '''new «interpretation.newElements.size»''' + } + + // Existence + interpretation.newElements+=newElement + + // Types + typeInterpretation.elements += newElement + if(typeInterpretation instanceof PartialComplexTypeInterpretation) { + typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] + } + + // Do recursive object creation + for(newConstructor : recursiceObjectCreations) { + createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) + } + + // Scope propagation + scopePropagator.propagateAdditionToType(typeInterpretation) + + return newElement + } + + protected def boolean createRelationLinkAction(DefinedElement src, DefinedElement trg, PartialRelationInterpretation relationInterpretation) { + val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] + relationInterpretation.relationlinks += link + } + + protected def boolean createRelationLinkWithInverse(DefinedElement src, DefinedElement trg, PartialRelationInterpretation relationInterpretation, PartialRelationInterpretation inverseInterpretation) { + val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] + relationInterpretation.relationlinks += link + val inverseLink = createBinaryElementRelationLink => [it.param1 = trg it.param2 = src] + inverseInterpretation.relationlinks += inverseLink + } +} + +@Data +class ObjectCreationInterpretationData { + PartialInterpretation interpretation + PartialTypeInterpratation typeInterpretation + PartialRelationInterpretation containerInterpretation + PartialRelationInterpretation containerInverseInterpretation + Function0 constructor + List recursiveConstructors = new LinkedList } -- cgit v1.2.3-54-g00ecf