/*******************************************************************************
* Copyright (c) 2010-2015 Henshin developers. All rights reserved.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* TU Berlin, University of Luxembourg, SES S.A.
*******************************************************************************/
package de.tub.tfs.henshin.analysis;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.impl.EPackageImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.henshin.interpreter.util.ModelHelper;
import org.eclipse.emf.henshin.model.And;
import org.eclipse.emf.henshin.model.Attribute;
import org.eclipse.emf.henshin.model.BinaryFormula;
import org.eclipse.emf.henshin.model.Edge;
import org.eclipse.emf.henshin.model.Formula;
import org.eclipse.emf.henshin.model.Graph;
import org.eclipse.emf.henshin.model.HenshinFactory;
import org.eclipse.emf.henshin.model.Mapping;
import org.eclipse.emf.henshin.model.Module;
import org.eclipse.emf.henshin.model.NestedCondition;
import org.eclipse.emf.henshin.model.Node;
import org.eclipse.emf.henshin.model.Not;
import org.eclipse.emf.henshin.model.Or;
import org.eclipse.emf.henshin.model.Rule;
import org.eclipse.emf.henshin.model.Unit;
import org.eclipse.emf.henshin.model.Xor;
import agg.attribute.AttrType;
import agg.attribute.AttrTypeMember;
import agg.attribute.handler.AttrHandler;
import agg.attribute.handler.impl.javaExpr.JexHandler;
import agg.cons.AtomConstraint;
import agg.parser.CriticalPair;
import agg.parser.CriticalPairData;
import agg.parser.CriticalPairOption;
import agg.parser.ExcludePairContainer;
import agg.parser.InvalidAlgorithmException;
import agg.util.Pair;
import agg.xt_basis.Arc;
import agg.xt_basis.Completion_InjCSP;
import agg.xt_basis.Completion_NAC;
import agg.xt_basis.GraGra;
import agg.xt_basis.GraphObject;
import agg.xt_basis.OrdinaryMorphism;
import agg.xt_basis.Type;
import agg.xt_basis.TypeException;
import agg.xt_basis.TypeGraph;
import agg.xt_basis.TypeSet;
public class AggInfo {
protected Module emfGrammar;
protected GraGra aggGrammar;
protected TypeSet aggTypeSet;
protected TypeGraph aggTypeGraph;
protected Map<EClass, Type> nodeTypeMap;
protected Map<EReference, Type> edgeTypeMap;
protected Map<Rule,agg.xt_basis.Rule> henshinRuleToAGGRuleConversion = new HashMap<Rule, agg.xt_basis.Rule>();
protected Map<agg.xt_basis.Rule,Rule> aggRuleToHenshinRuleConversion = new HashMap< agg.xt_basis.Rule,Rule>();
protected Map<Object,Object> aggToHenshinConversionMap = new HashMap<Object, Object>();
protected Map<Object,Object> henshinToAggConversionMap = new HashMap<Object, Object>();
private Map<de.tub.tfs.henshin.analysis.CriticalPair, List<EObject>> criticalPairToCriticalEObjects = new HashMap<de.tub.tfs.henshin.analysis.CriticalPair, List<EObject>>();
private LinkedList<EPackage> excludePackages = new LinkedList<EPackage>();
private List<EClassifier> excludeClassMap = new LinkedList<EClassifier>();
private EList<Rule> getRules(Module m) {
EList<Rule> rules = new BasicEList<Rule>();
for (Unit unit : m.getUnits()) {
if (unit instanceof Rule) {
rules.add((Rule) unit);
}
}
return ECollections.unmodifiableEList(rules);
}
public AggInfo(Module ts) {
aggTypeSet = new TypeSet();
aggTypeGraph = (TypeGraph) aggTypeSet.createTypeGraph();
aggGrammar = new GraGra(aggTypeSet);
aggGrammar.setGraTraOptions(new Completion_NAC(new Completion_InjCSP()));
// agg.xt_basis.Graph graph = aggGrammar.getGraph();
// aggGrammar.removeGraph(graph);
emfGrammar = ts;
nodeTypeMap = new HashMap<EClass, Type>();
edgeTypeMap = new HashMap<EReference, Type>();
for (EPackage package1 : excludePackages) {
excludeClassMap .addAll( package1.getEClassifiers());
}
convertImports(ts.getImports());
convertRules(getRules(ts));
}
private void convertRules(Collection<Rule> rules) {
for (Rule rule : rules) {
agg.xt_basis.Rule aggRule = createRule(rule);
henshinRuleToAGGRuleConversion.put(rule, aggRule);
aggRuleToHenshinRuleConversion.put(aggRule, rule);
}
}
private agg.xt_basis.Rule createRule(Rule henshinRule) {
agg.xt_basis.Rule aggRule = aggGrammar.createRule();
aggRule.setName(henshinRule.getName());
Map<Node, agg.xt_basis.Node> lhsNodeMap = fillGraph(henshinRule.getLhs(), aggRule.getLeft());
Map<Node, agg.xt_basis.Node> rhsNodeMap = fillGraph(henshinRule.getRhs(),
aggRule.getRight());
for (Mapping mapping : henshinRule.getMappings()) {
agg.xt_basis.Node aggLhsNode = lhsNodeMap.get(mapping.getOrigin());
agg.xt_basis.Node aggRhsNode = rhsNodeMap.get(mapping.getImage());
aggRule.addMapping(aggLhsNode, aggRhsNode);
}
for (Entry<Node, agg.xt_basis.Node> entry : lhsNodeMap.entrySet()) {
aggToHenshinConversionMap.put(entry.getValue(),entry.getKey());
henshinToAggConversionMap.put(entry.getKey(),entry.getValue());
}
for (Entry<Node, agg.xt_basis.Node> entry : rhsNodeMap.entrySet()) {
aggToHenshinConversionMap.put(entry.getValue(),entry.getKey());
henshinToAggConversionMap.put(entry.getKey(),entry.getValue());
}
// maps edges between nodes
aggRule.nextCompletion();
// translate Henshin ACs into NACs and PACs
// WARNING: if there are nestings or ORs or NOTs they will be ignored
// and
// the semantics of the rule will change.
convertAC(aggRule, lhsNodeMap, normalize(henshinRule.getLhs().getFormula()));
return aggRule;
}
private void convertAC(agg.xt_basis.Rule aggRule, Map<Node, agg.xt_basis.Node> nodeMap,
Formula formula) {
if (formula instanceof And) {
convertAC(aggRule, nodeMap, ((And) formula).getLeft());
convertAC(aggRule, nodeMap, ((And) formula).getRight());
} else if (formula instanceof NestedCondition) {
NestedCondition henshinAC = (NestedCondition) formula;
OrdinaryMorphism aggAC;
if (henshinAC.eContainer() instanceof Not)
aggAC = aggRule.createNAC();
else
aggAC = aggRule.createPAC();
Map<Node, agg.xt_basis.Node> acNodeMap = fillGraph(henshinAC.getConclusion(),
aggAC.getImage());
for (Mapping mapping : henshinAC.getMappings()) {
agg.xt_basis.Node aggLhsNode = nodeMap.get(mapping.getOrigin());
agg.xt_basis.Node aggRhsNode = acNodeMap.get(mapping.getImage());
aggAC.addMapping(aggLhsNode, aggRhsNode);
}
// maps edges between nodes
aggAC.nextCompletion();
}
if (formula instanceof Not){
convertAC(aggRule, nodeMap, ((Not) formula).getChild());
}
}
private Map<Node, agg.xt_basis.Node> fillGraph(Graph henshinGraph, agg.xt_basis.Graph aggGraph) {
Map<Node, agg.xt_basis.Node> graphNodeMap = new HashMap<Node, agg.xt_basis.Node>();
for (Node node : henshinGraph.getNodes()) {
if (excludeClassMap.contains(node.eClass()))
continue;
try {
if (nodeTypeMap.get(node.getType()) == null && node.getType().getEPackage() != null){
convertImports(Arrays.asList(node.getType().getEPackage()));
}
agg.xt_basis.Node aggNode = aggGraph.createNode(nodeTypeMap.get(node.getType()));
for (Attribute attribute : node.getAttributes()) {
aggNode.getAttribute().setExprAt(attribute.getValue(),
attribute.getType().getName());
}
graphNodeMap.put(node, aggNode);
} catch (Exception e) {
System.err.println(e);
}
}
for (Edge edge : henshinGraph.getEdges()) {
try {
Arc aggEdge = aggGraph.createArc(edgeTypeMap.get(edge.getType()),
graphNodeMap.get(edge.getSource()), graphNodeMap.get(edge.getTarget()));
aggToHenshinConversionMap.put(aggEdge, edge);
henshinToAggConversionMap.put(edge, aggEdge);
} catch (Exception e) {
System.err.println(e);
}
}
return graphNodeMap;
}
private void convertImports(List<EPackage> imports) {
for (EPackage ePackage : imports) {
if (ePackage.getNsURI() == null)
throw new RuntimeException("Could not find Package " + ((EPackageImpl)ePackage).eProxyURI());
createTypeNodes(ePackage);
}
aggTypeSet.getTypeGraph();
aggTypeSet.setLevelOfTypeGraph(TypeSet.ENABLED_MAX);
createTypeFeatures();
for (Entry<EClass, Type> entry : nodeTypeMap.entrySet()) {
aggToHenshinConversionMap.put(entry.getValue(), entry.getKey());
henshinToAggConversionMap.put(entry.getKey(),entry.getValue());
}
for (Entry<EReference, Type> entry : edgeTypeMap.entrySet()) {
aggToHenshinConversionMap.put(entry.getValue(), entry.getKey());
henshinToAggConversionMap.put(entry.getKey(),entry.getValue());
}
}
private void createTypeFeatures() {
AttrHandler handler = new JexHandler();
for (EClass emfType : nodeTypeMap.keySet()) {
if (excludeClassMap.contains(emfType))
continue;
Type aggNodeType = nodeTypeMap.get(emfType);
AttrType attr = aggNodeType.getAttrType();
// add inheritance relation
for (EClass emfParentType : emfType.getESuperTypes()) {
Type aggParentType = nodeTypeMap.get(emfParentType);
if (aggParentType != null) {
aggTypeSet.addInheritanceRelation(aggNodeType, aggParentType);
}
}
// add attributes to types
for (EAttribute emfAttribute : emfType.getEAttributes()) {
String dataType = EcoreUtil.toJavaInstanceTypeName(emfAttribute.getEGenericType());
System.out.println("DEBUG: " + dataType);
if (dataType.indexOf('<') != -1)
dataType = dataType.substring(0, dataType.indexOf('<'));
AttrTypeMember member = attr.addMember(handler,dataType , emfAttribute.getName());
if (member.getType() == null)
System.out.println("DEBUG: " + member.getType());
if (emfAttribute.getDefaultValue() != null)
aggNodeType.getTypeGraphNodeObject().getAttribute().setValueAt(emfAttribute.getDefaultValue(), emfAttribute.getName());
else
aggNodeType.getTypeGraphNodeObject().getAttribute().setExprValueAt("null", emfAttribute.getName());
}
// add edge types
for (EReference emfEdgeType : emfType.getEReferences()) {
Type aggEdgeType = aggTypeSet.getTypeByName(emfEdgeType.getName());
if (aggEdgeType == null)
aggEdgeType = aggTypeSet.createArcType(true);
EClass emfTargetType = (EClass) emfEdgeType.getEType();
Type aggTargetType = nodeTypeMap.get(emfTargetType);
if (aggTargetType != null) {
agg.xt_basis.Node aggSourceNode = aggTypeSet.getTypeGraphNode(aggNodeType);
agg.xt_basis.Node aggTargetNode = aggTypeSet.getTypeGraphNode(aggTargetType);
aggEdgeType.setStringRepr(emfEdgeType.getName());
aggEdgeType
.setAdditionalRepr(":SOLID_LINE::java.awt.Color[r=0,g=0,b=0]::[EDGE]:");
System.out.println("DEBUG: added " + aggSourceNode.getType().getName() + "---" + aggEdgeType + "---> " + aggTargetNode.getType().getName());
try {
Vector<Arc> arcs = aggTypeGraph.getArcs(aggEdgeType, aggSourceNode, aggTargetNode);
if (arcs!=null && !arcs.isEmpty())
continue; // do not create the edge again
Arc arc = aggTypeGraph.createArc(aggEdgeType, aggSourceNode, aggTargetNode);
aggEdgeType.setTargetMax(aggNodeType, aggTargetType,
emfEdgeType.isMany() ? -1 : 1);
henshinToAggConversionMap.put(new de.tub.tfs.henshin.analysis.Pair<EClass,EClass>(emfEdgeType.getEContainingClass(),(EClass)emfEdgeType.getEType() ), arc);
} catch (TypeException e) {
e.printStackTrace();
}
edgeTypeMap.put(emfEdgeType, aggEdgeType);
}
}
}
for (EClass emfType : nodeTypeMap.keySet()) {
for (EReference emfEdgeType : emfType.getEReferences()) {
if (emfEdgeType.getEOpposite() != null) {
AtomConstraint opCons = aggGrammar.createAtomic("op_" + emfEdgeType.getName());
// opCons = opCons.createNextConclusion(new
// agg.xt_basis.Graph());
agg.xt_basis.Graph premise = opCons.getOriginal();
opCons = opCons.getConclusion(0);
agg.xt_basis.Graph conclusion = opCons.getImage();
try {
agg.xt_basis.Node pSourceNode = premise
.createNode(nodeTypeMap.get(emfType));
agg.xt_basis.Node pTargetNode = premise.createNode(nodeTypeMap
.get(emfEdgeType.getEType()));
Arc pArc = premise.createArc(edgeTypeMap.get(emfEdgeType), pSourceNode,
pTargetNode);
agg.xt_basis.Node cSourceNode = conclusion.createNode(nodeTypeMap
.get(emfType));
agg.xt_basis.Node cTargetNode = conclusion.createNode(nodeTypeMap
.get(emfEdgeType.getEType()));
Arc cArc = conclusion.createArc(edgeTypeMap.get(emfEdgeType), cSourceNode,
cTargetNode);
Arc cArc2 = conclusion.createArc(
edgeTypeMap.get(emfEdgeType.getEOpposite()), cTargetNode,
cSourceNode);
opCons.addMapping(pSourceNode, cSourceNode);
opCons.addMapping(pTargetNode, cTargetNode);
opCons.addMapping(pArc, cArc);
} catch (TypeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (emfEdgeType.isContainment()) {
AtomConstraint opCons = aggGrammar
.createAtomic("cont_" + emfEdgeType.getName());
agg.xt_basis.Graph premise = opCons.getOriginal();
opCons = opCons.getConclusion(0);
agg.xt_basis.Graph conclusion = opCons.getImage();
agg.xt_basis.Node cSourceNode1;
try {
cSourceNode1 = conclusion.createNode(nodeTypeMap.get(emfType));
agg.xt_basis.Node cSourceNode2 = conclusion.createNode(nodeTypeMap
.get(emfType));
agg.xt_basis.Node cTargetNode = conclusion.createNode(nodeTypeMap
.get(emfEdgeType.getEType()));
Arc cArc = conclusion.createArc(edgeTypeMap.get(emfEdgeType), cSourceNode1,
cTargetNode);
Arc cArc2 = conclusion.createArc(edgeTypeMap.get(emfEdgeType),
cSourceNode2, cTargetNode);
} catch (TypeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (emfEdgeType.isMany()) {
AtomConstraint opCons = aggGrammar.createAtomic("p_" + emfEdgeType.getName());
// opCons = opCons.createNextConclusion(new
// agg.xt_basis.Graph());
agg.xt_basis.Graph premise = opCons.getOriginal();
opCons = opCons.getConclusion(0);
agg.xt_basis.Graph conclusion = opCons.getImage();
try {
// agg.xt_basis.Node pSourceNode =
// premise.createNode(nodeTypeMap.get(emfType));
// agg.xt_basis.Node pTargetNode =
// premise.createNode(nodeTypeMap.get(emfEdgeType.getEType()));
// Arc pArc =
// premise.createArc(edgeTypeMap.get(emfEdgeType),
// pSourceNode, pTargetNode);
agg.xt_basis.Node cSourceNode = conclusion.createNode(nodeTypeMap
.get(emfType));
agg.xt_basis.Node cTargetNode = conclusion.createNode(nodeTypeMap
.get(emfEdgeType.getEType()));
Arc cArc = conclusion.createArc(edgeTypeMap.get(emfEdgeType), cSourceNode,
cTargetNode);
Arc cArc2 = conclusion.createArc(edgeTypeMap.get(emfEdgeType), cSourceNode,
cTargetNode);
// opCons.addMapping(pSourceNode, cSourceNode);
// opCons.addMapping(pTargetNode, cTargetNode);
// opCons.addMapping(pArc, cArc);
} catch (TypeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
if (!aggGrammar.getListOfAtomics().isEmpty()){
String form = (aggGrammar.getListOfAtomics().get(0).getName().startsWith("op_") ? "" : "!")
+ "1";
for (int i = 2; i <= aggGrammar.getListOfAtomics().size(); i++) {
form += "&"
+ (aggGrammar.getListOfAtomics().get(i - 1).getName().startsWith("op_") ? ""
: "!") + i;
}
agg.cons.Formula formula = aggGrammar.createConstraint("Constraints");
System.out.println(form);
formula.setFormula(aggGrammar.getListOfAtomicObjects(), form);
}
}
private void createTypeNodes(EPackage ePackage) {
TypeGraph aggTypeGraph = (TypeGraph) aggTypeSet.getTypeGraph();
EClass eObjectType = EcoreFactory.eINSTANCE.createEObject().eClass();
Type aggEObjectType = nodeTypeMap.get(eObjectType);
if (aggEObjectType == null) {
aggEObjectType = aggTypeSet.createNodeType(true);
aggEObjectType.setStringRepr(eObjectType.getName());
aggEObjectType.setAdditionalRepr(":RECT:java.awt.Color[r=0,g=0,b=0]::[NODE]:");
try {
aggTypeGraph.createNode(aggEObjectType);
} catch (TypeException e) {
System.err.println(e);
}
nodeTypeMap.put(eObjectType, aggEObjectType);
}
// create nodes
for (EClassifier emfType : ePackage.getEClassifiers()) {
if (excludeClassMap.contains(emfType))
continue;
// create AGG type nodes
if (emfType instanceof EClass) {
if (nodeTypeMap.get(emfType) != null){
continue;
}
Type aggType = aggTypeSet.createNodeType(true);
aggType.setStringRepr(emfType.getName());
aggType.setAdditionalRepr(":RECT:java.awt.Color[r=0,g=0,b=0]::[NODE]:");
try {
aggType.addParent(aggEObjectType);
aggTypeGraph.createNode(aggType);
} catch (TypeException e) {
System.err.println(e);
}
nodeTypeMap.put((EClass) emfType, aggType);
}
}
}
public GraGra getAggGrammar() {
return aggGrammar;
}
public TypeSet getTypeSet() {
return aggTypeSet;
}
public TypeGraph getTypeGraph() {
return aggTypeGraph;
}
public Map<EClass, Type> getNodeTypeMap() {
return nodeTypeMap;
}
public Map<EReference, Type> getEdgeTypeMap() {
return edgeTypeMap;
}
public Module getEmfGrammar() {
return emfGrammar;
}
private Map<Rule,Rule> createControlflow(){
return null;
}
public boolean isCritical(CausalityType causalityType, Rule r1,Rule r2,Unit... context){
return false;
}
public boolean isDependentOn(Rule r1,Rule r2){
agg.xt_basis.Rule rule1 = getAGGRule(r1);
agg.xt_basis.Rule rule2 = getAGGRule(r2);
de.tub.tfs.henshin.analysis.DependencyPairContainer conflictContainer = new de.tub.tfs.henshin.analysis.DependencyPairContainer(getAggGrammar());
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> criticalPair = new Vector<Pair<Pair<OrdinaryMorphism,OrdinaryMorphism>,Pair<OrdinaryMorphism,OrdinaryMorphism>>>();
if (!rule1.isReadyToTransform())
System.out.println(rule1.getErrorMsg());
if (!rule2.isReadyToTransform())
System.out.println(rule2.getErrorMsg());
CriticalPairOption cpOption = new CriticalPairOption();
cpOption.setCriticalPairAlgorithm(CriticalPair.TRIGGER_DEPENDENCY);
cpOption.enableLayered(false);
cpOption.enableConsistent(true);
cpOption.enableStrongAttrCheck(true);
conflictContainer.enableComplete(cpOption.completeEnabled());
conflictContainer.enableReduce(cpOption.reduceEnabled());
conflictContainer.enableConsistent(cpOption.consistentEnabled());
conflictContainer.enableStrongAttrCheck(cpOption.strongAttrCheckEnabled());
conflictContainer.enableEqualVariableNameOfAttrMapping(cpOption.equalVariableNameOfAttrMappingEnabled());
conflictContainer.enableIgnoreIdenticalRules(cpOption.ignoreIdenticalRulesEnabled());
conflictContainer.enableReduceSameMatch(cpOption.reduceSameMatchEnabled());
conflictContainer.computeCriticalPair(rule1, rule2);
criticalPair = conflictContainer.getDependencyContainer().get(rule1).get(rule2).second;
if (criticalPair == null)
return false;
CriticalPairData data = new CriticalPairData(rule1,rule2,criticalPair);
return !data.hasCriticals();
}
public boolean isCritical(Rule r1,Rule r2){
return isInConflict(r1, r2);
}
public boolean isInConflict(Rule r1,Rule r2){
agg.xt_basis.Rule rule1 = getAGGRule(r1);
agg.xt_basis.Rule rule2 = getAGGRule(r2);
ConflictPairContainer conflictContainer = new ConflictPairContainer(getAggGrammar());
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> criticalPair = new Vector<Pair<Pair<OrdinaryMorphism,OrdinaryMorphism>,Pair<OrdinaryMorphism,OrdinaryMorphism>>>();
CriticalPairOption cpOption = new CriticalPairOption();
cpOption.setCriticalPairAlgorithm(CriticalPair.CONFLICT);
cpOption.enableLayered(false);
cpOption.enableConsistent(true); //olga - do take Graph consistency constraints in account
cpOption.enableStrongAttrCheck(true); //olga - do check attribute assignments more
conflictContainer.enableComplete(cpOption.completeEnabled());
conflictContainer.enableReduce(cpOption.reduceEnabled());
conflictContainer.enableConsistent(cpOption.consistentEnabled());
conflictContainer.enableStrongAttrCheck(cpOption.strongAttrCheckEnabled());
conflictContainer.enableEqualVariableNameOfAttrMapping(cpOption.equalVariableNameOfAttrMappingEnabled());
//conflictContainer.enableIgnoreIdenticalRules(cpOption.ignoreIdenticalRulesEnabled());
conflictContainer.enableReduceSameMatch(cpOption.reduceSameMatchEnabled());
conflictContainer.computeCriticalPair(rule1, rule2);
criticalPair = conflictContainer.getConflictContainer().get(rule1).get(rule2).second;
if (criticalPair == null)
return false;
CriticalPairData data = new CriticalPairData(rule1,rule2,criticalPair);
return !data.hasCriticals();
}
public List<de.tub.tfs.henshin.analysis.CriticalPair> getConflictOverlappings(Rule r1,Rule r2,Unit... context){
agg.xt_basis.Rule rule1 = getAGGRule(r1);
agg.xt_basis.Rule rule2 = getAGGRule(r2);
ConflictPairContainer conflictContainer = new ConflictPairContainer(getAggGrammar());
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> criticalPair = new Vector<Pair<Pair<OrdinaryMorphism,OrdinaryMorphism>,Pair<OrdinaryMorphism,OrdinaryMorphism>>>();
CriticalPairOption cpOption = new CriticalPairOption();
cpOption.setCriticalPairAlgorithm(CriticalPair.CONFLICT);
//cpOption.enableLayered(false);
//cpOption.enableConsistent(true); //olga
//cpOption.enableStrongAttrCheck(true); //olga
conflictContainer.enableComplete(cpOption.completeEnabled());
conflictContainer.enableReduce(cpOption.reduceEnabled());
conflictContainer.enableConsistent(cpOption.consistentEnabled());
conflictContainer.enableStrongAttrCheck(cpOption.strongAttrCheckEnabled());
conflictContainer.enableEqualVariableNameOfAttrMapping(cpOption.equalVariableNameOfAttrMappingEnabled());
conflictContainer.enableIgnoreIdenticalRules(cpOption.ignoreIdenticalRulesEnabled());
conflictContainer.enableReduceSameMatch(cpOption.reduceSameMatchEnabled());
conflictContainer.computeCriticalPair(rule1, rule2);
criticalPair = conflictContainer.getConflictContainer().get(rule1).get(rule2).second;
if (criticalPair == null)
return Collections.EMPTY_LIST;
CriticalPairData data = new CriticalPairData(rule1,rule2,criticalPair);
LinkedList<de.tub.tfs.henshin.analysis.CriticalPair> pairs = new LinkedList<de.tub.tfs.henshin.analysis.CriticalPair>();
while(data.next()){
de.tub.tfs.henshin.analysis.CriticalPair pair = createCriticalPair(data,context);
pairs.add(pair);
}
return pairs;
}
public List<de.tub.tfs.henshin.analysis.CriticalPair> getDependencyOverlappings(Rule r1,Rule r2,Unit... context){
agg.xt_basis.Rule rule1 = getAGGRule(r1);
agg.xt_basis.Rule rule2 = getAGGRule(r2);
de.tub.tfs.henshin.analysis.DependencyPairContainer conflictContainer = new de.tub.tfs.henshin.analysis.DependencyPairContainer(getAggGrammar());
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> criticalPair = new Vector<Pair<Pair<OrdinaryMorphism,OrdinaryMorphism>,Pair<OrdinaryMorphism,OrdinaryMorphism>>>();
CriticalPairOption cpOption = new CriticalPairOption();
cpOption.setCriticalPairAlgorithm(CriticalPair.TRIGGER_DEPENDENCY);
cpOption.enableLayered(false);
cpOption.enableConsistent(true); //olga
cpOption.enableStrongAttrCheck(true); //olga
conflictContainer.enableComplete(cpOption.completeEnabled());
conflictContainer.enableReduce(cpOption.reduceEnabled());
conflictContainer.enableConsistent(cpOption.consistentEnabled());
conflictContainer.enableStrongAttrCheck(cpOption.strongAttrCheckEnabled());
conflictContainer.enableEqualVariableNameOfAttrMapping(cpOption.equalVariableNameOfAttrMappingEnabled());
conflictContainer.enableIgnoreIdenticalRules(cpOption.ignoreIdenticalRulesEnabled());
conflictContainer.enableReduceSameMatch(cpOption.reduceSameMatchEnabled());
conflictContainer.computeCriticalPair(rule1, rule2);
criticalPair = conflictContainer.getDependencyContainer().get(rule1).get(rule2).second;
if (criticalPair == null)
return Collections.EMPTY_LIST;
CriticalPairData data = new CriticalPairData(rule1,rule2,criticalPair);
LinkedList<de.tub.tfs.henshin.analysis.CriticalPair> pairs = new LinkedList<de.tub.tfs.henshin.analysis.CriticalPair>();
while(data.next()){
de.tub.tfs.henshin.analysis.CriticalPair pair = createCriticalPair(data,context);
pairs.add(pair);
}
return pairs;
}
protected agg.xt_basis.Rule getAGGRule(Rule rule){
agg.xt_basis.Rule aggRule = this.henshinRuleToAGGRuleConversion.get(rule);
if (aggRule == null){
aggRule = createRule(rule);
henshinRuleToAGGRuleConversion.put(rule, aggRule);
aggRuleToHenshinRuleConversion.put(aggRule, rule);
}
return aggRule;
}
private de.tub.tfs.henshin.analysis.CriticalPair createCriticalPair(CriticalPairData data, Unit... context) {
de.tub.tfs.henshin.analysis.CriticalPair result = AnalysisFactory.eINSTANCE.createCriticalPair();
if (context.length > 0){
result.setSourceUnit(context[0]);
}
if (context.length > 1){
result.setTargetUnit(context[1]);
}
result.setType(CriticalPairType.get(data.getKindOfCurrentCritical()));
result.setRule1(aggRuleToHenshinRuleConversion.get(data.getRule1()));
result.setRule2(aggRuleToHenshinRuleConversion.get(data.getRule2()));
HashMap<agg.xt_basis.Node, Node> aggNodeToHeshinNodeConversion = new HashMap<agg.xt_basis.Node, Node>();
HashMap<Arc, Edge> aggArcToHenshinEdgeConversion = new HashMap<Arc, Edge>();
Graph conflictGraph = convertConflictGraph(data,aggNodeToHeshinNodeConversion,aggArcToHenshinEdgeConversion,result);
result.setOverlapping(conflictGraph);
aggToHenshinConversionMap.putAll(aggArcToHenshinEdgeConversion);
aggToHenshinConversionMap.putAll(aggNodeToHeshinNodeConversion);
LinkedList<Mapping> mappingsR1ToCG = new LinkedList<Mapping>();
LinkedList<Mapping> mappingsR2ToCG = new LinkedList<Mapping>();
LinkedList<Mapping> mappingsR1ToR2 = new LinkedList<Mapping>();
HashMap<Node,Node> cGToRule1Map = new HashMap<Node, Node>();
OrdinaryMorphism morph1 = data.getMorph1();
for (int i = 0 ;i < morph1.getDomainObjects().size();i++) {
Object obj1 = aggToHenshinConversionMap.get(morph1.getDomainObjects().get(i));
if (obj1 == null || !(obj1 instanceof Node))
continue;
Node source = (Node) obj1;
Node target = (Node) aggToHenshinConversionMap.get(morph1.getCodomainObjects().get(i));
Mapping mapping = HenshinFactory.eINSTANCE.createMapping(source,target);
mappingsR1ToCG.add(mapping);
cGToRule1Map.put(target, source);
}
OrdinaryMorphism morph2 = data.getMorph2DueToLHS();
for (int i = 0 ;i < morph2.getDomainObjects().size();i++) {
Object obj1 = aggToHenshinConversionMap.get(morph2.getDomainObjects().get(i));
if (obj1 == null || !(obj1 instanceof Node))
continue;
Node source = (Node) obj1;
Node target = (Node) aggToHenshinConversionMap.get(morph2.getCodomainObjects().get(i));
Mapping mapping = HenshinFactory.eINSTANCE.createMapping(source,target);
mappingsR2ToCG.add(mapping);
if (cGToRule1Map.containsKey(target)){
Mapping mapping2 = HenshinFactory.eINSTANCE.createMapping(cGToRule1Map.get(target),source);
mappingsR1ToR2.add(mapping2);
}
}
OrdinaryMorphism morph3 = data.getMorph2DueToNAC();
for (int i = 0 ;morph3 != null && i < morph3.getDomainObjects().size();i++) {
Object obj1 = aggToHenshinConversionMap.get(morph3.getDomainObjects().get(i));
if (obj1 == null || !(obj1 instanceof Node))
continue;
Node source = (Node) obj1;
Node target = (Node) aggToHenshinConversionMap.get(morph3.getCodomainObjects().get(i));
Mapping mapping = HenshinFactory.eINSTANCE.createMapping(source,target);
mappingsR2ToCG.add(mapping);
//if (cGToRule1Map.containsKey(target)){
// Mapping mapping2 = HenshinFactory.eINSTANCE.createMapping(cGToRule1Map.get(target),source);
// mappingsR1ToR2.add(mapping2);
//}
}
result.getMappingsOverlappingToRule1().addAll(mappingsR1ToCG);
result.getMappingsOverlappingToRule2().addAll(mappingsR2ToCG);
result.getMappingsRule1ToRule2().addAll(mappingsR1ToR2);
convertCriticalObjects(data.getCriticalGraphObjects(), result);
return result;
}
private void convertCriticalObjects(List<GraphObject> criticalGraphObjects, de.tub.tfs.henshin.analysis.CriticalPair criticalPair) {
List<EObject> criticalObjects = new ArrayList<EObject>();
for (GraphObject o : criticalGraphObjects) {
Object object = aggToHenshinConversionMap.get(o);
if (object instanceof EObject) {
criticalObjects.add((EObject)object);
}
}
criticalPairToCriticalEObjects.put(criticalPair, criticalObjects);
}
public Map<de.tub.tfs.henshin.analysis.CriticalPair, List<EObject>> getCriticalObjects() {
return criticalPairToCriticalEObjects;
}
private Graph convertConflictGraph(CriticalPairData data,
HashMap<agg.xt_basis.Node, Node> nodeConversion,
HashMap<Arc, Edge> arcConversion,de.tub.tfs.henshin.analysis.CriticalPair p) {
Graph graph = HenshinFactory.eINSTANCE.createGraph();
graph.setName(data.getCriticalGraph().getName());
agg.xt_basis.Graph criticalGraph = data.getCriticalGraph();
for (agg.xt_basis.Node aggNode : criticalGraph.getNodesSet()) {
Node node = HenshinFactory.eINSTANCE.createNode();
node.setName(aggNode.getObjectName());
node.setType((EClass) this.aggToHenshinConversionMap.get(aggNode.getType()));
graph.getNodes().add(node);
nodeConversion.put(aggNode, node);
if (aggNode.isCritical())
p.getCriticalObjects().add(node);
int numberOfEntries = aggNode.getAttribute().getNumberOfEntries();
for (int i = 0; i < numberOfEntries; i++) {
String attrName = aggNode.getAttribute().getNameAsString(i);
if (!aggNode.getAttribute().isValueSetAt(attrName))
continue;
String value = aggNode.getAttribute().getValueAsString(i);
for (EAttribute attr : node.getType().getEAllAttributes()) {
if (attr.getName().equals(attrName)){
Attribute attribute = HenshinFactory.eINSTANCE.createAttribute();
attribute.setType(attr);
attribute.setValue(value);
node.getAttributes().add(attribute);
break;
}
}
}
}
for (Arc aggArc : criticalGraph.getArcsSet()) {
Edge edge = HenshinFactory.eINSTANCE.createEdge();
edge.setSource(nodeConversion.get(aggArc.getSource()));
edge.setTarget(nodeConversion.get(aggArc.getTarget()));
edge.setType((EReference) aggToHenshinConversionMap.get(aggArc.getType()));
graph.getEdges().add(edge);
arcConversion.put(aggArc, edge);
if (aggArc.isCritical())
p.getCriticalObjects().add(edge);
}
return graph;
}
public Map<Integer,Integer> getConflictType(Rule r1,Rule r2){
agg.xt_basis.Rule rule1 = getAGGRule(r1);
agg.xt_basis.Rule rule2 = getAGGRule(r2);
ExcludePairContainer conflictContainer = new ExcludePairContainer(getAggGrammar());
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> criticalPair = new Vector<Pair<Pair<OrdinaryMorphism,OrdinaryMorphism>,Pair<OrdinaryMorphism,OrdinaryMorphism>>>();
try {
criticalPair = conflictContainer.getCriticalPair(rule1, rule2, CriticalPair.EXCLUDE);
} catch (InvalidAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
CriticalPairData data = new CriticalPairData(rule1,rule2,criticalPair);
HashMap<Integer,Integer> result = new HashMap<Integer,Integer>();
for (int i = 0; i <= 12; i++) {
int size = data.getCriticalDataOfKind(i).getSize();
if (size > 0){
result.put(i,size);
}
}
return result;
}
public Map<Integer,Integer> getDepencyType(Rule r1,Rule r2){
agg.xt_basis.Rule rule1 = getAGGRule(r1);
agg.xt_basis.Rule rule2 = getAGGRule(r2);
ExcludePairContainer conflictContainer = new ExcludePairContainer(getAggGrammar());
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> criticalPair = new Vector<Pair<Pair<OrdinaryMorphism,OrdinaryMorphism>,Pair<OrdinaryMorphism,OrdinaryMorphism>>>();
try {
criticalPair = conflictContainer.getCriticalPair(rule1, rule2, CriticalPair.EXCLUDE);
} catch (InvalidAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
CriticalPairData data = new CriticalPairData(rule1,rule2,criticalPair);
HashMap<Integer,Integer> result = new HashMap<Integer,Integer>();
for (int i = 0; i <= 12; i++) {
int size = data.getCriticalDataOfKind(i).getSize();
if (size > 0){
result.put(i,size);
}
}
return result;
}
public void save(String dir,String fileName){
this.getAggGrammar().setDirName(dir);
this.getAggGrammar().save(fileName);
}
public static Formula normalize(Formula nc){
Formula root = EcoreUtil.copy(nc);
System.out.println("=====================================================================");
System.out.println("=== DEBUG: " + debugFormula(nc,new char[]{'A'}));
System.out.println("=== DEBUG: " + debugFormula(root,new char[]{'A'}));
System.out.println("=====================================================================");
return eval(root,false);
}
public static Formula eval(Formula nc,boolean change){
if (nc instanceof Not){
change = !change;
return eval(((Not) nc).getChild(),change);
}
if (nc instanceof NestedCondition){
if (change){
/*if (((NestedCondition) nc).isNegated()){
return nc;
} else {*/
Not not = HenshinFactory.eINSTANCE.createNot();
not.setChild(nc);
return not;
//}
} else {
/*if (((NestedCondition) nc).isNegated()){
Not not = HenshinFactory.eINSTANCE.createNot();
not.setChild(nc);
return not;
}*/
return nc;
}
}
if (nc instanceof BinaryFormula){
if (change){
if (nc instanceof And){
Or or= HenshinFactory.eINSTANCE.createOr();
or.setLeft(eval(((BinaryFormula) nc).getLeft(),change));
or.setRight(eval(((BinaryFormula) nc).getRight(),change));
return or;
}
if (nc instanceof Or){
And and = HenshinFactory.eINSTANCE.createAnd();
and.setLeft(eval(((BinaryFormula) nc).getLeft(),change));
and.setRight(eval(((BinaryFormula) nc).getRight(),change));
return and;
}
if (nc instanceof Xor){
Not not = HenshinFactory.eINSTANCE.createNot();
And and1 = HenshinFactory.eINSTANCE.createAnd();
And and2 = HenshinFactory.eINSTANCE.createAnd();
Or or = HenshinFactory.eINSTANCE.createOr();
Formula f = and1;
and1.setLeft(or);
and1.setRight(not);
not.setChild(and2);
or.setLeft(((BinaryFormula) nc).getLeft());
or.setRight(((BinaryFormula) nc).getRight());
and2.setLeft(((BinaryFormula) nc).getLeft());
and2.setRight(((BinaryFormula) nc).getRight());
return eval(f,change);
}
} else {
((BinaryFormula) nc).setLeft(eval(((BinaryFormula) nc).getLeft(),change));
((BinaryFormula) nc).setRight(eval(((BinaryFormula) nc).getRight(),change));
return nc;
}
}
return nc;
}
public static String debugFormula(Formula f,char[] varName){
if (f instanceof NestedCondition){
char var = varName[0]++;
return (((NestedCondition) f).getConclusion().getName() == null ? "" + var : ((NestedCondition) f).getConclusion().getName());
}
if (f instanceof And){
if (!(f.eContainer() instanceof And))
return "(" + debugFormula(((And) f).getLeft(), varName) + " and " + debugFormula(((And) f).getRight(), varName) + ")";
else
return debugFormula(((And) f).getLeft(), varName) + " and " + debugFormula(((And) f).getRight(), varName);
}
if (f instanceof Or){
if (!(f.eContainer() instanceof Or))
return "(" + debugFormula(((Or) f).getLeft(), varName) + " or " + debugFormula(((Or) f).getRight(), varName) + ")";
else
return debugFormula(((Or) f).getLeft(), varName) + " or " + debugFormula(((Or) f).getRight(), varName);
}
if (f instanceof Not){
return " not " + debugFormula(((Not) f).getChild(), varName);
}
if (f instanceof Xor){
if (!(f.eContainer() instanceof Xor))
return "(" + debugFormula(((Xor) f).getLeft(), varName) + " xor " + debugFormula(((Xor) f).getRight(), varName) + ")";
else
return debugFormula(((Xor) f).getLeft(), varName) + " xor " + debugFormula(((Xor) f).getRight(), varName);
}
if (f == null){
return "";
}
return f.toString();
}
public static void exportAsTransformationSystem(de.tub.tfs.henshin.analysis.CriticalPair criticalPair){
@SuppressWarnings("unchecked")
HashSet<HashSet<Node>> mappings = MappingConverter.convertMappings(criticalPair);
Module system = HenshinFactory.eINSTANCE.createModule();
int id = 0;
for (HashSet<Node> hashSet : mappings) {
for (Node node : hashSet) {
node.setName("id:" + id);
}
id++;
}
system.getUnits().add(EcoreUtil.copy(criticalPair.getRule1()));
system.getUnits().add(EcoreUtil.copy(criticalPair.getRule2()));
//system.getInstances().add(criticalPair.getOverlapping());
ModelHelper.saveFile(criticalPair.getType().getLiteral() + "(" + criticalPair.getRule1().getName() + "_and_" + criticalPair.getRule2().getName() + "_id:" + criticalPair.hashCode() + ").henshin", system);
}
public void registerAdditionalAttribute(EAttribute attr,String value,Node target){
Type aggType = nodeTypeMap.get(target.getType());
String dataType = EcoreUtil.toJavaInstanceTypeName(attr.getEGenericType());
System.out.println("DEBUG: " + dataType);
if (dataType.indexOf('<') != -1)
dataType = dataType.substring(0, dataType.indexOf('<'));
AttrTypeMember member = (AttrTypeMember) aggType.getAttrType().getMemberAt(attr.getName() + attr.hashCode());
if (member == null)
member = aggType.getAttrType().addMember(new JexHandler(),dataType , attr.getName() + attr.hashCode());
if (member.getType() == null)
System.out.println("DEBUG: " + member.getType());
if (attr.getDefaultValue() != null)
aggType.getTypeGraphNodeObject().getAttribute().setValueAt(attr.getDefaultValue(), attr.getName() + attr.hashCode());
else
aggType.getTypeGraphNodeObject().getAttribute().setExprValueAt("null", attr.getName() + attr.hashCode());
agg.xt_basis.Node aggNode = (agg.xt_basis.Node) henshinToAggConversionMap.get(target);
aggNode.getAttribute().setExprAt(value, attr.getName() + attr.hashCode());
}
public void registerAdditionalAttribute(EAttribute attr,String value,Edge target){
Type aggType = edgeTypeMap.get(target.getType());
Type sourceType = nodeTypeMap.get(target.getType().getEContainingClass());
Type targetType = nodeTypeMap.get(target.getType().getEType());
Arc typeArc = aggType.getTypeGraphArcObject(sourceType, targetType);
String dataType = EcoreUtil.toJavaInstanceTypeName(attr.getEGenericType());
System.out.println("DEBUG: " + dataType);
if (dataType.indexOf('<') != -1)
dataType = dataType.substring(0, dataType.indexOf('<'));
AttrTypeMember member = (AttrTypeMember) aggType.getAttrType().getMemberAt(attr.getName());
if (member == null)
member = aggType.getAttrType().addMember(new JexHandler(),dataType , attr.getName());
if (member.getType() == null)
System.out.println("DEBUG: " + member.getType());
if (attr.getDefaultValue() != null)
typeArc.getAttribute().setValueAt(attr.getDefaultValue(), attr.getName());
else
typeArc.getAttribute().setExprValueAt("null", attr.getName());
agg.xt_basis.Arc aggArc = (agg.xt_basis.Arc) henshinToAggConversionMap.get(target);
aggArc.getAttribute().setExprAt(value, attr.getName());
}
}