From 6f88c4bd4e91728cea62505e893b0ce300baf7fc Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Thu, 7 Feb 2019 18:24:45 +0100 Subject: Ecore2Cft transformation --- .../cft2ft/Cft2FtTransformation.xtend | 10 +++ .../ecore2cft/ComponentFaultTreeTrace.xtend | 39 ++++++++++ .../ecore2cft/ComponentInstanceTrace.xtend | 51 ++++++++++++ .../ecore2cft/ComponentNameGenerator.xtend | 16 ++++ .../ecore2cft/Ecore2CftTransformation.xtend | 27 +++++++ .../transformation/ecore2cft/InputTrace.xtend | 29 +++++++ .../transformation/ecore2cft/LookupHandler.xtend | 47 +++++++++++ .../transformation/ecore2cft/MappingHandler.xtend | 91 ++++++++++++++++++++++ .../transformation/ecore2cft/MappingQueries.xtend | 38 +++++++++ 9 files changed, 348 insertions(+) create mode 100644 Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/Cft2FtTransformation.xtend create mode 100644 Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentFaultTreeTrace.xtend create mode 100644 Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentInstanceTrace.xtend create mode 100644 Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentNameGenerator.xtend create mode 100644 Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/Ecore2CftTransformation.xtend create mode 100644 Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/InputTrace.xtend create mode 100644 Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/LookupHandler.xtend create mode 100644 Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/MappingHandler.xtend create mode 100644 Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/MappingQueries.xtend (limited to 'Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree') diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/Cft2FtTransformation.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/Cft2FtTransformation.xtend new file mode 100644 index 00000000..caaffc3c --- /dev/null +++ b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/Cft2FtTransformation.xtend @@ -0,0 +1,10 @@ +package hu.bme.mit.inf.dslreasoner.faulttree.transformation.cft2ft + +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.ComponentFaultTree + +class Cft2FtTransformation { + def createFaultTree(ComponentFaultTree componentFaultTree) { + // TODO + throw new UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentFaultTreeTrace.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentFaultTreeTrace.xtend new file mode 100644 index 00000000..7a3e377b --- /dev/null +++ b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentFaultTreeTrace.xtend @@ -0,0 +1,39 @@ +package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft + +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.CftFactory +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.ComponentDefinition +import java.util.Map +import org.eclipse.viatra.query.runtime.api.IPatternMatch +import org.eclipse.xtend.lib.annotations.Accessors + +class ComponentFaultTreeTrace { + @Accessors val componentFaultTree = CftFactory.eINSTANCE.createComponentFaultTree + + val nameGenerator = new ComponentNameGenerator + val Map componentInstancesMap = newHashMap + + def instantiateComponent(IPatternMatch patternMatch, ComponentDefinition componenDefinition) { + if (componentInstancesMap.containsKey(patternMatch)) { + throw new IllegalArgumentException("Already instantiated component for match: " + patternMatch) + } + val componentTrace = new ComponentInstanceTrace(componentFaultTree, componenDefinition, nameGenerator) + componentInstancesMap.put(patternMatch, componentTrace) + componentTrace + } + + def setTopLevel(ComponentInstanceTrace trace) { + if (componentFaultTree.topEvent !== null) { + throw new IllegalArgumentException("Top level component already set") + } + val outputs = trace.outputs + if (outputs.size !== 1) { + throw new IllegalArgumentException("Top level component must have 1 output, got " + outputs.size + + " instead") + } + componentFaultTree.topEvent = outputs.head + } + + def lookup(IPatternMatch patternMatch) { + componentInstancesMap.get(patternMatch) + } +} diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentInstanceTrace.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentInstanceTrace.xtend new file mode 100644 index 00000000..7353bfe5 --- /dev/null +++ b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentInstanceTrace.xtend @@ -0,0 +1,51 @@ +package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft + +import com.google.common.collect.Maps +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.CftFactory +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.ComponentDefinition +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.ComponentFaultTree +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.EventDeclaration +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.InputEvent +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Output +import java.util.Map + +class ComponentInstanceTrace { + val componentInstance = CftFactory.eINSTANCE.createComponent + val Map inputEventsMap + val Map outputEventsMap + + protected new(ComponentFaultTree faultTree, ComponentDefinition componentDefinition, + ComponentNameGenerator nameGenerator) { + componentInstance.componentDefinition = componentDefinition + componentInstance.name = nameGenerator.nextName(componentDefinition) + inputEventsMap = Maps.newHashMapWithExpectedSize(componentDefinition.inputEvents.size) + for (inputEvent : componentDefinition.inputEvents) { + val inputTrace = new InputTrace(componentInstance, inputEvent) + inputEventsMap.put(inputEvent, inputTrace) + } + outputEventsMap = Maps.newHashMapWithExpectedSize(componentDefinition.outputEvents.size) + for (outputEvent : componentDefinition.outputEvents) { + val output = CftFactory.eINSTANCE.createOutput + output.eventDeclaration = outputEvent + componentInstance.outputs += output + outputEventsMap.put(outputEvent, output) + } + faultTree.components += componentInstance + } + + def void assign(EventDeclaration inputEvent, ComponentInstanceTrace sourceComponent, EventDeclaration outputEvent) { + val inputTrace = inputEventsMap.get(inputEvent) + if (inputTrace === null) { + throw new IllegalArgumentException("Unknown input: " + inputEvent) + } + val output = sourceComponent.outputEventsMap.get(outputEvent) + if (output === null) { + throw new IllegalArgumentException("Unknown output: " + outputEvent) + } + inputTrace.assign(output) + } + + protected def getOutputs() { + componentInstance.outputs + } +} diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentNameGenerator.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentNameGenerator.xtend new file mode 100644 index 00000000..71d40a9b --- /dev/null +++ b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentNameGenerator.xtend @@ -0,0 +1,16 @@ +package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft + +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.ComponentDefinition +import java.util.Map + +class ComponentNameGenerator { + static val DEFAULT_NAME = "__unnamed" + + val Map instanceCounts = newHashMap + + def nextName(ComponentDefinition componentDefinition) { + val instanceCount = instanceCounts.getOrDefault(componentDefinition, 0) + instanceCounts.put(componentDefinition, instanceCount + 1) + (componentDefinition.name ?: DEFAULT_NAME) + instanceCount + } +} diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/Ecore2CftTransformation.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/Ecore2CftTransformation.xtend new file mode 100644 index 00000000..36aac5e1 --- /dev/null +++ b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/Ecore2CftTransformation.xtend @@ -0,0 +1,27 @@ +package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft + +import com.google.common.collect.ImmutableList +import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.TransformationDefinition +import java.util.List +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine + +class Ecore2CftTransformation { + val List mappingHandlers + + new(TransformationDefinition transformationDefinition, ViatraQueryEngine viatraQueryEngine) { + val mappingQueries = new MappingQueries(transformationDefinition, viatraQueryEngine) + mappingHandlers = ImmutableList.copyOf(transformationDefinition.mappingDefinitions.map [ mappingDefinition | + new MappingHandler(mappingDefinition, mappingQueries) + ]) + } + + def createComponentFaultTree() { + val trace = new ComponentFaultTreeTrace + for (handler : mappingHandlers) { + handler.instantiateComponents(trace) + } + for (handler : mappingHandlers) { + handler.instantiateConnections(trace) + } + } +} diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/InputTrace.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/InputTrace.xtend new file mode 100644 index 00000000..c529a09b --- /dev/null +++ b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/InputTrace.xtend @@ -0,0 +1,29 @@ +package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft + +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.CftFactory +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Component +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Connection +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Input +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.InputEvent +import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Output +import java.util.Map + +class InputTrace { + val Input input = CftFactory.eINSTANCE.createInput + val Map connectionsMap = newHashMap + + protected new(Component component, InputEvent inputEvent) { + input.inputEvent = inputEvent + component.inputs += input + } + + def void assign(Output output) { + val connection = connectionsMap.get(output) + if (connection === null) { + val newConnection = CftFactory.eINSTANCE.createConnection + newConnection.output = output + input.incomingConnections += newConnection + connectionsMap.put(output, newConnection) + } + } +} diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/LookupHandler.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/LookupHandler.xtend new file mode 100644 index 00000000..3a06dcc3 --- /dev/null +++ b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/LookupHandler.xtend @@ -0,0 +1,47 @@ +package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft + +import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.LookupDefinition +import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.MappingDefinition +import org.eclipse.viatra.query.runtime.api.IPatternMatch +import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher + +class LookupHandler { + val int[] argumentIndices + val ViatraQueryMatcher lookedUpMatcher + + new(MappingDefinition mappingDefinition, LookupDefinition lookupDefinition, + ViatraQueryMatcher lookedUpMatcher) { + if (lookupDefinition.eContainer != mappingDefinition) { + throw new IllegalArgumentException("lookupDefinition must be contained in mappingDefinition") + } + val argumentCount = lookupDefinition.arguments.size + if (argumentCount != lookedUpMatcher.parameterNames.length) { + throw new IllegalArgumentException( + "lookupDefinition (name: " + lookupDefinition.mapping?.pattern?.name + + ") must have as many arguments as lookedUpMatcher (name: " + lookedUpMatcher.patternName + ")") + } + argumentIndices = newIntArrayOfSize(argumentCount) + for (var int i = 0; i < argumentCount; i++) { + val argument = lookupDefinition.arguments.get(i) + val argumentIndex = mappingDefinition.parameters.indexOf(argument) + argumentIndices.set(i, argumentIndex) + } + this.lookedUpMatcher = lookedUpMatcher + } + + def lookupForMatch(ComponentFaultTreeTrace faultTreeTrace, IPatternMatch match) { + val lookedUpMatch = createLookedUpMatch(match) + faultTreeTrace.lookup(lookedUpMatch) + } + + private def createLookedUpMatch(IPatternMatch match) { + val lookedUpMatch = lookedUpMatcher.newEmptyMatch + val argumentCount = argumentIndices.length + for (var int i = 0; i < argumentCount; i++) { + val argumentIndex = argumentIndices.get(i) + var argumentValue = match.get(argumentIndex) + lookedUpMatch.set(i, argumentValue) + } + lookedUpMatch + } +} diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/MappingHandler.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/MappingHandler.xtend new file mode 100644 index 00000000..643af5c4 --- /dev/null +++ b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/MappingHandler.xtend @@ -0,0 +1,91 @@ +package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft + +import com.google.common.collect.ImmutableMap +import com.google.common.collect.Maps +import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.LookupDefinition +import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.MappingDefinition +import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.Variable +import java.util.Map +import org.eclipse.viatra.query.runtime.api.IPatternMatch +import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher + +class MappingHandler { + val ViatraQueryMatcher matcher + val MappingDefinition mappingDefinition + val Map lookupHandlers + + new(MappingDefinition mappingDefinition, MappingQueries mappingQueries) { + matcher = mappingQueries.getMatcher(mappingDefinition) + this.mappingDefinition = mappingDefinition + val variables = newHashSet + for (assignment : mappingDefinition.assignments) { + variables += assignment.input.component + variables += assignment.output.component + } + lookupHandlers = ImmutableMap.copyOf(variables.filter(LookupDefinition).toMap([it], [ lookupDefinition | + mappingQueries.createLookupHandler(mappingDefinition, lookupDefinition) + ])) + } + + def instantiateComponents(ComponentFaultTreeTrace faultTreeTrace) { + if (!hasComponentInstace) { + return + } + matcher.forEachMatch [ match | + val componentTrace = faultTreeTrace.instantiateComponent(match, componentDefinition) + if (isTopLevel) { + faultTreeTrace.topLevel = componentTrace + } + ] + } + + def instantiateConnections(ComponentFaultTreeTrace faultTreeTrace) { + if (!hasConnections) { + return + } + matcher.forEachMatch [ match | + val lookedUpComponents = lookupComponents(faultTreeTrace, match) + for (assignment : mappingDefinition.assignments) { + val input = assignment.input + val inputComponent = lookedUpComponents.get(input.component) + val output = assignment.output + val outputComponent = lookedUpComponents.get(output.component) + if (inputComponent !== null && outputComponent !== null) { + inputComponent.assign(input.event, outputComponent, output.event) + } + } + ] + } + + private def Map lookupComponents(ComponentFaultTreeTrace faultTreeTrace, + IPatternMatch match) { + val lookedUpComponents = Maps.newHashMapWithExpectedSize(lookupHandlers.size + 1) + if (hasComponentInstace) { + val componentInstance = faultTreeTrace.lookup(match) + lookedUpComponents.put(mappingDefinition.componentInstance, componentInstance) + } + for (pair : lookupHandlers.entrySet) { + val componentInstance = pair.value.lookupForMatch(faultTreeTrace, match) + if (componentInstance !== null) { + lookedUpComponents.put(pair.key, componentInstance) + } + } + lookedUpComponents + } + + private def getComponentDefinition() { + mappingDefinition.componentInstance?.componentType + } + + private def hasComponentInstace() { + componentDefinition !== null + } + + private def isTopLevel() { + mappingDefinition.topLevel + } + + private def hasConnections() { + !mappingDefinition.assignments.empty + } +} diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/MappingQueries.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/MappingQueries.xtend new file mode 100644 index 00000000..6683b3f8 --- /dev/null +++ b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/MappingQueries.xtend @@ -0,0 +1,38 @@ +package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft + +import com.google.common.collect.ImmutableMap +import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.LookupDefinition +import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.MappingDefinition +import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.TransformationDefinition +import java.util.Map +import org.eclipse.viatra.query.patternlanguage.emf.specification.SpecificationBuilder +import org.eclipse.viatra.query.runtime.api.GenericQueryGroup +import org.eclipse.viatra.query.runtime.api.IPatternMatch +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine +import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher + +class MappingQueries { + val Map> matchersMap + + new(TransformationDefinition transformationDefinition, ViatraQueryEngine viatraQueryEngine) { + val specificationBuilder = new SpecificationBuilder + val querySpecificationsMap = transformationDefinition.mappingDefinitions.toMap([it], [ + specificationBuilder.getOrCreateSpecification(pattern) + ]) + GenericQueryGroup.of(querySpecificationsMap.values).prepare(viatraQueryEngine) + matchersMap = ImmutableMap.copyOf(querySpecificationsMap.mapValues[getMatcher(viatraQueryEngine)]) + } + + def getMatcher(MappingDefinition mappingDefinition) { + val matcher = matchersMap.get(mappingDefinition) + if (matcher === null) { + throw new IllegalArgumentException("Unknown mapping definition: " + mappingDefinition) + } + matcher + } + + def createLookupHandler(MappingDefinition mappingDefinition, LookupDefinition lookupDefinition) { + val lookedUpMatcher = getMatcher(lookupDefinition.mapping) + new LookupHandler(mappingDefinition, lookupDefinition, lookedUpMatcher) + } +} -- cgit v1.2.3-70-g09d2