[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[henshin-dev] Fwd: Henshin Interpreter Diff mit User Constraints
|
Hallo Christian,
here is the patch updated to revision 1633.
Since package matching is now integrated into interpreter, all
changes have taken place in interpreter.
Thanks for considering the patch
(it might really be useful also for other Henshin users)
Best,
Claudia
-------- Original-Nachricht --------
Here is the Henshin Interpreter Diff with User Constraints
On 07/12/2012 04:40 PM, Claudia Ermel wrote:
Am 13.07.2012 13:43, schrieb Claudia Ermel:
> Hi Christian,
>
> thanks for the positive feedback.
> Your are right, it makes more sense to update our version to
the current revision first, including the patch. I will send you the
updated Java files when we have finished the update.
> But it's good to know that you agree in general.
>
> Best,
> Claudia
>
> Am 12.07.2012 20:34, schrieb Christian Krause:
>> Hi Claudia,
>>
>> your extension seems useful also for other applications and
I think it is a good idea to incorporate it into our development
version. Since we changed the API and the internal structure of the
interpreter (e.g. the matching plug-in was merged into the
interpreter plug-in), it would be more helpful if you can send us
the added or changed Java files. Then I can see what's the best way
to integrate them.
>>
>> Cheers,
>> Christian
>>
>> On 07/12/2012 04:40 PM, Claudia Ermel wrote:
>>> Dear Gregor and all,
>>>
>>> as discussed last Tuesday, we need a patch for
henshin.matching and henshin.interpreter that allows us in our new
triple graph grammar editor to apply rules according to certain
source consistency conditions.
>>> Using the patch, these conditions can be incorporated
in a special UserConstraint class where we implement the additional
checks that have to be performed for matching.
>>>
>>> In our particular case, we check a boolean attribute
"isTranslated" of a rule node that, if true, must be mapped to a
graph node only if this graph node has been translated before; (and
the other way round: a "false"-tagged rule node must be matched only
to a graph node that has NOT YET been translated -- we check this by
looking up certain tables where we store ids of translated
elements).
>>> We cannot model this by an equally-bound "isTranslated"
attributes in the instance model because the instance model (and its
EMF model) must not be extended by new attribute (types); the
"isTranslated" attribute serves only for rule application purposes,
but does not belong to the model.
>>>
>>> Moreover, it does NOT help us to check only if the
objects are in the "used objects" list of the matchfinder, because
there may be objects that have been used by the rule before
("used_object=true") but should be used again by the next rule since
the matches of both rules may well overlap in these objects.
>>> The "used_object" value alone does not tell us whether
the "isTranslated"-values of rule and graph object do coincide or
not.
>>>
>>> Hence, we need the patch and would be very happy if you
could integrate it.
>>> The patch is very general and allows Henshin users to
add user-specific constraints to the matching process.
>>> (If no user constraints are needed, nothing has to be
done and everything works as before.)
>>> Here is a short description of the changes in this
patch (based on revision 1243):
>>>
>>> 1) in org.eclipse.emf.henshin.matching
>>> - new class in Package constraints: public abstract
class UserConstraint implements Constraint
>>>
>>> 2) in org.eclipse.emf.henshin.interpreter
>>> - new class: public abstract class
HenshinUserConstraint extends UserConstraint
>>>
>>> - in class EmfEngine:
>>> + a new variable
>>> private HashMap<Class<? extends
UserConstraint>, Object[]> userConstraints = new
HashMap<Class<? extends UserConstraint>,Object[]>();
>>>
>>> + a new method
>>> public void registerUserConstraint(Class<? extends
UserConstraint> con,Object... params)
>>>
>>> Using the patch in our particular case:
>>> Method registerUserConstraint is called in execute()
by us in tggeditor.commands.ExecuteRulesCommand:
>>> HashMap<Node, Boolean> isTranslatedNodeMap = new
HashMap<Node, Boolean>();
>>> emfEngine.registerUserConstraint(RuleConstraint.class,
isTranslatedNodeMap);
>>>
>>> The RuleConstraint class is our TGGEditor class
tggeditor.commands.RuleConstraint and extends HenshinUserConstraint
and implements the source consistency check we need.
>>>
>>> I attach the patches for matching and interpreter.
Please have a look and tell us what you think.
>>>
>>> Best,
>>> Claudia
|
Index: src/org/eclipse/emf/henshin/interpreter/impl/EngineImpl.java
===================================================================
--- src/org/eclipse/emf/henshin/interpreter/impl/EngineImpl.java (revision 1633)
+++ src/org/eclipse/emf/henshin/interpreter/impl/EngineImpl.java (working copy)
@@ -11,6 +11,7 @@
*******************************************************************************/
package org.eclipse.emf.henshin.interpreter.impl;
+import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -58,6 +59,7 @@
import org.eclipse.emf.henshin.interpreter.matching.constraints.DomainSlot;
import org.eclipse.emf.henshin.interpreter.matching.constraints.Solution;
import org.eclipse.emf.henshin.interpreter.matching.constraints.SolutionFinder;
+import org.eclipse.emf.henshin.interpreter.matching.constraints.UserConstraint;
import org.eclipse.emf.henshin.interpreter.matching.constraints.Variable;
import org.eclipse.emf.henshin.model.And;
import org.eclipse.emf.henshin.model.Attribute;
@@ -95,6 +97,9 @@
// Whether to sort variables.
protected boolean sortVariables;
+ private HashMap<Constructor<? extends UserConstraint>, Object[]> userConstraints = new HashMap<Constructor<? extends UserConstraint>,Object[]>();
+
+
/**
* Default constructor.
*/
@@ -495,7 +500,7 @@
protected RuleInfo getRuleInfo(Rule rule) {
RuleInfo ruleInfo = ruleInfos.get(rule);
if (ruleInfo == null) {
- ruleInfo = new RuleInfo(rule, this);
+ ruleInfo = new RuleInfo(rule, this,this.userConstraints);
ruleInfos.put(rule, ruleInfo);
// Check for missing factories:
for (Node node : ruleInfo.getChangeInfo().getCreatedNodes()) {
@@ -791,4 +796,44 @@
return scriptEngine;
}
+
+
+ public void registerUserConstraint(Class<? extends UserConstraint> con,Object... params){
+ if (this.userConstraints == null){
+ this.userConstraints = new HashMap<Constructor<? extends UserConstraint>,Object[]>();
+ }
+ Constructor<? extends UserConstraint> c = null;
+ Object[] newParams = null;
+ @SuppressWarnings("unchecked")
+ Constructor<? extends UserConstraint>[] constructors = (Constructor<? extends UserConstraint>[]) con.getConstructors();
+ constructorLoop: for (Constructor<? extends UserConstraint> constructor : constructors) {
+
+ Class<?>[] constructorTypes = constructor.getParameterTypes();
+ boolean matchingTypes = true;
+ if (constructorTypes.length != params.length+1){
+ continue;
+ }
+
+ for (int i = 1;i < constructorTypes.length;i++) {
+ if (matchingTypes)
+ matchingTypes &= constructorTypes[i].isAssignableFrom(params[i-1].getClass());
+ else
+ continue constructorLoop;
+ }
+
+ if (constructorTypes[0].equals(Node.class)){
+ newParams = new Object[1 + params.length];
+ newParams [0] = null;
+ System.arraycopy(params, 0, newParams , 1, params.length);
+ c = constructor;
+ break;
+ }
+ }
+
+
+
+ this.userConstraints.put(c,newParams);
+ }
+
+
}
\ No newline at end of file
Index: src/org/eclipse/emf/henshin/interpreter/info/RuleInfo.java
===================================================================
--- src/org/eclipse/emf/henshin/interpreter/info/RuleInfo.java (revision 1633)
+++ src/org/eclipse/emf/henshin/interpreter/info/RuleInfo.java (working copy)
@@ -11,7 +11,11 @@
*******************************************************************************/
package org.eclipse.emf.henshin.interpreter.info;
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+
import org.eclipse.emf.henshin.interpreter.impl.EngineImpl;
+import org.eclipse.emf.henshin.interpreter.matching.constraints.UserConstraint;
import org.eclipse.emf.henshin.model.Rule;
public class RuleInfo {
@@ -21,11 +25,11 @@
private RuleChangeInfo changeInfo;
private ConditionInfo conditionInfo;
- public RuleInfo(Rule rule, EngineImpl engine) {
+ public RuleInfo(Rule rule, EngineImpl engine,HashMap<Constructor<? extends UserConstraint>, Object[]> userConstraints) {
this.rule = rule;
this.conditionInfo = new ConditionInfo(rule);
- this.variableInfo = new VariableInfo(this, engine);
+ this.variableInfo = new VariableInfo(this, engine,userConstraints);
this.changeInfo = new RuleChangeInfo(rule);
}
Index: src/org/eclipse/emf/henshin/interpreter/info/VariableInfo.java
===================================================================
--- src/org/eclipse/emf/henshin/interpreter/info/VariableInfo.java (revision 1633)
+++ src/org/eclipse/emf/henshin/interpreter/info/VariableInfo.java (working copy)
@@ -1,11 +1,14 @@
package org.eclipse.emf.henshin.interpreter.info;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
@@ -15,6 +18,7 @@
import org.eclipse.emf.henshin.interpreter.matching.constraints.DanglingConstraint;
import org.eclipse.emf.henshin.interpreter.matching.constraints.ParameterConstraint;
import org.eclipse.emf.henshin.interpreter.matching.constraints.ReferenceConstraint;
+import org.eclipse.emf.henshin.interpreter.matching.constraints.UserConstraint;
import org.eclipse.emf.henshin.interpreter.matching.constraints.Variable;
import org.eclipse.emf.henshin.model.Attribute;
import org.eclipse.emf.henshin.model.BinaryFormula;
@@ -52,7 +56,7 @@
private Rule rule;
private EngineImpl engine;
- public VariableInfo(RuleInfo ruleInfo, EngineImpl engine) {
+ public VariableInfo(RuleInfo ruleInfo, EngineImpl engine, HashMap<Constructor<? extends UserConstraint>, Object[]> userConstraints) {
this.rule = ruleInfo.getRule();
this.engine = engine;
@@ -65,10 +69,12 @@
createVariables(rule.getLhs(), null);
for (Node node : rule.getLhs().getNodes()) {
+ if (userConstraints != null)
+ createUserConstraints(node,userConstraints);
+
if (rule.getMappings().getImage(node,rule.getRhs())==null)
createDanglingConstraints(node);
}
-
mainVariables = variable2mainVariable.values();
}
@@ -153,6 +159,39 @@
var.danglingConstraints.add(constraint);
}
+
+ private void createUserConstraints(Node node, HashMap<Constructor<? extends UserConstraint>, Object[]> userConstraints) {
+
+ Variable var = node2variable.get(node);
+ for (Entry<Constructor<? extends UserConstraint>, Object[]> entry : userConstraints.entrySet()) {
+
+ UserConstraint instance;
+ try {
+ entry.getValue()[0] = node;
+ instance = (UserConstraint) entry.getKey().newInstance(entry.getValue());
+ var.userConstraints.add(instance);
+
+ } catch (IllegalArgumentException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (InstantiationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ break;
+
+
+ }
+
+
+ }
+
private Map<EReference, Integer> getEdgeCounts(Node node, boolean incoming) {
Collection<Edge> edges = incoming ? node.getIncoming() : node.getOutgoing();
Collection<Edge> oppositeEdges = incoming ? node.getOutgoing() : node.getIncoming();
Index: src/org/eclipse/emf/henshin/interpreter/matching/constraints/HenshinUserConstraint.java
===================================================================
--- src/org/eclipse/emf/henshin/interpreter/matching/constraints/HenshinUserConstraint.java (revision 0)
+++ src/org/eclipse/emf/henshin/interpreter/matching/constraints/HenshinUserConstraint.java (working copy)
@@ -0,0 +1,40 @@
+package org.eclipse.emf.henshin.interpreter.matching.constraints;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.henshin.interpreter.EGraph;
+import org.eclipse.emf.henshin.interpreter.impl.EGraphImpl;
+import org.eclipse.emf.henshin.interpreter.util.HenshinEGraph;
+import org.eclipse.emf.henshin.model.Node;
+
+public abstract class HenshinUserConstraint extends UserConstraint {
+
+
+ /**
+ *
+ * @param node the node in the LHS of the rule which this constraint belongs to
+ */
+ public HenshinUserConstraint(Node node) {
+ super(node);
+ }
+
+ /**
+ *
+ * @param graphNode the mapped node in the hostgraph
+ * @return Returns whether this constraint is satisfied or not i.e. there exists a morphism between the graph containing this constraints node and the host graph.
+ */
+ public abstract boolean check(Node graphNode);
+
+ @Override
+ public boolean check(DomainSlot slot,EGraph graph){
+ return check(getGraphNode(slot,graph));
+ }
+
+ protected Node getGraphNode(DomainSlot slot,EGraph graph){
+ return getGraphNode(getValue(slot), graph);
+ }
+
+ protected Node getGraphNode(EObject eObject,EGraph graph){
+ return ((HenshinEGraph)graph).getObject2NodeMap().get(eObject);
+ }
+
+}
Index: src/org/eclipse/emf/henshin/interpreter/matching/constraints/UserConstraint.java
===================================================================
--- src/org/eclipse/emf/henshin/interpreter/matching/constraints/UserConstraint.java (revision 0)
+++ src/org/eclipse/emf/henshin/interpreter/matching/constraints/UserConstraint.java (working copy)
@@ -0,0 +1,24 @@
+package org.eclipse.emf.henshin.interpreter.matching.constraints;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.henshin.interpreter.EGraph;
+import org.eclipse.emf.henshin.model.Node;
+
+public abstract class UserConstraint implements Constraint {
+
+
+ public UserConstraint(Node node) {
+ }
+
+
+ public abstract boolean check(DomainSlot slot,EGraph graph);
+
+ public boolean unlock(Variable sender,DomainSlot slot){
+ return true;
+ }
+
+ protected EObject getValue(DomainSlot slot){
+ return slot.value;
+ }
+
+}
Index: src/org/eclipse/emf/henshin/interpreter/matching/constraints/Variable.java
===================================================================
--- src/org/eclipse/emf/henshin/interpreter/matching/constraints/Variable.java (revision 1633)
+++ src/org/eclipse/emf/henshin/interpreter/matching/constraints/Variable.java (working copy)
@@ -41,6 +41,9 @@
// Containment constraints:
public final List<ContainmentConstraint> containmentConstraints;
+ // User defined constraints:
+ public final List<UserConstraint> userConstraints;
+
/**
* Constructor. Creates the related {@link TypeConstraint} already.
* @param type Type of the node to be matched.
@@ -60,6 +63,7 @@
danglingConstraints = new ArrayList<DanglingConstraint>();
referenceConstraints = new ArrayList<ReferenceConstraint>();
parameterConstraints = new ArrayList<ParameterConstraint>();
+ userConstraints = new ArrayList<UserConstraint>();
containmentConstraints = new ArrayList<ContainmentConstraint>();
}
begin:vcard
fn:Dr. Claudia Ermel
n:Ermel;Claudia
org;quoted-printable;quoted-printable:Technische Universit=C3=A4t Berlin;Institut f=C3=BCr Softwaretechnik und Theoretische Informatik
adr:;;Franklinstr. 28-29;Berlin;;10587;Germany
email;internet:claudia.ermel@xxxxxxxxxxxx
tel;work:+49 30 314 27787
tel;fax:+49 30 314 23516
url:http://www.tfs.tu-berlin.de/menue/home/team/ermel_claudia/
version:2.1
end:vcard