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/TheStateCoder.java | 215 +++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoder.java (limited to 'Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoder.java') 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 ""; + } +} -- cgit v1.2.3-54-g00ecf