From e11bce7ad3e803e80883499fec0ad6e4540ffe43 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Tue, 30 Jun 2020 18:03:48 +0200 Subject: Add modified VIATRA-DSE version --- .../viatra/dse/statecoding/IObjectsProvider.java | 45 ++++ .../dse/statecoding/IObjectsProviderFactory.java | 25 +++ .../dse/statecoding/IncrementalObjectProvider.java | 60 +++++ .../IncrementalObjectProviderFactory.java | 18 ++ .../dse/statecoding/StatecodingDependency.java | 33 +++ .../statecoding/StatecodingDependencyGraph.java | 44 ++++ .../dse/statecoding/StatecodingDependencyType.java | 15 ++ .../viatra/dse/statecoding/StatecodingNode.java | 100 +++++++++ .../dse/statecoding/StatecodingNodeType.java | 17 ++ .../viatra/dse/statecoding/TheStateCoder.java | 215 ++++++++++++++++++ .../dse/statecoding/TheStateCoderFactory.java | 40 ++++ .../dse/statecoding/simple/SimpleStateCoder.java | 250 +++++++++++++++++++++ .../simple/SimpleStateCoderFactory.java | 38 ++++ 13 files changed, 900 insertions(+) create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProvider.java create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProviderFactory.java create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProvider.java create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProviderFactory.java create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependency.java create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyGraph.java create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyType.java create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNode.java create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNodeType.java create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoder.java create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoderFactory.java create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder.java create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoderFactory.java (limited to 'Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding') 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 @@ +/******************************************************************************* + * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.viatra.dse.statecoding; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * Implementation of this interface is responsible to provide {@link EObject}s of a given {@link EClass} for + * {@link TheStateCoder} + * + * @author Andras Szabolcs Nagy + * + */ +public interface IObjectsProvider { + + /** + * Initialize the {@link IObjectsProvider} on a given model and {@link StatecodingDependencyGraph}. + * + * @param notifier + * The root of the model. + * @param statecodingDependencyGraph + * The state coding dependency graph. + */ + void init(Notifier notifier, StatecodingDependencyGraph statecodingDependencyGraph); + + /** + * Returns the instances of an {@link EClass} in a model. + * + * @param eClass + * The class of the objects. + * @return The collection of the instances. + */ + Collection getEObjects(EClass eClass); + +} 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 @@ +/******************************************************************************* + * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.viatra.dse.statecoding; + +/** + * Interface for creating {@link IObjectsProvider} instances. + * + * @author Andras Szabolcs Nagy + */ +public interface IObjectsProviderFactory { + + /** + * Creates an {@link IObjectsProvider} implementation. + * + * @return The newly created {@link IObjectsProvider}. + */ + IObjectsProvider createObjectsProvider(); + +} 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 @@ +/******************************************************************************* + * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.viatra.dse.statecoding; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.viatra.dse.api.DSEException; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.base.api.IndexingLevel; +import org.eclipse.viatra.query.runtime.base.api.NavigationHelper; +import org.eclipse.viatra.query.runtime.emf.EMFScope; +import org.eclipse.viatra.query.runtime.exception.ViatraQueryException; + +public class IncrementalObjectProvider implements IObjectsProvider { + + private Logger logger = Logger.getLogger(getClass()); + private NavigationHelper baseIndex; + + @Override + public void init(Notifier notifier, StatecodingDependencyGraph statecodingDependencyGraph) { + + try { + EMFScope scope = new EMFScope(notifier); + ViatraQueryEngine queryEngine = ViatraQueryEngine.on(scope); + + Set classes = new HashSet(); +// Set references = new HashSet(); + for (StatecodingNode node : statecodingDependencyGraph.getNodes()) { + classes.add(node.getClazz()); +// for (StatecodingDependency dependency : node.getStatecodingDependencies()) { +// // TODO inverse reference +// references.add(dependency.eReference); +// } + } + baseIndex = EMFScope.extractUnderlyingEMFIndex(queryEngine); + baseIndex.registerEClasses(classes, IndexingLevel.FULL); + } catch (ViatraQueryException e) { + logger.error("Failed to initialize VIATRA Query engine on the given notifier", e); + throw new DSEException("Failed to initialize VIATRA Query engine on the given notifier"); + } + } + + @Override + public Collection getEObjects(EClass eClass) { + return baseIndex.getAllInstances(eClass); + } + +} 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 @@ +/******************************************************************************* + * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.viatra.dse.statecoding; + +public class IncrementalObjectProviderFactory implements IObjectsProviderFactory { + + @Override + public IncrementalObjectProvider createObjectsProvider() { + return new IncrementalObjectProvider(); + } + +} 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 @@ +/******************************************************************************* + * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.viatra.dse.statecoding; + +import org.eclipse.emf.ecore.EReference; + +public class StatecodingDependency { + + protected EReference eReference; + protected StatecodingNode node; + protected boolean isContained; + protected StatecodingDependencyType type; + + public StatecodingDependency(EReference eReference, StatecodingNode node, boolean isContained, + StatecodingDependencyType type) { + super(); + this.eReference = eReference; + this.node = node; + this.isContained = isContained; + this.type = type; + } + + public StatecodingDependency(EReference eReference, StatecodingNode node) { + this(eReference, node, false, StatecodingDependencyType.NORMAL); + } + +} \ 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 @@ +/******************************************************************************* + * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.viatra.dse.statecoding; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.ecore.EClass; + +public class StatecodingDependencyGraph { + + private List nodes = new ArrayList(); + + public StatecodingNode createNode(EClass clazz) { + StatecodingNode node = new StatecodingNode(clazz); + node.setGraph(this); + addNode(node); + return node; + } + + public void addNode(StatecodingNode node) { + nodes.add(node); + } + + public StatecodingNode getNodeByClass(EClass eClass) { + for (StatecodingNode node : nodes) { + if (node.getClazz().equals(eClass)) { + return node; + } + } + return null; + } + + public List getNodes() { + return nodes; + } + +} 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 @@ +/******************************************************************************* + * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.viatra.dse.statecoding; + +public enum StatecodingDependencyType { + + NORMAL, + INVERSE +} 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 @@ +/******************************************************************************* + * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.viatra.dse.statecoding; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EReference; + +public class StatecodingNode { + + private StatecodingDependencyGraph graph; + + private final EClass clazz; + private Set attributes = new TreeSet(Comparator.comparing(EAttribute::getName)); + private List dependencies = new ArrayList(); + private boolean stateCodeIsId = false; + private StatecodingNodeType statecodingNodeType = StatecodingNodeType.CREATE_AND_DELETE; + + public StatecodingNode(EClass clazz) { + this.clazz = clazz; + } + + public StatecodingNode withAttribute(EAttribute attribute) { + attributes.add(attribute); + return this; + } + + public StatecodingNode withType(StatecodingNodeType type) { + statecodingNodeType = type; + return this; + } + + public StatecodingNode withUniqueness() { + stateCodeIsId = true; + return this; + } + + public StatecodingNode withDependency(EReference reference, StatecodingNode node) { + dependencies.add(new StatecodingDependency(reference, node)); + return this; + } + + public StatecodingNode withInverseDependency(EReference reference, StatecodingNode node) { + dependencies.add(new StatecodingDependency(reference, node, false, StatecodingDependencyType.INVERSE)); + return this; + } + + public void addDependency(StatecodingDependency statecodingDependency) { + dependencies.add(statecodingDependency); + } + + public EClass getClazz() { + return clazz; + } + + public boolean isStateCodeIsId() { + return stateCodeIsId; + } + + public void setStateCodeIsId(boolean stateCodeIsId) { + this.stateCodeIsId = stateCodeIsId; + } + + public StatecodingNodeType getStatecodingNodeType() { + return statecodingNodeType; + } + + public void setStatecodingNodeType(StatecodingNodeType statecodingNodeType) { + this.statecodingNodeType = statecodingNodeType; + } + + public Set getAttributes() { + return attributes; + } + + public List getStatecodingDependencies() { + return dependencies; + } + + public StatecodingDependencyGraph getGraph() { + return graph; + } + + public void setGraph(StatecodingDependencyGraph graph) { + this.graph = graph; + } + +} 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 @@ +/******************************************************************************* + * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.viatra.dse.statecoding; + +public enum StatecodingNodeType { + + FIXED, + ONLY_CREATE, + ONLY_DELETE, + CREATE_AND_DELETE +} 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 @@ +/******************************************************************************* + * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.viatra.dse.statecoding; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.viatra.dse.api.DSEException; +import org.eclipse.viatra.dse.statecode.IStateCoder; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; + +public class TheStateCoder implements IStateCoder { + + private StatecodingDependencyGraph sdg; + private IObjectsProvider objectProvider; + + public TheStateCoder(StatecodingDependencyGraph sdg, IObjectsProvider objectProvider) { + this.sdg = sdg; + this.objectProvider = objectProvider; + } + + @Override + public void init(Notifier notifier) { + // TODO checks + // TODO node sorting based on traversal - in factory + + // this.notifier = notifier; + // try { + // EMFScope scope = new EMFScope(notifier); + // queryEngine = ViatraQueryEngine.on(scope); + // } catch (ViatraQueryException e1) { + // logger.error("Failed to initialize VIATRA Query engine on the given notifier", e1); + // throw new DSEException("Failed to initialize VIATRA Query engine on the given notifier"); + // } + + objectProvider.init(notifier, sdg); + } + + @Override + public String createStateCode() { + + StringBuilder sb = new StringBuilder(); + + // TODO sort + for (StatecodingNode node : sdg.getNodes()) { + sb.append(node.getClazz().getName()); + sb.append(':'); + sb.append(addStateCode(node)); + sb.append('|'); + } + sb.deleteCharAt(sb.length() - 1); + + return sb.toString(); + + } + + @Override + public Object createActivationCode(IPatternMatch match) { + // TODO root object + // TODO parameterless? + + int i = 0; + StringBuilder sb = new StringBuilder(); + Object object; + do { + object = match.get(i++); + if (object != null) { + if (object instanceof EObject) { + EObject eObject = (EObject) object; + sb.append(addStateCode(sdg.getNodeByClass(eObject.eClass()), eObject)); + } else { + // TODO toString or not to toString + } + } + } while (object != null); + + return sb.toString(); + } + + public String addStateCode(StatecodingNode node, EObject eObject) { + StringBuilder sb = new StringBuilder(); + + Set attributes = node.getAttributes(); + if (!attributes.isEmpty()) { + for (EAttribute eAttribute : attributes) { + // attributes are sorted + // TODO handle collection + sb.append(eObject.eGet(eAttribute)); + sb.append(';'); + } + sb.deleteCharAt(sb.length() - 1); + } + + List dependencies = node.getStatecodingDependencies(); + int dependenciesSize = dependencies.size(); + if (dependenciesSize > 0) { + String[] codeParts = new String[dependenciesSize]; + int i = 0; + for (StatecodingDependency dependency : dependencies) { + String code = addStateCodeFromDependency(dependency, eObject); + codeParts[i++] = code; + } + Arrays.sort(codeParts); + + sb.append("("); + sb.append(codeParts[0]); + for (i = 1; i < codeParts.length; i++) { + sb.append(';'); + sb.append(codeParts[i]); + } + sb.append(")"); + } + return sb.toString(); + } + + public String addStateCode(StatecodingNode node) { + Collection eObjects = objectProvider.getEObjects(node.getClazz()); + int size = eObjects.size(); + + if (size > 0) { + String[] codeParts = new String[size]; + int i = 0; + for (EObject eObject : eObjects) { + String code = addStateCode(node, eObject); + codeParts[i++] = code; + } + Arrays.sort(codeParts); + + StringBuilder sb = new StringBuilder(); + sb.append(codeParts[0]); + for (i = 1; i < codeParts.length; i++) { + sb.append(';'); + sb.append(codeParts[i]); + } + return sb.toString(); + } + + return ""; + } + + public String addStateCodeFromDependency(StatecodingDependency sd, EObject eObject) { + + if (sd.type.equals(StatecodingDependencyType.NORMAL)) { + + Object eReferred = eObject.eGet(sd.eReference); + if (eReferred == null) { + return ""; + } else if (eReferred instanceof EList) { + EList refferedList = (EList) eReferred; + // TODO test + if (!refferedList.isEmpty()) { + + String[] codeParts = new String[refferedList.size()]; + int i = 0; + for (Object referredEObject : refferedList) { + String code = addStateCode(sd.node, (EObject) referredEObject); + codeParts[i++] = code; + } + Arrays.sort(codeParts); + + StringBuilder sb = new StringBuilder(); + sb.append('['); + sb.append(codeParts[0]); + for (i = 1; i < codeParts.length; i++) { + sb.append(';'); + sb.append(codeParts[i]); + } + sb.append(']'); + return sb.toString(); + + } + } else if (eReferred instanceof EObject) { + return addStateCode(sd.node, (EObject) eReferred); + } else { + throw new DSEException("The EObject " + eObject.toString() + " does not have a feature " + + eReferred.toString() + "."); + } + + } else { + for (EObject dependentEObject : objectProvider.getEObjects(sd.node.getClazz())) { + Object eReferred = dependentEObject.eGet(sd.eReference); + if (eReferred == null) { + continue; + } else if (eReferred instanceof EList) { + // TODO this is slow, use VIATRA Query + for (Object referredEObject : ((EList) eReferred)) { + if (referredEObject.equals(eObject)) { + return addStateCode(sd.node, (EObject) dependentEObject); + } + } + } else if (eReferred.equals(eObject)) { + // Probably never happens? + return addStateCode(sd.node, (EObject) dependentEObject); + } else { + throw new DSEException("The EObject " + eObject.toString() + " does not have a feature " + + eReferred.toString() + "."); + } + } + } + + return ""; + } +} 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 @@ +/******************************************************************************* + * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.viatra.dse.statecoding; + +import org.eclipse.viatra.dse.statecode.IStateCoder; +import org.eclipse.viatra.dse.statecode.IStateCoderFactory; + +public class TheStateCoderFactory implements IStateCoderFactory { + + private StatecodingDependencyGraph sdg; + private IObjectsProviderFactory objectProviderFactory; + + public TheStateCoderFactory(StatecodingDependencyGraph sdg) { + this(sdg, new IncrementalObjectProviderFactory()); + } + + public TheStateCoderFactory(StatecodingDependencyGraph sdg, IObjectsProviderFactory objectProviderFactory) { + this.sdg = sdg; + this.objectProviderFactory = objectProviderFactory; + + // TODO cyclic dependency? - exception + + // TODO make plan for traversal + + // TODO If the type is FIXED and all dependency is FIXED then do not create state code for it (them) + // This is not true :( e.g. matchmaking - they are fixed, but the references must be encoded + } + + @Override + public IStateCoder createStateCoder() { + return new TheStateCoder(sdg, objectProviderFactory.createObjectsProvider()); + } + +} 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 @@ +/******************************************************************************* + * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.viatra.dse.statecoding.simple; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.EStructuralFeature.Setting; +import org.eclipse.viatra.dse.api.DSEException; +import org.eclipse.viatra.dse.statecode.IStateCoder; +import org.eclipse.viatra.dse.util.EMFHelper.MetaModelElements; +import org.eclipse.viatra.dse.util.ValueComparableEObjectStringMap; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.base.api.FeatureListener; +import org.eclipse.viatra.query.runtime.base.api.IndexingLevel; +import org.eclipse.viatra.query.runtime.base.api.InstanceListener; +import org.eclipse.viatra.query.runtime.base.api.NavigationHelper; +import org.eclipse.viatra.query.runtime.emf.EMFBaseIndexWrapper; +import org.eclipse.viatra.query.runtime.emf.EMFScope; +import org.eclipse.viatra.query.runtime.exception.ViatraQueryException; + +/** + * + * @author Andras Szabolcs Nagy + * + */ +public class SimpleStateCoder implements IStateCoder { + + private Set classes; + private Set features; + private NavigationHelper navigationHelper; + + private Map> objectCodes; + private int maxDepth; + + private Set changedOrNewEObjects = new HashSet(); + private Set deletedClasses = new HashSet(); + + public SimpleStateCoder(MetaModelElements metaModelElements) { + this.maxDepth = 1; + + classes = metaModelElements.classes; + features = new HashSet(metaModelElements.attributes); + features.addAll(metaModelElements.references); + } + + @Override + public void init(Notifier notifier) { + try { + EMFScope scope = new EMFScope(notifier); + ViatraQueryEngine queryEngine = ViatraQueryEngine.on(scope); + EMFBaseIndexWrapper baseIndex = (EMFBaseIndexWrapper) queryEngine.getBaseIndex(); + navigationHelper = baseIndex.getNavigationHelper(); + navigationHelper.registerObservedTypes(classes, null, features, IndexingLevel.FULL); + } catch (ViatraQueryException e) { + throw new DSEException(e); + } + + objectCodes = new HashMap>(); + for (EClass eClass : classes) { + Map codes = new ValueComparableEObjectStringMap(); + + objectCodes.put(eClass, codes); + + for (EObject eObject : navigationHelper.getDirectInstances(eClass)) { + codes.put(eObject, createObjectCodeWithDepth(eObject, maxDepth)); + } + } + + navigationHelper.addFeatureListener(features, new FeatureListener() { + + @Override + public void featureInserted(EObject host, EStructuralFeature feature, Object value) { + changedOrNewEObjects.add(host); + } + + @Override + public void featureDeleted(EObject host, EStructuralFeature feature, Object value) { + changedOrNewEObjects.add(host); + if (value instanceof EObject) { + changedOrNewEObjects.add((EObject) value); + } + } + }); + + navigationHelper.addInstanceListener(classes, new InstanceListener() { + + @Override + public void instanceInserted(EClass clazz, EObject instance) { + changedOrNewEObjects.add(instance); + } + + @Override + public void instanceDeleted(EClass clazz, EObject instance) { + deletedClasses.add(instance); + } + }); + } + + private String createObjectCodeWithDepth(EObject eObject, int depth) { + + StringBuilder sb = new StringBuilder(); + + Collection attributes = eObject.eClass().getEAllAttributes(); + for (EAttribute eAttribute : attributes) { + Object value = eObject.eGet(eAttribute); + sb.append(value); + sb.append(','); + } + if (!attributes.isEmpty()) { + sb.deleteCharAt(sb.length() - 1); + } + if (depth > 0) { + sb.append('-'); + Collection eReferences = eObject.eClass().getEAllReferences(); + for (EReference eReference : eReferences) { + Object value = eObject.eGet(eReference); + if (value == null) { + sb.append("null,"); + } else if (value instanceof EObject) { + sb.append(createObjectCodeWithDepth((EObject) value, depth - 1)); + sb.append(','); + } else { + List referencedEObjects = (List) value; + if (!referencedEObjects.isEmpty()) { + + String[] codes = new String[referencedEObjects.size()]; + int index = 0; + for (EObject referencedEObject : referencedEObjects) { + codes[index++] = createObjectCodeWithDepth(referencedEObject, depth - 1); + } + Arrays.sort(codes); + sb.append('('); + for (String code : codes) { + sb.append(code); + } + sb.append("),"); + } + } + } + sb.deleteCharAt(sb.length() - 1); + } + return sb.toString(); + } + + @Override + public Object createStateCode() { + + refreshObjectCodes(); + + StringBuilder sb = new StringBuilder(); + + for (EClass eClass : classes) { + + Set instances = navigationHelper.getDirectInstances(eClass); + + if (!instances.isEmpty()) { + + sb.append(eClass.getName()); + sb.append(':'); + + String[] codesToSort = new String[instances.size()]; + int index = 0; + Map codes = objectCodes.get(eClass); + for (EObject eObject : instances) { + codesToSort[index++] = codes.get(eObject); + } + Arrays.sort(codesToSort); + for (String string : codesToSort) { + sb.append(string); + sb.append(';'); + } + sb.deleteCharAt(sb.length() - 1); + sb.append('|'); + } + } + if (sb.length() != 0) { + sb.deleteCharAt(sb.length() - 1); + } + return sb.toString(); + } + + private void refreshObjectCodes() { + for (EObject eObject : deletedClasses) { + EClass eClass = eObject.eClass(); + objectCodes.get(eClass).remove(eObject); + } + deletedClasses.clear(); + + Set objectsToRecode = new HashSet(); + for (EObject eObject : changedOrNewEObjects) { + objectsToRecode.add(eObject); + for (Setting setting : navigationHelper.getInverseReferences(eObject)) { + objectsToRecode.add(setting.getEObject()); + } + } + + for (EObject eObject : objectsToRecode) { + EClass eClass = eObject.eClass(); + objectCodes.get(eClass).put(eObject, createObjectCodeWithDepth(eObject, maxDepth)); + } + changedOrNewEObjects.clear(); + } + + @Override + public Object createActivationCode(IPatternMatch match) { + + StringBuilder sb = new StringBuilder(); + String[] tokens = match.specification().getFullyQualifiedName().split("\\."); + sb.append(tokens[tokens.length - 1]); + sb.append(':'); + Object param; + for (int i = 0; (param = match.get(i)) != null; i++) { + EObject eObject = (EObject) param; + + Collection attributes = eObject.eClass().getEAllAttributes(); + for (EAttribute eAttribute : attributes) { + Object value = eObject.eGet(eAttribute); + sb.append(value); + sb.append(','); + } + if (!attributes.isEmpty()) { + sb.deleteCharAt(sb.length() - 1); + } + + sb.append('|'); + } + sb.deleteCharAt(sb.length() - 1); + return sb.toString().intern(); + } + +} 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 @@ +/******************************************************************************* + * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.viatra.dse.statecoding.simple; + +import java.util.Collection; +import java.util.HashSet; + +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.viatra.dse.statecode.IStateCoder; +import org.eclipse.viatra.dse.statecode.IStateCoderFactory; +import org.eclipse.viatra.dse.util.EMFHelper; +import org.eclipse.viatra.dse.util.EMFHelper.MetaModelElements; + +/** + * + * @author Andras Szabolcs Nagy + * + */ +public class SimpleStateCoderFactory implements IStateCoderFactory { + + private MetaModelElements metaModelElements; + + public SimpleStateCoderFactory(Collection metaModelPackages) { + metaModelElements = EMFHelper.getAllMetaModelElements(new HashSet(metaModelPackages)); + } + + @Override + public IStateCoder createStateCoder() { + return new SimpleStateCoder(metaModelElements); + } + +} -- cgit v1.2.3-70-g09d2