From 59a53fc819355fb2809b23544a5ca19ffff802fb Mon Sep 17 00:00:00 2001 From: OszkarSemerath Date: Mon, 16 Jul 2018 18:25:34 +0200 Subject: Scope support for attributes --- .../application/execution/ScopeLoader.xtend | 171 ++++++++++++++++++--- 1 file changed, 146 insertions(+), 25 deletions(-) (limited to 'Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/ScopeLoader.xtend') diff --git a/Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/ScopeLoader.xtend b/Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/ScopeLoader.xtend index ee1a92f0..9b2b4a3e 100644 --- a/Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/ScopeLoader.xtend +++ b/Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/ScopeLoader.xtend @@ -14,49 +14,172 @@ import hu.bme.mit.inf.dslreasoner.application.applicationConfiguration.StringTyp import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic_Trace import hu.bme.mit.inf.dslreasoner.logic.model.builder.TypeScopes +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDefinition import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partial2logicannotations.PartialModelRelation2Assertion +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.IntegerElement +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.NaryRelationLink +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PrimitiveElement +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.RealElement +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.StringElement +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.UnaryElementRelationLink +import java.math.BigDecimal +import java.util.HashMap +import java.util.LinkedList +import java.util.List +import java.util.Map +import java.util.Set import org.eclipse.emf.ecore.EClass +import org.eclipse.xtend.lib.annotations.Data + +import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntLiteral +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealLiteral +import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.StringLiteral + +@Data class KnownElements { + val Map> knownElementsByType + val Set knownIntegers + val Set knownReals + val Set knownStrings +} class ScopeLoader { - def TypeScopes loadScope(ScopeSpecification specification, LogicProblem problem, Ecore2Logic ecore2Logic, Ecore2Logic_Trace trace) { + def loadScope(ScopeSpecification specification, LogicProblem problem, Ecore2Logic ecore2Logic, Ecore2Logic_Trace trace) { val res = new TypeScopes + val knownElements = initialiseknownElements(problem,res) + val inconsistencies = new LinkedList() + for(scopeSpecification : specification.scopes) { - setSpecification(scopeSpecification,res,ecore2Logic,trace) + setSpecification(scopeSpecification,res,knownElements,ecore2Logic,trace,inconsistencies) } - return res + + return res -> inconsistencies + } + + def protected initialiseknownElements(LogicProblem p, TypeScopes s) { + val Map> res = new HashMap + for(definedType : p.types.filter(TypeDefinition)) { + val supertypes = definedType.transitiveClosureStar[x|x.supertypes] + for(supertype : supertypes) { + for(element : definedType.elements) { + res.putOrAddToSet(supertype,element) + } + } + } + val partailModelContents = p.annotations.filter(PartialModelRelation2Assertion).map[target].toList.map[eAllContents.toIterable].flatten.toList + s.knownIntegers += partailModelContents.filter(IntLiteral).map[it.value] + s.knownReals += partailModelContents.filter(RealLiteral).map[it.value] + s.knownStrings += partailModelContents.filter(StringLiteral).map[it.value] + + res + } + + def dispatch getElements(UnaryElementRelationLink link) { + #[link.param1] + } + def dispatch getElements(BinaryElementRelationLink link) { + #[link.param1,link.param2] + } + def dispatch getElements(NaryRelationLink link) { + link.elements } - def dispatch setSpecification(ObjectTypeScope scope, TypeScopes aggregated, Ecore2Logic ecore2Logic, Ecore2Logic_Trace trace) { - //val existingObjects = - aggregated.minNewElements = getLowerLimit(scope.number) - aggregated.maxNewElements = getUpperLimit(scope.number) + def dispatch setSpecification(ObjectTypeScope scope, TypeScopes aggregated, Map> knownElements, Ecore2Logic ecore2Logic, Ecore2Logic_Trace trace, List inconsistencies) { + val numberOfKnownElements = knownElements.values.flatten.toSet.size + + aggregated.minNewElements = updateLowerLimit(scope.isSetsNew,numberOfKnownElements,aggregated.minNewElements,getLowerLimit(scope.number)) + aggregated.maxNewElements = updateUpperLimit(scope.isSetsNew,numberOfKnownElements,aggregated.maxNewElements,getUpperLimit(scope.number)) } - def dispatch setSpecification(ClassTypeScope scope, TypeScopes aggregated, Ecore2Logic ecore2Logic, Ecore2Logic_Trace trace) { + def dispatch setSpecification(ClassTypeScope scope, TypeScopes aggregated, Map> knownElements, Ecore2Logic ecore2Logic, Ecore2Logic_Trace trace, List inconsistencies) { val target = scope.type.element - if(target.feature != null) { + if(target.feature !== null) { throw new IllegalArgumentException('''Feature scopes are not supported: "«target.feature.name»"!''') } else { val targetClassifier = target.classifier if(targetClassifier instanceof EClass) { val type = ecore2Logic.TypeofEClass(trace,targetClassifier) - aggregated.minNewElementsByType.put(type,getLowerLimit(scope.number)) - aggregated.maxNewElementsByType.put(type,getUpperLimit(scope.number)) + val known = type.lookup(knownElements).size + aggregated.minNewElementsByType.put(type, + updateLowerLimit( + scope.setsNew, + known, + type.lookup(aggregated.minNewElementsByType), + getLowerLimit(scope.number) + ) + ) + aggregated.maxNewElementsByType.put(type, + updateUpperLimit( + scope.setsNew, + known, + type.lookup(aggregated.minNewElementsByType), + getUpperLimit(scope.number) + ) + ) } else { throw new IllegalArgumentException('''Non-EClass scopes are not supported: "«targetClassifier.name»"!''') } } } - def dispatch setSpecification(IntegerTypeScope scope, TypeScopes aggregated, Ecore2Logic ecore2Logic, Ecore2Logic_Trace trace) { - aggregated.minNewIntegers = scope.number.lowerLimit - aggregated.maxNewIntegers = scope.number.upperLimit + def dispatch setSpecification(IntegerTypeScope scope, TypeScopes aggregated, Map> knownElements, Ecore2Logic ecore2Logic, Ecore2Logic_Trace trace, List inconsistencies) { + val number = scope.number + if(number instanceof IntEnumberation) { + addToKnownCollection(aggregated.knownIntegers,number.entry,scope.isSetsNew,inconsistencies) + } else { + aggregated.minNewIntegers = updateLowerLimit(scope.isSetsNew,aggregated.knownIntegers.size,aggregated.minNewIntegers,number.lowerLimit) + aggregated.maxNewIntegers = updateLowerLimit(scope.isSetsNew,aggregated.knownIntegers.size,aggregated.maxNewIntegers,number.upperLimit) + } + } + + def dispatch setSpecification(RealTypeScope scope, TypeScopes aggregated, Map> knownElements, Ecore2Logic ecore2Logic, Ecore2Logic_Trace trace, List inconsistencies) { + val number = scope.number + if(number instanceof RealEnumeration) { + val x = number.entry; + addToKnownCollection(aggregated.knownReals,x,scope.isSetsNew,inconsistencies) + } else { + aggregated.minNewReals = updateLowerLimit(scope.isSetsNew,aggregated.knownReals.size,aggregated.minNewReals,number.lowerLimit) + aggregated.maxNewReals = updateLowerLimit(scope.isSetsNew,aggregated.knownReals.size,aggregated.maxNewReals,number.upperLimit) + } + } + def dispatch setSpecification(StringTypeScope scope, TypeScopes aggregated, Map> knownElements, Ecore2Logic ecore2Logic, Ecore2Logic_Trace trace, List inconsistencies) { + val number = scope.number + if(number instanceof StringEnumeration) { + addToKnownCollection(aggregated.knownStrings,number.entry,scope.isSetsNew,inconsistencies) + } else { + aggregated.minNewStrings = updateLowerLimit(scope.isSetsNew,aggregated.knownStrings.size,aggregated.minNewStrings,number.lowerLimit) + aggregated.maxNewStrings = updateLowerLimit(scope.isSetsNew,aggregated.knownStrings.size,aggregated.maxNewStrings,number.upperLimit) + } + } + def addToKnownCollection(Set known, List definedInScope, boolean isSetNew, List inconsistencies) { + if(isSetNew) { + known += definedInScope + } else { + if(!definedInScope.containsAll(known)) { + val notDefinedInScope = known.filter[!definedInScope.contains(it)] + inconsistencies += '''Inconsistent scope: problem already contains literal«IF notDefinedInScope.size > 0»s«ENDIF» that excluded by a scope: «FOR e: notDefinedInScope SEPARATOR ", "»«e»«ENDFOR».''' + } + known.clear + known += definedInScope + } } - def dispatch setSpecification(RealTypeScope scope, TypeScopes aggregated, Ecore2Logic ecore2Logic, Ecore2Logic_Trace trace) { - aggregated.minNewReals = scope.number.lowerLimit - aggregated.maxNewReals = scope.number.upperLimit + + def updateLowerLimit(boolean isAdditional, int known, int original, int value) { + if(isAdditional) { + return Math.max(original,value) + } else { + return Math.max(original,value-known) + } } - def dispatch setSpecification(StringTypeScope scope, TypeScopes aggregated, Ecore2Logic ecore2Logic, Ecore2Logic_Trace trace) { - aggregated.minNewStrings = scope.number.lowerLimit - aggregated.maxNewStrings = scope.number.upperLimit + def updateUpperLimit(boolean isAdditional, int known, int original, int value) { + if(isAdditional) { + return Math.min(original,value) + } else { + val target = if(value == Integer.MAX_VALUE) { Integer.MAX_VALUE } else {value-known} + return Math.min(original,target) + } } def dispatch getLowerLimit(IntervallNumber specification) { @@ -70,14 +193,12 @@ class ScopeLoader { def dispatch getLowerLimit(RealEnumeration specification) { 0 } def dispatch getLowerLimit(StringEnumeration specification) { 0 } def dispatch getUpperLimit(IntervallNumber specification) { - if(specification.isMaxUnlimited) return -1 + if(specification.isMaxUnlimited) return Integer.MAX_VALUE else return specification.maxNumber } def dispatch getUpperLimit(ExactNumber specification) { - if(specification.isExactUnlimited) return -1 + if(specification.isExactUnlimited) return Integer.MAX_VALUE else return specification.exactNumber } - def dispatch getUpperLimit(IntEnumberation specification) { 0 } - def dispatch getUpperLimit(RealEnumeration specification) { 0 } - def dispatch getUpperLimit(StringEnumeration specification) { 0 } + } \ No newline at end of file -- cgit v1.2.3-54-g00ecf