package agg.parser;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import agg.attribute.AttrContext;
import agg.attribute.AttrInstance;
import agg.attribute.AttrMapping;
import agg.attribute.AttrType;
import agg.attribute.handler.HandlerExpr;
import agg.attribute.impl.AttrTupleManager;
import agg.attribute.impl.CondMember;
import agg.attribute.impl.CondTuple;
import agg.attribute.impl.ContextView;
import agg.attribute.impl.ValueMember;
import agg.attribute.impl.ValueTuple;
import agg.attribute.impl.VarMember;
import agg.attribute.impl.VarTuple;
import agg.parser.ExcludePairContainer.Entry;
import agg.util.Pair;
import agg.util.Triple;
import agg.xt_basis.Arc;
import agg.xt_basis.BadMappingException;
import agg.xt_basis.BaseFactory;
import agg.xt_basis.CompletionStrategySelector;
import agg.xt_basis.Completion_InjCSP;
import agg.xt_basis.GraGra;
import agg.xt_basis.Graph;
import agg.xt_basis.GraphObject;
import agg.xt_basis.Match;
import agg.xt_basis.MorphCompletionStrategy;
import agg.xt_basis.Node;
import agg.xt_basis.OrdinaryMorphism;
import agg.xt_basis.Rule;
import agg.xt_basis.TestStep;
import agg.xt_basis.Type;
import agg.xt_basis.TypeException;
import agg.xt_basis.TypeSet;
import agg.xt_basis.csp.CompletionPropertyBits;
import agg.xt_basis.csp.Completion_InheritCSP;
/**
* This class implements an algorithm to decide whether two rules are in conflict:
* the first rule prohibits the second.
*
* @author $Author: olga $
* @version $Id: ExcludePair.java,v 1.147 2010/12/16 17:32:14 olga Exp $
*/
public class ExcludePair implements CriticalPair {
protected int cpdKind = -1;
protected boolean computable = true;
protected boolean checkSwitchDependency;
protected boolean dependencyCond1;
protected boolean dependencyCond2;
protected boolean withNACs = true;
protected boolean withPACs = true;
protected boolean complete = true;
protected int maxBoundOfCriticCause = 0; // <=0 unbound
public boolean reduceSameMatch;
protected boolean consistentOnly;
protected boolean dangling = true;
protected MorphCompletionStrategy strategy;
protected boolean ownStrategy = true;
protected boolean ignoreIdenticalRules;
protected GraGra grammar;
protected boolean stop;
protected boolean inclAsGraph;
/* Global help containers needed for rule analysis and more */
protected Vector<Pair<Type, Pair<Type, Type>>>
typesTG_L2, typesTG_NAC2, typesTG_PAC2;
protected Vector<GraphObject> contextC1_L1, boundB1_L1, preservedK1_L1;
protected Vector<GraphObject> contextC1_R1, boundB1_R1, preservedK1_R1;
protected Vector<GraphObject> delete, produce, preservedChanged, danglingEdges;
protected boolean criticalNACOfR2exists;
protected boolean essential;
public boolean strongAttrCheck;
protected int levelOfTypeGraphCheck;
protected boolean consistCheck, withNACsCheck, withPACsCheck;
protected boolean directStrctCnfl, directStrctCnflUpToIso;
private OrdinaryMorphism nacInsideOverlapGraph;
private Hashtable<ValueMember, Pair<String, String>> attrMember2Expr;
protected boolean withInheritance;
protected boolean equalVariableNameOfAttrMapping;
protected boolean danglEdge;
protected boolean namedObjectOnly;
protected int inclCount, inclProgress;
protected Hashtable<OrdinaryMorphism,Pair<OrdinaryMorphism, OrdinaryMorphism>> ac2leftExtended; //NAC | PAC
protected int duIndx, pfIndx=-1, caIndx;
protected String duIndxStr, pfIndxStr, caIndxStr;
long freeM, usedM;
/**
* Creates a new object to compute critical pairs.
*/
public ExcludePair() {
((AttrTupleManager) agg.attribute.impl.AttrTupleManager
.getDefaultManager()).setVariableContext(true);
this.typesTG_L2 = new Vector<Pair<Type, Pair<Type, Type>>>(5);
this.typesTG_NAC2 = new Vector<Pair<Type, Pair<Type, Type>>>(5);
this.typesTG_PAC2 = new Vector<Pair<Type, Pair<Type, Type>>>(5);
this.contextC1_L1 = new Vector<GraphObject>(5);
this.boundB1_L1 = new Vector<GraphObject>(5);
this.preservedK1_L1 = new Vector<GraphObject>(5);
this.contextC1_R1 = new Vector<GraphObject>(5);
this.boundB1_R1 = new Vector<GraphObject>(5);
this.preservedK1_R1 = new Vector<GraphObject>(5);
this.delete = new Vector<GraphObject>(5);
this.produce = new Vector<GraphObject>(5);
this.preservedChanged = new Vector<GraphObject>(5);
this.danglingEdges = new Vector<GraphObject>(5);
this.attrMember2Expr = new Hashtable<ValueMember, Pair<String, String>> (2);
this.duIndx=-1; this.pfIndx=-1; this.caIndx=-1;
this.duIndxStr="-1:"; this.pfIndxStr="-1:-1:"; this.caIndxStr="-1:";
}
protected void clear() {
this.typesTG_L2.clear();
this.typesTG_NAC2.clear();
this.typesTG_PAC2.clear();
this.contextC1_L1.clear();
this.boundB1_L1.clear();
this.preservedK1_L1.clear();
this.contextC1_R1.clear();
this.boundB1_R1.clear();
this.preservedK1_R1.clear();
this.delete.clear();
this.produce.clear();
this.preservedChanged.clear();
if (this.ac2leftExtended != null)
this.ac2leftExtended.clear();
if (this.attrMember2Expr != null)
this.attrMember2Expr.clear();
}
public void dispose() {
this.clear();
this.typesTG_L2 = null;
this.typesTG_NAC2 = null;
this.typesTG_PAC2 = null;
this.contextC1_L1 = null;
this.boundB1_L1 = null;
this.preservedK1_L1 = null;
this.contextC1_R1 = null;
this.boundB1_R1 = null;
this.preservedK1_R1 = null;
this.delete = null;
this.produce = null;
this.preservedChanged = null;
this.ac2leftExtended = null;
this.attrMember2Expr = null;
this.doneOverlaps = null;
if (this.ownStrategy)
this.strategy = null;
}
public void stop() {
this.stop = true;
}
public void setGraGra(final GraGra grammar) {
this.grammar = grammar;
}
/**
* Returns the number of kind of pairs which will be distinguished. There
* must be at least two kind of pairs. That means one kind has no conflicts
* and the second kind has conflicts.
*
* @return The number of available algorithms.
*/
public int getNumberOfKindOfPairs() {
return 2;
}
public void enableComplete(boolean enable) {
this.complete = enable;
}
/**
* Returns the current maximum number of inclusions to check.
*/
public int getNumberOfInclusions() {
return this.inclCount;
}
/**
* Returns the progress index of the current maximum number of inclusions to check.
*/
public int getProgressOfInclusions() {
return this.inclProgress;
}
/**
* Whether NACs are enabled or not this decision is done by the NAC property
* bit of the morphism completion strategy:
* <code> withNACs = strategy.getProperties().get(CompletionPropertyBits.NAC); </code>
*
* @deprecated replaced by setMorphismCompletionStrategy(MorphCompletionStrategy strat)
*/
public void enableNACs(boolean enable) {
this.withNACs = enable;
}
/**
* Whether PACs are enabled or not this decision is done by the PAC property
* bit of the morphism completion strategy:
* <code> withPACs = strategy.getProperties().get(CompletionPropertyBits.PAC); </code>
*
* @deprecated replaced by setMorphismCompletionStrategy(MorphCompletionStrategy strat)
*/
public void enablePACs(boolean enable) {
this.withPACs = enable;
}
public void enableDirectlyStrictConfluent(boolean enable) {
this.directStrctCnfl = enable;
}
public void enableDirectlyStrictConfluentUpToIso(boolean enable) {
this.directStrctCnflUpToIso = enable;
}
public void enableReduce(boolean enable) {
this.essential = enable;
}
public void enableReduceSameMatch(boolean enable) {
this.reduceSameMatch = enable;
}
public void enableStrongAttrCheck(boolean enable) {
this.strongAttrCheck = enable;
}
public void enableEqualVariableNameOfAttrMapping(boolean enable) {
this.equalVariableNameOfAttrMapping = enable;
}
public void enableConsistent(boolean enable, GraGra gragra) {
this.consistentOnly = enable;
this.grammar = gragra;
}
public void enableNamedObjectOnly(boolean enable) {
this.namedObjectOnly = enable;
}
public void setMaxBoundOfCriticCause(int bound) {
this.maxBoundOfCriticCause = bound;
}
public void setMorphismCompletionStrategy(MorphCompletionStrategy strat) {
this.strategy = strat;
this.dangling = this.strategy.getProperties()
.get(CompletionPropertyBits.DANGLING);
this.withNACs = this.strategy.getProperties().get(CompletionPropertyBits.NAC);
this.withPACs = this.strategy.getProperties().get(CompletionPropertyBits.PAC);
this.withPACs = this.strategy.getProperties().get(CompletionPropertyBits.GAC);
}
public void enableIgnoreIdenticalRules(boolean b) {
this.ignoreIdenticalRules = b;
}
// ****************************************************************************+
/**
* Checks whether this rule pair is critical of the specified kind.
* Returns null if this pair is not critical,
* otherwise returns overlapping morphisms
* which show all found critical situations of these rules.
*
* @param kind
* specifies the algorithm kind of critical pair
* @param r1
* first rule
* @param r2
* second rule
* @throws InvalidAlgorithmException
* Thrown if a illegal algorithm is selected.
* @return critical overlapping of these two rules
*/
public Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
isCritical(int kind, Rule r1, Rule r2)
throws InvalidAlgorithmException {
// if (r1.hasEnabledACs(false) || r2.hasEnabledACs(false)) {
// System.out.println("( "+r1.getName()+" , "+r2.getName()+" )"+" CPA for rules with GACs is not jet supported.");
// throw new InvalidAlgorithmException("CPA for rules with GACs is not jet supported.",
// CriticalPairEvent.NOT_COMPUTABLE);
// }
if (this.ignoreIdenticalRules && r1 == r2) {
if (kind == EXCLUDE)
return null;
else if (kind == CONFLICTFREE)
return null;
else
throw new InvalidAlgorithmException("No such algorithm", kind);
}
this.ownStrategy = false;
if (this.strategy == null) {
this.strategy = (MorphCompletionStrategy) CompletionStrategySelector
.getDefault().clone();
// this.strategy.showProperties();
this.ownStrategy = true;
}
if (kind == EXCLUDE) {
return isExclude(r1, r2);
} else if (kind == CONFLICTFREE) {
return isExclude(r1, r2);
}
else
throw new InvalidAlgorithmException("No such algorithm", kind);
}
protected boolean isProgressIndexSet() {
return (this.duIndx!=-1) || (this.pfIndx!=-1) || (this.caIndx!=-1);
}
/**
* Checks if the first rule exclude the second rule.
*
* @param r1
* The first rule.
* @param r2
* The second rule.
* @return All critical overlappings of this rule pair.
*/
protected Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
isExclude(final Rule r1, final Rule r2) {
// System.out.println("ExcludePair.isExclude:: "+ r1.getName() + ", " + r2.getName());
// if (this.withPACs && r1.hasPACs()) {
// r1.extendByPacs();
// }
// if (this.essential) {
// disable Type Multiplicity and Graph Constraints and NACs checking
// this.disableConstraints();
// }
// else
{
// set Type Multiplicity check to be TypeSet.ENABLED_MAX
this.levelOfTypeGraphCheck = this.grammar.getTypeSet().getLevelOfTypeGraphCheck();
if (this.levelOfTypeGraphCheck > TypeSet.ENABLED_MAX)
this.grammar.getTypeSet().setLevelOfTypeGraph(TypeSet.ENABLED_MAX);
}
// check global NACs of r2 before all other checks;
// if LHS of r1 satisfy a global NAC of r2
// which disregards all node attributes and does not contain any edges,
// then r2 is not applicable in this case and
// this rule pair cannot be critical in general
if (this.withNACs && !checkGlobalNACsOfRule2(r1, r2)) {
// System.out.println("ExcludePair.isExclude:: a global NAC of rule2 FAILED!");
System.out.println("*** ExcludePair.isExclude:: [ "
+ r1.getName() + ", " + r2.getName()
+ " ] non-critical.");
return null;
}
System.gc();
freeM = Runtime.getRuntime().freeMemory();
this.prepareCriticalPairContextData(r1, r2);
boolean
canLHS1OverlapLHS2 = canMatchConstantAttributeLHS1intoLHS2(r1, r2);
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
resultOverlappings = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
if (this.doneOverlaps != null) {
if (!this.doneOverlaps.isEmpty()) {
resultOverlappings.addAll(this.doneOverlaps);
this.doneOverlaps.clear();
this.doneOverlaps = null;
}
}
// check delete-use conflicts
if (!this.isProgressIndexSet() || this.duIndx >= 0) {
if (!this.stop && !this.contextC1_L1.isEmpty() && canLHS1OverlapLHS2) {
if (!this.stop) {
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
deleteUseOverlappings = getDeleteUseConflicts(r1, r2);
if (deleteUseOverlappings != null && !deleteUseOverlappings.isEmpty()) {
// test: CriticalPairData view
// this.inspectCritPair(r1, r2, deleteUseOverlappings);
resultOverlappings.addAll(deleteUseOverlappings);
}
}
}
}
// check produce-forbid conflicts
if (!this.stop
&& (!this.isProgressIndexSet() || this.pfIndx >=0)
&& this.withNACs && !this.contextC1_R1.isEmpty()
&& (this.complete || resultOverlappings.isEmpty())) {
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
produceForbidOverlappings = getProduceForbidConflicts(r1, r2);
if (produceForbidOverlappings != null && !produceForbidOverlappings.isEmpty()) {
// test: CriticalPairData view
// this.inspectCritPair(r1, r2, produceForbidOverlappings);
resultOverlappings.addAll(produceForbidOverlappings);
}
}
// check change-use attribute conflicts
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
changeAttributeOverlappings = null;
if (!this.stop
&& (this.complete || resultOverlappings.isEmpty())) {
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>>
changedAttrsL1 = new Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>>();
// fill preservedChanged vector
if (this.withNACs) {
ruleChangesAttributes(r1, r2, this.contextC1_L1, this.boundB1_L1,
this.preservedK1_L1, changedAttrsL1, this.typesTG_NAC2);
} else {
ruleChangesAttributes(r1, r2, this.contextC1_L1, this.boundB1_L1,
this.preservedK1_L1, changedAttrsL1, this.typesTG_L2);
}
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>>
changedAttrsL2 = new Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>>();
if (this.preservedChanged.isEmpty()
|| !ruleRestrictsAttributes(this.strongAttrCheck, r2, changedAttrsL2, changedAttrsL1)) {
// here do nothing!
} else {
changeAttributeOverlappings = getChangeAttributeConflicts(r1,
r2, changedAttrsL1, changedAttrsL2);
if (changeAttributeOverlappings != null && !changeAttributeOverlappings.isEmpty()) {
resultOverlappings.addAll(changeAttributeOverlappings);
}
}
}
// check produce-delete (dangling edge) conflicts
if (!this.stop
&& !this.checkSwitchDependency
&& this.danglEdge
&& resultOverlappings.isEmpty()) {
resetCriticalPairContextData(r2, r1);
restrictDeleteContextDuetoDanglingEdge();
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
produceDeleteOverlappings = getProduceEdgeDeleteNodeConflicts(r2, r1);
if (produceDeleteOverlappings != null && !produceDeleteOverlappings.isEmpty()) {
resultOverlappings.addAll(produceDeleteOverlappings);
}
}
// set index of the overlapping graphs
for (int i = 0; i < resultOverlappings.size(); i++) {
Pair<OrdinaryMorphism, OrdinaryMorphism> morphisms = resultOverlappings.elementAt(i).first;
int j = i + 1;
Graph overlap = morphisms.first.getImage();
String name = overlap.getName();
if (name.indexOf('(') == 0) {
int ii = name.indexOf(')');
if (ii > 0)
name = overlap.getName().substring(ii+1);
}
overlap.setName("( "+j+" ) "+name);
unsetAllTransientAttrValuesOfOverlapGrah(overlap);
final String r1Prefix = "r1_";
final String r2Prefix = "r2_";
ExcludePairHelper.renameContextVariableOfOverlappingPair(r1, r2, morphisms, r1Prefix, r2Prefix);
}
unsetAllTransientAttrValuesOfRule(r1);
unsetAllTransientAttrValuesOfRule(r2);
this.grammar.getTypeSet().setLevelOfTypeGraph(this.levelOfTypeGraphCheck);
resultOverlappings.trimToSize();
usedM = freeM - Runtime.getRuntime().freeMemory();
if (resultOverlappings.isEmpty()) {
System.out.println("*** ExcludePair.isExclude:: [ "
+ r1.getName() + ", " + r2.getName()
+ " ] non-critical.");
return null;
}
System.out.println("*** ExcludePair.isExclude:: [ "
+ r1.getName() + ", " + r2.getName() + " ] "
+ resultOverlappings.size()
+ " critical overlapping graph(s).");
return resultOverlappings;
}
protected void prepareCriticalPairContextData(final Rule r1, final Rule r2) {
// fill this.typesTG_L2 with types used in LHS of r2
fillTypeSubset(r2.getLeft(), this.typesTG_L2);
// System.out.println("this.typesTG_L2: "+ this.typesTG_L2);
// fill typesTG_PAC2 with types from this.typesTG_L2
// and types used in PACs of r2
if (this.withPACs)
getTypeSubsetLeft_PACs(r2, this.typesTG_L2, this.typesTG_PAC2);
// fill typesTG_NAC2 with types from this.typesTG_L2
// and types used in NACs of r2
if (this.withNACs)
getTypeSubsetLeft_NACs(r2, this.typesTG_L2, this.typesTG_NAC2);
// compute left context, boundary, preserved and delete of r1
if (this.withPACs)
computeLeftC_B_K(r1, this.contextC1_L1, this.boundB1_L1, this.preservedK1_L1,
this.delete, this.typesTG_PAC2);
else
computeLeftC_B_K(r1, this.contextC1_L1, this.boundB1_L1, this.preservedK1_L1,
this.delete, this.typesTG_L2);
// compute right context, boundary, preserved and produce of r1
if (this.withNACs)
computeRightC_B_K(r1, this.contextC1_R1, this.boundB1_R1, this.preservedK1_R1,
this.produce, this.typesTG_NAC2);
else
computeRightC_B_K(r1, this.contextC1_R1, this.boundB1_R1, this.preservedK1_R1,
this.produce, this.typesTG_L2);
// check dangling edge match condition
this.danglEdge = danglingEdgeAfterFirstProduceSecondDelete(r1, r2);
this.typesTG_L2.trimToSize();
this.typesTG_PAC2.trimToSize();
this.typesTG_NAC2.trimToSize();
this.contextC1_L1.trimToSize();
this.boundB1_L1.trimToSize();
this.preservedK1_L1.trimToSize();
this.contextC1_R1.trimToSize();
this.boundB1_R1.trimToSize();
this.preservedK1_R1.trimToSize();
this.delete.trimToSize();
this.produce.trimToSize();
}
private void resetCriticalPairContextData(final Rule r1, final Rule r2) {
// fill this.typesTG_L2 with types used in LHS of r2
this.typesTG_L2.clear();
fillTypeSubset(r2.getLeft(), this.typesTG_L2);
// fill typesTG_PAC2 with types from this.typesTG_L2
// and types used in PACs of r2
this.typesTG_PAC2.clear();
// if (this.withPACs)
// getTypeSubsetLeft_PACs(r2, this.typesTG_L2, this.typesTG_PAC2);
// fill this.typesTG_NAC2 with types from this.typesTG_L2
// and types used in NACs of r2
this.typesTG_NAC2.clear();
// if (this.withNACs)
// getTypeSubsetLeft_NACs(r2, this.typesTG_L2, this.typesTG_NAC2);
// compute left context, boundary, preserved and delete of r1
this.contextC1_L1.clear();
this.boundB1_L1.clear();
this.preservedK1_L1.clear();
this.delete.clear();
// if (this.withPACs)
// computeLeftC_B_K(r1, contextC1_l1, boundB1_l1, preservedK1_l1,
// this.delete, this.typesTG_PAC2);
// else
computeLeftC_B_K(r1, this.contextC1_L1, this.boundB1_L1, this.preservedK1_L1,
this.delete, this.typesTG_L2);
}
private void restrictDeleteContextDuetoDanglingEdge() {
for (int i=0; i<this.delete.size(); i++) {
final GraphObject go = this.delete.get(i);
if (go.isArc() || !this.danglingEdges.contains(go)) {
this.delete.remove(go);
i--;
}
}
}
/**
* Disable type multiplicity (max and min) constraints,
* graph consistency constraints,
* NACs. PACs.
*/
protected void disableConstraints() {
// store current value and disable constraints
this.levelOfTypeGraphCheck = this.grammar.getTypeSet().getLevelOfTypeGraphCheck();
this.grammar.getTypeSet().setLevelOfTypeGraph(TypeSet.ENABLED);
this.consistCheck = this.consistentOnly;
this.consistentOnly = false;
this.withNACsCheck = this.withNACs;
this.withNACs = false;
this.withPACsCheck = this.withPACs;
this.withPACs = false;
}
/**
* Enable type multiplicity constraints,
* graph consistency constraints,
* NACs, PACs.
*/
protected void enableConstraints() {
this.grammar.getTypeSet().setLevelOfTypeGraph(this.levelOfTypeGraphCheck);
this.consistentOnly = this.consistCheck;
this.withNACs = this.withNACsCheck;
this.withPACs = this.withPACsCheck;
}
/**
* Let the first rule r1 be applicable.
* The second rule r2 contains a global NAC which disregards any attributes of nodes
* and does not contain any edges.
* Checks whether the second rule r2 can be applied in this case.
* If not, then this rule pair is not critical.
* @param r1
* @param r2
* @return true if the second rule r2 can be applied
*/
protected boolean checkGlobalNACsOfRule2(final Rule r1, final Rule r2) {
final List<OrdinaryMorphism> nacsR2 = r2.getNACsList();
for (int i=0; i<nacsR2.size(); i++) {
final OrdinaryMorphism nac = nacsR2.get(i);
if (nac.isEnabled()
&& nac.isEmpty() // a global NAC
&& !nac.getTarget().areAnyAttributesOfNodesSet() // attrs of nodes are disregarded
&& !nac.getTarget().getArcsSet().iterator().hasNext()) { // no edges
if (this.strategy.isInjective()) { // injective match strategy
final Iterator<Node> nodes = nac.getTarget().getNodesSet().iterator();
boolean countfailed = true;
while (countfailed && nodes.hasNext()) {
Node n = nodes.next();
List<Node> list = nac.getTarget().getNodes(n.getType());
List<Node> list1 = r1.getLeft().getNodes(n.getType());
List<Node> list2 = r2.getLeft().getNodes(n.getType());
int countInNacGraph = list != null? list.size(): 0;
int countInLHS1 = list1 != null? list1.size(): 0;
int countInLHS2 = list2 != null? list2.size(): 0;
if (countInLHS1 < (countInLHS2+countInNacGraph))
countfailed = false;
}
if (countfailed)
return false;
}
}
}
return true;
}
private MorphCompletionStrategy getLocalMorphismCompletionStrategy() {
if (this.withInheritance)
return new Completion_InheritCSP();
return new Completion_InjCSP();
}
private boolean doCompose(
final MorphCompletionStrategy localStrategy,
final OrdinaryMorphism result,
final OrdinaryMorphism morph1,
final OrdinaryMorphism morph2) {
boolean res;
if (localStrategy instanceof Completion_InheritCSP) {
res = result.doComposeInherit(morph1, morph2);
} else {
res = result.doCompose(morph1, morph2);
}
if (res) {
replaceVarAttrByConstFromSrcToTar(result);
}
return res;
}
private void replaceVarAttrByConstFromSrcToTar(final OrdinaryMorphism m) {
Enumeration<GraphObject> dom = m.getDomain();
while (dom.hasMoreElements()) {
GraphObject obj = dom.nextElement();
GraphObject img = m.getImage(obj);
if (obj.getAttribute() != null
&& img.getAttribute() != null) {
ValueTuple val1 = (ValueTuple) obj.getAttribute();
ValueTuple val2 = (ValueTuple) img.getAttribute();
for (int i=0; i<val1.getNumberOfEntries(); i++) {
ValueMember v1 = val1.getValueMemberAt(i);
if (v1.isSet() && v1.getExpr().isConstant()) {
ValueMember v2 = val2.getValueMemberAt(v1.getName());
if (v2 != null && (!v2.isSet() || !v2.getExpr().isConstant())) {
v2.setExprAsText(v1.getExprAsText());
v2.setTransient(v1.isTransient());
}
}
}
}
}
}
boolean canMatchConstantAttributeLHS1intoLHS2(Rule r1, Rule r2) {
if (!r2.getLeft().getNodesSet().iterator().hasNext()
|| r2.getTypeSet().hasInheritance())
return true;
boolean domExists = false;
boolean domValid = false;
boolean canMatch = true;
Iterator<Node> nodes1 = r1.getLeft().getNodesSet().iterator();
while (nodes1.hasNext()) {
GraphObject go1 = nodes1.next();
// check whether domain exists
HashSet<GraphObject> dom2 = r2.getLeft().getTypeObjectsMap().get(
go1.getType().convertToKey());
if (dom2 == null) {
Vector<Type> parents_go1 = go1.getType().getAllParents();
for (int p=0; p<parents_go1.size(); p++) {
Type pt = parents_go1.get(p);
dom2 = r2.getLeft().getTypeObjectsMap().get(
pt.convertToKey());
if(dom2 != null)
break;
}
if (dom2 == null)
continue;
}
domExists = true;
if (go1.getAttribute() == null) {
domValid = true;
continue;
}
// search for constant attribute value
final Vector<String> attrAsConstant = new Vector<String>();
for (int i = 0; i < go1.getAttribute().getNumberOfEntries(); i++) {
ValueMember vm = (ValueMember) go1.getAttribute()
.getMemberAt(i);
if (vm.isSet() && vm.getExpr().isConstant()) {
attrAsConstant.add(vm.getName());
}
}
if (attrAsConstant.isEmpty()) {
domValid = true;
continue;
}
// now search for constant attr value in domain
Iterator<GraphObject> iter = dom2.iterator();
while (iter.hasNext()) {
GraphObject go2 = iter.next();
canMatch = true;
for (int j = 0; j < attrAsConstant.size(); j++) {
String vmName = attrAsConstant.get(j);
ValueMember vm2 = (ValueMember) go2.getAttribute()
.getMemberAt(vmName);
if ((vm2 == null) || !vm2.isSet() || !vm2.getExpr().isConstant())
continue;
else if (vm2.isSet() && vm2.getExpr().isConstant()) {
ValueMember vm1 = (ValueMember) go1.getAttribute()
.getMemberAt(vmName);
if (!vm2.getExpr().equals(vm1.getExpr())) {
canMatch = false;
break;
}
}
}
if (canMatch) {
domValid = true;
}
}
}
if (!domExists || !domValid)
return false;
return true;
}
/*
* Check constant attributes of a NAC graph of the rule2 agains constant attributes
* of the new graph objects of the RHS of the rule1.
* Note: only free unmapped nodes of a NAC are checked!
*/
boolean canMatchConstAttrOfNAC2intoRHS1(
final OrdinaryMorphism nac2,
final Graph rhs1,
final Vector<GraphObject> tocheckRHS1) {
if (!nac2.getTarget().getNodesSet().iterator().hasNext()
|| nac2.getTarget().getTypeSet().hasInheritance())
return true;
boolean canMatch = true;
boolean domExists = false;
boolean domValid = false;
// take only unmapped nodes of a NAC graph
final Vector<Node> nodes2 = new Vector<Node>();
Iterator<Node> nac2nodes = nac2.getTarget().getNodesSet().iterator();
while (nac2nodes.hasNext()) {
Node go2 = nac2nodes.next();
if (!nac2.getInverseImage(go2).hasMoreElements()) {
// free nodes only
if (go2.getNumberOfInOutArcs() == 0)
nodes2.add(go2);
}
}
for (int k = 0; k < nodes2.size(); k++) {
Node go2 = nodes2.get(k);
// check whether domain exists
HashSet<GraphObject> dom1 = rhs1.getTypeObjectsMap().get(
go2.getType().convertToKey());
if (dom1 == null) {
continue;
}
domExists = true;
if (go2.getAttribute() == null) {
domValid = true;
continue;
}
// search for constant attr value
final Vector<String> attrAsConstant = new Vector<String>();
for (int j = 0; j < go2.getAttribute().getNumberOfEntries(); j++) {
ValueMember vm2 = (ValueMember) go2.getAttribute().getMemberAt(j);
if (vm2.isSet() && vm2.getExpr().isConstant()) {
attrAsConstant.add(vm2.getName());
}
}
if (attrAsConstant.isEmpty()) {
domValid = true;
continue;
}
// search for constant attr value in domain
Iterator<GraphObject> iter = dom1.iterator();
while (iter.hasNext()) {
GraphObject go1 = iter.next();
if (!tocheckRHS1.contains(go1))
continue;
canMatch = true;
for (int j = 0; j < attrAsConstant.size(); j++) {
String vmName = attrAsConstant.get(j);
ValueMember
vm1 = (ValueMember)go1.getAttribute().getMemberAt(vmName);
if ((vm1 == null) || !vm1.isSet() || !vm1.getExpr().isConstant())
continue;
else if (vm1.isSet() && vm1.getExpr().isConstant()) {
ValueMember
vm2 = (ValueMember) go2.getAttribute().getMemberAt(vmName);
if (!vm1.getExpr().equals(vm2.getExpr())) {
canMatch = false;
break;
}
}
}
if (canMatch) {
domValid = true;
// System.out.println("canMatch "+go1.getType().getName()+"
// --> "+go2.getType().getName());
}
}
}
// System.out.println("after node check: domain exists: "+ domExists+"
// canMatchCount: "+ canMatchCount);
/*
// take only unmapped edges of a NAC
Enumeration<Arc> allarcs2 = nac2.getTarget().getArcs();
final Vector<Arc> arcs2 = new Vector<Arc>();
while (allarcs2.hasMoreElements()) {
Arc go2 = allarcs2.nextElement();
if (!nac2.getInverseImage(go2).hasMoreElements())
arcs2.add(go2);
}
for (int k = 0; k < arcs2.size(); k++) {
Arc go2 = arcs2.get(k);
// check whether domain exists
Vector<GraphObject> dom1 = rhs1.getTypeObjectsMap().get(
go2.getTypeMapKey()); // .convertToKey());
if (dom1 == null) {
continue;
}
domExists = true;
if (go2.getAttribute() == null) {
domValid = true;
continue;
}
// search for constant attr value
final Vector<String> attrAsConstant = new Vector<String>();
for (int i = 0; i < go2.getAttribute().getNumberOfEntries(); i++) {
ValueMember vm = (ValueMember) go2.getAttribute()
.getMemberAt(i);
if (vm.isSet() && vm.getExpr().isConstant()) {
attrAsConstant.add(vm.getName());
}
}
if (attrAsConstant.isEmpty()) {
domValid = true;
continue;
}
// search for constant attr value in domain
for (int i = 0; i < dom1.size(); i++) {
GraphObject go1 = dom1.get(i);
if (tocheckRHS1 != null && !tocheckRHS1.contains(go1))
continue;
canMatch = true;
for (int j = 0; j < attrAsConstant.size(); j++) {
String vmName = attrAsConstant.get(j);
ValueMember vm1 = (ValueMember) go1.getAttribute()
.getMemberAt(vmName);
if (!vm1.isSet() || !vm1.getExpr().isConstant())
continue;
else if (vm1.isSet() && vm1.getExpr().isConstant()) {
ValueMember vm2 = (ValueMember) go2.getAttribute()
.getMemberAt(vmName);
if (!vm2.getExpr().equals(vm1.getExpr())) {
canMatch = false;
break;
}
}
}
if (canMatch) {
domValid = true;
// System.out.println("canMatch "+go1.getType().getName()+"
// --> "+go2.getType().getName());
}
}
}
*/
if (domExists && !domValid)
return false;
return true;
}
protected boolean needMoreCheckDueToDelConstAttr(final Rule r1, final Rule r2) {
final List<GraphObject> delObjsLHS1 = r1.getElementsToDelete();
final Hashtable<Type, Vector<GraphObject>> table = new Hashtable<Type, Vector<GraphObject>>();
for (int i = 0; i < delObjsLHS1.size(); i++) {
GraphObject goLHS1 = delObjsLHS1.get(i);
if (this.canMapLeftObjDueToConstAttr(goLHS1, r1, r2, table))
return true;
else
this.contextC1_L1.remove(goLHS1);
}
return false;
}
private boolean canMapLeftObjDueToConstAttr(
final GraphObject goLHS1,
final Rule r1, final Rule r2,
final Hashtable<Type, Vector<GraphObject>> table) {
if (goLHS1.getAttribute() == null
|| goLHS1.getAttribute().getNumberOfEntries() == 0)
return true;
Vector<GraphObject> vec2 = table.get(goLHS1.getType());
if (vec2 == null) {
vec2 = r2.getLeft().getElementsOfTypeAsVector(goLHS1.getType());
if (vec2.isEmpty()) {
Vector<Type> parents = goLHS1.getType().getAllParents();
for (int p = 1; p < parents.size(); p++) {
Type pt = parents.get(p);
Vector<GraphObject> v = r2.getLeft().getElementsOfTypeAsVector(pt);
if (!v.isEmpty())
vec2.addAll(v);
}
}
final Enumeration<OrdinaryMorphism> pacs_r2 = r2.getPACs();
while (pacs_r2.hasMoreElements()) {
final OrdinaryMorphism pac2 = pacs_r2.nextElement();
if (pac2.isEnabled())
vec2.addAll(pac2.getTarget().getElementsOfTypeAsVector(goLHS1.getType()));
}
table.put(goLHS1.getType(), vec2);
}
boolean canMap = true;
ValueTuple vtLHS1 = (ValueTuple) goLHS1.getAttribute();
// search for at least one object to map
for (int k = 0; k < vec2.size(); k++) {
GraphObject goLHS2 = vec2.get(k);
ValueTuple vtLHS2 = (ValueTuple) goLHS2.getAttribute();
canMap = true;
for (int j = 0; j < vtLHS1.getNumberOfEntries(); j++) {
ValueMember vmLHS1 = vtLHS1.getValueMemberAt(j);
if (vmLHS1.isSet() && vmLHS1.getExpr().isConstant()) {
ValueMember vmLHS2 = vtLHS2.getValueMemberAt(vmLHS1.getName());
if (vmLHS2.isSet() && vmLHS2.getExpr().isConstant()
&& !vmLHS2.getExpr().equals(vmLHS1.getExpr())) {
canMap = false;
break;
}
}
}
if (canMap)
break;
}
return canMap;
}
/*
private boolean needMoreCheckWhenProduceConstantAttribute(Rule r1,
OrdinaryMorphism nac2) {
// final Vector<GraphObject> res = new Vector<GraphObject>();
boolean needMoreCheck = true;
int needMoreCheckCount = 0;
List<GraphObject> prodObjsRHS1 = r1.getElementsToCreate();
final Hashtable<Type, Vector<GraphObject>> table = new Hashtable<Type, Vector<GraphObject>>();
for (int i = 0; i < prodObjsRHS1.size(); i++) {
GraphObject goRHS1 = prodObjsRHS1.get(i);
Vector<GraphObject> vec2 = nac2.getTarget()
.getElementsOfTypeAsVector(goRHS1.getType());
for (int j = vec2.size() - 1; j >= 0; j--) {
GraphObject go = vec2.get(j);
if (nac2.getInverseImage(go).hasMoreElements())
vec2.remove(go);
}
if (!vec2.isEmpty()) {
if (goRHS1.getAttribute() == null)
return true;
} else
continue;
ValueTuple vtRHS1 = (ValueTuple) goRHS1.getAttribute();
ValueMember vmRHS1;
for (int j = 0; j < vtRHS1.getNumberOfEntries(); j++) {
vmRHS1 = vtRHS1.getValueMemberAt(j);
if (vmRHS1.isSet() && vmRHS1.getExpr().isConstant()) {
Vector<GraphObject> vec = table.get(goRHS1.getType());
if (vec == null) {
vec = vec2;
if (vec.isEmpty()) {
break;
} else
table.put(goRHS1.getType(), vec);
}
int needMoreCheckLocalCount = 0;
for (int k = 0; k < vec.size(); k++) {
needMoreCheck = true;
GraphObject goNAC2 = vec.get(k);
ValueTuple vtNAC2 = (ValueTuple) goNAC2.getAttribute();
ValueMember vmNAC2;
for (int l = 0; l < vtNAC2.getNumberOfEntries(); l++) {
vmNAC2 = vtNAC2.getValueMemberAt(l);
if (vmNAC2.isSet() && vmNAC2.getExpr().isConstant()) {
// System.out.println(vmRHS1.getExprAsText()+"
// ?= "+vmNAC2.getExprAsText());
if (!vmNAC2.getExpr().equals(vmRHS1.getExpr())) {
needMoreCheck = false;
break;
}
}
}
if (needMoreCheck)
needMoreCheckLocalCount++;
}
if (needMoreCheckLocalCount > 0)
needMoreCheckCount++;
} else
needMoreCheckCount++;
}
}
return (needMoreCheckCount > 0);
}
private boolean needMoreCheckWhenProduceCostantAttribute(
Vector<GraphObject> prodObjsRHS1,
Hashtable<Type, Vector<GraphObject>> type2gosNAC2) {
// System.out.println("ExcludePair.needMoreCheckWhenProduceCostantAttribute
// ");
boolean needMoreCheck = true;
int needMoreCheckCount = 0;
// System.out.println("prodObjsRHS1: "+prodObjsRHS1);
for (int i = 0; i < prodObjsRHS1.size(); i++) {
GraphObject goRHS1 = prodObjsRHS1.get(i);
Vector<GraphObject> vec = type2gosNAC2.get(goRHS1.getType());
// System.out.println("vec: "+vec);
if (!vec.isEmpty()) {
if (goRHS1.getAttribute() == null)
return true;
} else
continue;
ValueTuple vtRHS1 = (ValueTuple) goRHS1.getAttribute();
ValueMember vmRHS1;
for (int j = 0; j < vtRHS1.getNumberOfEntries(); j++) {
vmRHS1 = vtRHS1.getValueMemberAt(j);
if (vmRHS1.isSet() && vmRHS1.getExpr().isConstant()) {
int needMoreCheckLocalCount = 0;
for (int k = 0; k < vec.size(); k++) {
needMoreCheck = true;
GraphObject goNAC2 = vec.get(k);
ValueTuple vtNAC2 = (ValueTuple) goNAC2.getAttribute();
ValueMember vmNAC2;
for (int l = 0; l < vtNAC2.getNumberOfEntries(); l++) {
vmNAC2 = vtNAC2.getValueMemberAt(l);
if (vmNAC2.isSet() && vmNAC2.getExpr().isConstant()) {
// System.out.println(vmRHS1.getExprAsText()+"
// ?= "+vmNAC2.getExprAsText());
if (!vmNAC2.getExpr().equals(vmRHS1.getExpr())) {
needMoreCheck = false;
break;
}
}
}
if (needMoreCheck)
needMoreCheckLocalCount++;
}
if (needMoreCheckLocalCount > 0)
needMoreCheckCount++;
} else
needMoreCheckCount++;
}
}
return (needMoreCheckCount > 0);
}
*/
protected void destroyOverlapping(Pair<OrdinaryMorphism, OrdinaryMorphism> p) {
OrdinaryMorphism om1 = p.first;
OrdinaryMorphism om2 = p.second;
om1.dispose();
om1 = null;
om2.dispose(false, true);
om2 = null;
}
/*
* Here is the max overlapping size of nodes only.
*/
// @SuppressWarnings("unused")
// private int removeInclSmallerMaxOverlap(int maxOverlapSize,
// final Vector<Vector<GraphObject>> inclusions) {
// int maxSize = maxOverlapSize;
// if (this.maxOverlapping) {
// for (int l=0; l<inclusions.size(); l++) {
// final Vector<GraphObject> inclSet = inclusions.get(l);
// int nodeCount = getNodeCount(inclSet);
// if (nodeCount > maxSize) {
// maxSize = nodeCount;
// int i = l-1;
// while (i>=0) {
// inclusions.remove(l);
// l--;
// i--;
// }
// }
// else if (nodeCount < maxSize) {
// inclusions.remove(l);
// l--;
// }
// }
// inclusions.trimToSize();
// }
// return maxSize;
// }
// private int getNodeCount(final List<GraphObject> inclSet) {
// int count = 0;
// for (int i=0; i<inclSet.size(); i++) {
// if (inclSet.get(i).isNode())
// count++;
// }
// return count;
// }
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
doneOverlaps;
@SuppressWarnings("unchecked")
public void setProgressIndx(Entry e) {
this.duIndxStr = e.duIndxStr;
this.pfIndxStr = e.pfIndxStr;
this.caIndxStr = e.caIndxStr;
try {
this.duIndx = Integer.valueOf(this.duIndxStr.split(":")[0]).intValue();
this.pfIndx = Integer.valueOf(this.pfIndxStr.split(":")[0]).intValue();
this.caIndx = Integer.valueOf(this.caIndxStr.split(":")[0]).intValue();
} catch (NumberFormatException ex) {}
if (e.getOverlapping() != null) {
if (this.doneOverlaps == null)
this.doneOverlaps = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
else
this.doneOverlaps.clear();
for (int i=0; i<e.getOverlapping().size(); i++) {
doneOverlaps.add((Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>)e.getOverlapping().get(i));
}
}
}
protected void unsetProgressIndx() {
this.duIndxStr = "";
this.pfIndxStr = "";
this.caIndxStr = "";
this.duIndx = -1;
this.pfIndx = -1;
this.caIndx = -1;
}
private int getDUIndx() {
try {
this.duIndx = Integer.valueOf(this.duIndxStr.split(":")[0]).intValue();
} catch (NumberFormatException ex) {
this.duIndx = -1;
}
// System.out.println("getDUIndx: "+this.duIndx+" "+this.duIndxStr);
return this.duIndx;
}
private String getDUNameIndx() {
try {
return this.duIndxStr.split(":")[1];
} catch (ArrayIndexOutOfBoundsException ex) {}
return "";
}
private void saveDUIndx(int i, String s, boolean switchDep) {
//TODO also for switch dependency
this.duIndx = i;
String swDep = switchDep? "1": "0";
this.duIndxStr = String.valueOf(this.duIndx)
.concat(":").concat(s)
.concat(":").concat(swDep);
}
protected Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getDeleteUseConflicts(
final Rule r1,
final Rule r2) {
System.out.println(" ExcludePair.getDeleteUseConflicts:: [ "
+ r1.getName() + ", " + r2.getName() + " ] ...");
// check constant attribute of deleted objects of r1
// against constant attribute of LHS of r2
// The objects of appropriate type from LHS of r2
// should use this constant attribute
if (!needMoreCheckDueToDelConstAttr(r1, r2))
return null;
this.cpdKind = CriticalPairData.DELETE_USE_CONFLICT;
if (this.essential) {
return this.getEssentialDeleteUseConflicts(r1, r2);
}
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlaps = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
// only for dependency check
if (this instanceof DependencyPair) {
if (!this.checkSwitchDependency
&& this.duIndxStr.endsWith(":1")) {
return overlaps;
}
else if (this.checkSwitchDependency
&& this.duIndxStr.endsWith(":0")) {
this.duIndxStr = "";
}
}
this.inclCount = 0;
this.inclProgress = 0;
this.duIndx = this.getDUIndx();
String duNameIndx = this.duIndxStr.contains(":PAC")? this.getDUNameIndx(): "";
if (this.ac2leftExtended == null)
this.ac2leftExtended = new Hashtable<OrdinaryMorphism,Pair<OrdinaryMorphism, OrdinaryMorphism>>();
final Graph g = r1.getLeft();
int maxSize = r2.getLeft().getSize();
Enumeration<OrdinaryMorphism> pacs2 = r2.getPACs();
boolean lhs_done = false;
boolean perform = true;
while (perform && !this.stop) {
String pacName = "";
// test PACs
OrdinaryMorphism L2isoL2ExtendedByPAC = null;
Pair<OrdinaryMorphism, OrdinaryMorphism> lhs_pac_pair = null;
OrdinaryMorphism pac = null;
if (this.withPACs && pacs2.hasMoreElements()) {
pac = pacs2.nextElement();
if (!pac.isEnabled()
|| (this.duIndx > 0 && this.duIndxStr.contains(":PAC")
&& !pac.getName().equals(duNameIndx))) {
continue;
}
}
Vector<Vector<GraphObject>> inclusions = null;
this.inclAsGraph = false;
int size = maxSize;
size = this.contextC1_L1.size();
if (size > maxSize) size = maxSize;
Vector<Vector<GraphObject>>
contextCombis = ExcludePairHelper.getInclusions(g, size, this.contextC1_L1, true);
// each inclusion should contain at least one object to delete
checkInclusions(contextCombis, this.delete);
if (contextCombis.size() == 0)
break;
if (pac != null) {
boolean pacCritical = ExcludePairHelper.isCriticalPAC(pac, this.delete);
if (pacCritical) {
L2isoL2ExtendedByPAC = r2.getLeft().isomorphicCopy();
if (L2isoL2ExtendedByPAC != null) {
// extend LHS of r2 by a PAC
// images of the PAC objects are disjunct (injective)
lhs_pac_pair = extendLeftGraphByPAC(L2isoL2ExtendedByPAC, pac, false);
pacName = pac.getName();
maxSize = L2isoL2ExtendedByPAC.getTarget().getSize();
lhs_done = true;
}
}
}
if (namedObjectOnly) {
this.checkInclusionsDuetoNamedObject(contextCombis);
if (contextCombis.size() == 0)
break;
}
size = this.preservedK1_L1.size();
if (size > maxSize) size = maxSize;
Vector<Vector<GraphObject>>
preservedCombis = ExcludePairHelper.getPlainCombinedInclusions(
new Vector<GraphObject>(this.preservedK1_L1), size, g);
int ncp = 0; // the number of (contextCombis X preservedCombis)
int nn = 0; // the number of already checked inclusions
int nm = contextCombis.size()-1; // the last index of contextCombis
// start a loop to combine the last vector of context with all preservedCombis
while (nm >= 0 && !this.stop) {
if (preservedCombis.size() > 0) {
if (!contextCombis.isEmpty()) {
// combine one inclusion of contextCombis with all inclusions of preservedCombis
inclusions = ExcludePairHelper.combineFirstWithSecondAboveThird(
maxSize, contextCombis.get(nm), preservedCombis, this.boundB1_L1);
contextCombis.remove(nm); // remove last element
nm = contextCombis.size()-1; // the last index of contextCombis
// reduce inclusions up to this.duIndx
if (this.duIndx > 0 && this.duIndx > nn) {
if ((ncp + inclusions.size()-1) < this.duIndx) {
// the last index of all inclusions is smaller then saved duIndx,
// so continue to combine next context vector with all preservedCombis
ncp = ncp + inclusions.size();
continue;
}
nn = ncp + inclusions.size();
int i=inclusions.size()-1;
while (ncp + inclusions.size() > this.duIndx) {
inclusions.remove(i);
i=inclusions.size()-1;
}
nn = nn - inclusions.size();
// System.out.println(nn+" "+this.duIndx);
ncp = this.duIndx;
this.duIndx = -1; // unset this.duIndx
}
}
}
else if (this.duIndx > 0) {
// reduce contextCombis up to this.duIndx
int i=contextCombis.size()-1;
while (i>=0 && i>=this.duIndx) {
contextCombis.remove(i);
i=contextCombis.size()-1;
}
inclusions = contextCombis;
ncp = this.duIndx;
// unset this.duIndx
this.duIndx = -1;
nm = -1; // break for the while-loop over nm
}
else {
// to compute all inclusions
inclusions = contextCombis;
nm = -1; // break of the while-loop
}
this.inclCount = inclusions.size();
System.out.println("to check inclusions: "+ this.inclCount +" already checked: "+ncp);
int n100 = 0, nn2 = 0; // counter of 100
int i=inclusions.size()-1;
// work from end to begin of the list, make and check inclusion morphisms
while (i>=0 && !this.stop) {
// Vector<GraphObject> inclSet = inclusions.remove(i);
// i=inclusions.size()-1;
Vector<GraphObject> inclSet = inclusions.get(i);
i--;
n100++; // counter of 100
OrdinaryMorphism inclMorphism = makeInclusionMorphism(inclSet, g);
if (inclMorphism == null) {
continue;
}
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
localOverlaps = null;
// get overlappings
if (L2isoL2ExtendedByPAC == null) {
// with LHS of second rule only
localOverlaps = getOverlappingsVectorDeleteUse(r1, r2, inclMorphism);
setGraphNameOfDeleteUseConflict(r1, r2, localOverlaps);
lhs_done = true;
}
else {
// with extended LHS by PAC of second rule
localOverlaps = getOverlappingsVectorDeleteUse(r1, r2, lhs_pac_pair, inclMorphism);
for (int x=0; x<localOverlaps.size(); x++) {
setGraphNameOfDeleteUseConflict(r1, r2, localOverlaps.get(x), pacName);
unsetAllTransientAttrValuesOfOverlapGrah(localOverlaps.get(x).first.first.getTarget());
}
lhs_done = true;
}
this.inclProgress++;
inclMorphism.dispose(true, false); inclMorphism = null;
// unsetAllTransientAttrValuesOfRule(r2);
overlaps.addAll(localOverlaps);
localOverlaps.clear();
localOverlaps = null;
if (!this.complete && !overlaps.isEmpty()) {
break;
}
if (n100 == 100) {
nn2++;
System.out.println("checked inclusions: "+n100*nn2+" to check: "+i);
n100 = 0;
inclusions.trimToSize();
}
} // while (i>=0 && !this.stop) over inclusions
if (stop) {
// set this.duIndx
if (pacName.isEmpty())
this.saveDUIndx(ncp + i, "".concat(":LHS"), this.checkSwitchDependency);
else
this.saveDUIndx(ncp + i, pacName.concat(":PAC"), this.checkSwitchDependency);
System.out.println("DeleteUse conflict: stop at index: "+this.duIndx);
}
// set the number of all valid inclusions
ncp = ncp + this.inclCount;
if (!this.complete && !overlaps.isEmpty()) {
break;
}
// TEST ONLY
if (this.maxBoundOfCriticCause > 0
&& overlaps.size() > this.maxBoundOfCriticCause) {
break;
}
} // while(nm >= 0 && !this.stop) over contextCombis
inclusions = null;
contextCombis = null;
preservedCombis = null;
perform = (this.withPACs && pacs2.hasMoreElements()) || !lhs_done;
} // while (perform && !this.stop) over PACs
if (!stop) {
this.saveDUIndx(-1, "", false);
}
if (this.withPACs) {
pacs2 = r2.getPACs();
while (pacs2.hasMoreElements()) {
// restore constant attribute value
this.replaceVarAttrValueByConst(pacs2.nextElement());
}
}
//test reduce isomorphic
if (!r1.getTypeSet().isArcDirected() && overlaps.size() > 0) {
reduceCriticalPairs(overlaps);
}
System.out.println(" ExcludePair.getDeleteUseConflicts:: [ "
+ r1.getName() + ", " + r2.getName() + " ] " + overlaps.size()
+ " critical overlapping(s)");
overlaps.trimToSize();
this.cpdKind = -1;
System.gc();
return overlaps;
}
protected boolean tryExcludePAC(
Rule r1,
Rule r2,
Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
overlap) {
boolean failed = false;
OrdinaryMorphism om1 = overlap.first.first;
OrdinaryMorphism om2 = overlap.first.second;
Enumeration<GraphObject> gos = om2.getTarget().getElements();
while (!failed && gos.hasMoreElements()) {
GraphObject go = gos.nextElement();
if (om1.getInverseImage(go).hasMoreElements()) {
Enumeration<GraphObject> en2 = om2.getInverseImage(go);
if (en2.hasMoreElements()) {
GraphObject go2 = en2.nextElement();
if (!r2.getLeft().isElement(go2))
failed = true;
}
}
else if (om2.getInverseImage(go).hasMoreElements()) {
failed = true;
}
}
if (!failed) {
Iterator<Arc> arcs = (new Vector<Arc>(om2.getTarget().getArcsSet())).iterator();
while (arcs.hasNext()) {
Arc go = arcs.next();
if (!om1.getInverseImage(go).hasMoreElements()
&& !om2.getInverseImage(go).hasMoreElements()) {
try {
om2.getTarget().destroyArc(go, false, true);
} catch (TypeException ex) {failed = true;}
}
}
Iterator<Node> nodes = (new Vector<Node>(om2.getTarget().getNodesSet())).iterator();
while (nodes.hasNext()) {
Node go = nodes.next();
if (!om1.getInverseImage(go).hasMoreElements()
&& !om2.getInverseImage(go).hasMoreElements()) {
try {
om2.getTarget().destroyNode(go, false, true);
} catch (TypeException ex) {failed = true;}
}
}
if (!failed) {
overlap.second = null;
return true;
}
}
return false;
}
protected void setGraphNameOfDeleteUseConflict(Rule r1, Rule r2,
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlaps) {
// mark critical objects
for (int i = 0; i < overlaps.size(); i++) {
final Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
pi = overlaps.get(i);
final Graph overlapGraph = pi.first.first.getTarget();
// set name of overlap graph
if ((this instanceof DependencyPair)
&& !this.checkSwitchDependency) {
if (overlapGraph.getName().indexOf("produce-need(PAC:") == -1) {
overlapGraph.setName(CriticalPairData.PRODUCE_USE_D_TXT); //"produce-use-dependency");
}
pi.first.first.setName("MorphOf_"+r1.getName());
pi.first.second.setName("MorphOf_"+r2.getName());
}
else {
if (overlapGraph.getName().indexOf("delete-need(PAC:") == -1) {
overlapGraph.setName(CriticalPairData.DELETE_USE_C_TXT); //"delete-use-conflict");
// graph name containing a PAC name is set in getOverlappingsVectorDeleteUse
}
pi.first.first.setName("MorphOf_"+r1.getName());
pi.first.second.setName("MorphOf_"+r2.getName());
}
}
}
protected void setGraphNameOfDeleteUseConflict(Rule r1, Rule r2,
final Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
overlap,
final String pacName) {
// mark critical objects
final Graph overlapGraph = overlap.first.first.getTarget();
// set name of overlap graph
if ((this instanceof DependencyPair)
&& !this.checkSwitchDependency) {
if (overlapGraph.getName().indexOf("produce-need(PAC:") == -1) {
overlapGraph.setName(CriticalPairData.PRODUCE_USE_D_TXT); //"produce-use-dependency");
}
if (pacName != null && pacName.length() != 0) {
overlapGraph.setName(CriticalPairData.PRODUCE_USE_D_TXT+" (PAC: " + pacName+ ")");
overlapGraph.setHelpInfo("PAC:"+pacName);
}
overlap.first.first.setName("MorphOf_"+r1.getName());
overlap.first.second.setName("MorphOf_"+r2.getName());
}
else {
if (overlapGraph.getName().indexOf("delete-need(PAC:") == -1) {
overlapGraph.setName(CriticalPairData.DELETE_USE_C_TXT); //"delete-use-conflict");
// graph name containing a PAC name is set in getOverlappingsVectorDeleteUse
}
if (pacName != null && pacName.length() != 0) {
// overlapGraph.setName(CriticalPairData.DELETE_USE_C_TXT);
overlapGraph.setName(CriticalPairData.DELETE_USE_C_TXT+" (PAC: " + pacName+ ")");
overlapGraph.setHelpInfo("PAC:"+pacName);
}
overlap.first.first.setName("MorphOf_"+r1.getName());
overlap.first.second.setName("MorphOf_"+r2.getName());
}
}
/*
private boolean isProduceDelete(
final Graph overlapGraph,
final Pair<OrdinaryMorphism, OrdinaryMorphism> cpair,
final Rule r2) {
Enumeration<GraphObject> dom2 = cpair.second.getDomain();
while (dom2.hasMoreElements()) {
GraphObject go2 = dom2.nextElement();
GraphObject go = cpair.second.getImage(go2);
if (go.isCritical() && r2.getImage(go2) == null)
return true;
}
return false;
}
*/
private Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getEssentialDeleteUseConflicts(
final Rule r1,
final Rule r2) {
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlaps = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
this.cpdKind = CriticalPairData.DELETE_USE_CONFLICT;
// only for dependency check
if (this instanceof DependencyPair) {
if (!this.checkSwitchDependency
&& this.duIndxStr.endsWith(":1")) {
return overlaps;
}
else if (this.checkSwitchDependency
&& this.duIndxStr.endsWith(":0")) {
this.duIndxStr = "";
}
}
this.inclCount = 0;
this.inclProgress = 0;
this.duIndx = this.getDUIndx();
String duNameIndx = this.duIndxStr.contains(":PAC")? this.getDUNameIndx(): "";
Enumeration<OrdinaryMorphism> pacs2 = r2.getPACs();
final Graph g = r1.getLeft();
int maxSize = r2.getLeft().getSize();
int size = maxSize;
// check NACs and add found objs to contextC1_l1
// and remove from preservedK1_l1
// findMorphismNACintoRHSAndAddToContext(r1, true, contextC1_l1,
// preservedK1_l1, this.typesTG_L2, this.delete);
// check multiplicity max==1 and add such objs to contextC1_l1 and
// remove from preservedK1_l1
// addToContextIfTypeMaxMultiplicitySet(r1.getLeft(), contextC1_l1,
// preservedK1_l1, this.typesTG_L2);
this.inclAsGraph = false;
boolean lhs_done = false;
boolean perform = true;
while (perform && !this.stop) {
String pacName = "";
// test PACs
OrdinaryMorphism L2isoL2ExtendedByPACs = null;
Pair<OrdinaryMorphism, OrdinaryMorphism> lhs_pac_pair = null;
OrdinaryMorphism pac = null;
if (this.withPACs && pacs2.hasMoreElements()) {
pac = pacs2.nextElement();
if (this.duIndx > 0
&& !duNameIndx.isEmpty()
&& !pac.getName().equals(duNameIndx))
continue;
}
Vector<Vector<GraphObject>> inclusions = null;
size = this.contextC1_L1.size();
if (size > maxSize) size = maxSize;
Vector<Vector<GraphObject>>
contextCombis = ExcludePairHelper.getInclusions(g, size, this.contextC1_L1, true);
// each inclusion should contain at least one object to delete
checkInclusions(contextCombis, this.delete);
if (contextCombis.size() == 0)
break;
if (pac != null) {
if (pac.isEnabled()) {
boolean pacCritical = ExcludePairHelper.isCriticalPAC(pac, this.delete);
if (pacCritical) {
L2isoL2ExtendedByPACs = r2.getLeft().isomorphicCopy();
if (L2isoL2ExtendedByPACs != null) {
// extend LHS of r2 by a PAC
// images of the PAC objects are disjunct (injective)
lhs_pac_pair = extendLeftGraphByPAC(L2isoL2ExtendedByPACs, pac, false);
pacName = pac.getName();
maxSize = L2isoL2ExtendedByPACs.getTarget().getSize();
lhs_done = true;
}
}
}
}
if (namedObjectOnly) {
this.checkInclusionsDuetoNamedObject(contextCombis);
if (contextCombis.size() == 0)
break;
}
int nn = 0;
if (!this.stop) {
if (this.duIndx > 0) {
// copy not computed inclusions
inclusions = new Vector<Vector<GraphObject>>();
for (int i=0; i<this.duIndx && i<contextCombis.size(); i++) {
inclusions.add(contextCombis.get(i));
}
nn = contextCombis.size() - this.duIndx;
this.duIndx = -1;
}
else {
inclusions = contextCombis;
}
this.inclCount = inclusions.size();
System.out.println("to check essential inclusions: "+ this.inclCount +" already checked: "+nn);
nn = nn+inclusions.size();
// help for system.out.println
int nn100 = 0;
int nn2 = 0;
// make and check inclusion morphism
int i=inclusions.size()-1;
while (i >= 0 && !this.stop) {
// Vector<GraphObject> inclSet = inclusions.remove(i);
// i=inclusions.size()-1;
Vector<GraphObject> inclSet = inclusions.get(i);
i--;
nn100++; // counter of 100
OrdinaryMorphism inclMorphism = makeInclusionMorphism(inclSet, g);
if (inclMorphism == null) {
continue;
}
// get overlapping
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
localOverlaps = null;
if (L2isoL2ExtendedByPACs == null) {
localOverlaps = getOverlappingsVectorDeleteUse(r1, r2, inclMorphism);
setGraphNameOfDeleteUseConflict(r1, r2, localOverlaps);
lhs_done = true;
}
else {
localOverlaps = getOverlappingsVectorDeleteUse(r1, r2, lhs_pac_pair, inclMorphism);
for (int x=0; x<localOverlaps.size(); x++) {
setGraphNameOfDeleteUseConflict(r1, r2, localOverlaps.get(x), pacName);
}
lhs_done = true;
}
this.inclProgress++;
inclSet.clear();
inclMorphism.dispose(true, false);
inclMorphism = null;
overlaps.addAll(localOverlaps);
localOverlaps.clear();
if (!this.complete && !overlaps.isEmpty()) {
break;
}
if (nn100 == 100) {
nn2++;
System.out.println("checked inclusions: "+(nn100*nn2));
nn100 = 0;
}
if (stop) {
break;
}
} // while (i>=0 && !this.stop)
if (stop) {
// set this.duIndx
if (pacName.isEmpty())
this.saveDUIndx(i, "", this.checkSwitchDependency);
else
this.saveDUIndx(i, pacName, this.checkSwitchDependency);
System.out.println("DeleteUse conflict: stop at index: "+this.duIndx);
break;
}
if (!this.complete && !overlaps.isEmpty()) {
break;
}
}
contextCombis = null;
inclusions = null;
perform = (this.withPACs && pacs2.hasMoreElements()) || !lhs_done;
}// while(perform && !stop)
if (!stop) {
this.saveDUIndx(-1, "", false);
}
if (this.withPACs) {
pacs2 = r2.getPACs();
while (pacs2.hasMoreElements()) {
// restore constant attribute value
this.replaceVarAttrValueByConst(pacs2.nextElement());
}
}
System.out.println(" ExcludePair.getDeleteUseConflicts:: [ "
+ r1.getName() + ", " + r2.getName() + " ] " + overlaps.size()
+ " critical overlapping(s)");
overlaps.trimToSize();
this.cpdKind = -1;
return overlaps;
}
private Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getProduceEdgeDeleteNodeConflicts(
final Rule r1,
final Rule r2) {
System.out.println(" ExcludePair.getProduceEdgeDeleteNodeConflicts:: [ "
+ r2.getName() + ", " + r1.getName() + " ] ...");
this.cpdKind = CriticalPairData.PRODUCE_EDGE_DELTE_NODE_CONFLICT;
this.inclCount = 0;
// NOTE: r1 deletes node, r2 used node and produce an edge at it
//
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlaps = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
// generate critical inclusions as Hashtable:
// - key is Integer(size) of inclusion,
// - object is Vector with GraphObjects;
// each inclusion should contain at least one graph object to be deleted
final Graph g = r1.getLeft();
int maxSize = r2.getLeft().getSize();
int size = maxSize;
Vector<Vector<GraphObject>> inclusions;
this.inclAsGraph = false;
size = this.contextC1_L1.size();
if (size > maxSize)
size = maxSize;
Vector<Vector<GraphObject>>
contextCombis = ExcludePairHelper.getInclusions(g, size, this.contextC1_L1, true);
checkInclusions(contextCombis, this.delete);
if (contextCombis.size() > 0) {
if (namedObjectOnly)
this.checkInclusionsDuetoNamedObject(contextCombis);
}
if (contextCombis.size() > 0) {
if (this.essential) {
inclusions = contextCombis;
System.out.println("essential inclusions : "+inclusions.size());
}
else {
size = this.preservedK1_L1.size();
if (size > maxSize)
size = maxSize;
Vector<Vector<GraphObject>>
preservedCombis = ExcludePairHelper.getPlainCombinedInclusions(
new Vector<GraphObject>(this.preservedK1_L1), size, g);
inclusions = ExcludePairHelper.combineInclusions(maxSize, contextCombis,
preservedCombis, this.boundB1_L1);
contextCombis.removeAllElements();
preservedCombis.removeAllElements();
contextCombis = null;
preservedCombis = null;
}
System.out.println("to check inclusions: "+inclusions.size());
// make and check inclusion morphism
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
localOverlaps = null;
while (inclusions.size() > 0 && !this.stop) {
this.inclCount = inclusions.size();
Vector<GraphObject> inclSet = inclusions.get(0);
inclusions.remove(inclSet);
OrdinaryMorphism inclMorphism = makeInclusionMorphism(inclSet, g);
// System.out.println("inclMorphism: "+inclMorphism);
if (inclMorphism == null) {
continue;
}
// get overlappings
localOverlaps = getOverlappingsVectorDeleteUse(r1, r2, inclMorphism);
inclSet.clear();
inclMorphism.dispose(true, false);
//TEST
//this.inspectCritPair(r1, r2, localOverlaps);
// mark critical objects
for (int i = 0; i < localOverlaps.size(); i++) {
final Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
pi = localOverlaps.get(i);
OrdinaryMorphism m1 = pi.first.first;
OrdinaryMorphism m2 = pi.first.second;
if (this.danglingEdge(r1, r2, m1, m2)) {
// set name of the overlap graph
// m1.getTarget().setName("produceEdge-deleteNode-conflict");
m1.getTarget().setName(CriticalPairData.PRODUCE_EDGE_DELETE_NODE_C_TXT);
// to check this conflict the rules are changed: r1 is rule2 and r2 is rule1
// so change m1 and m2 to get right order for (rule1, rule2)
pi.first.first = m2;
pi.first.second = m1;
} else {
localOverlaps.remove(i);
i--;
}
}
overlaps.addAll(localOverlaps);
localOverlaps.clear();
if (!this.complete && !overlaps.isEmpty()) {
break;
}
}
}
inclusions = null;
System.out.println(" ExcludePair.getProduceEdgeDeleteNodeConflicts:: [ "
+ r2.getName() + ", " + r1.getName() + " ] " + overlaps.size()
+ " critical overlapping(s)");
overlaps.trimToSize();
this.cpdKind = -1;
return overlaps;
}
private void markDeleteUseCriticalObject(
final Rule r2,
final Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>> pi) {
String pacName = "";
OrdinaryMorphism m1 = pi.first.first;
OrdinaryMorphism m2 = pi.first.second;
Iterator<?> en = m1.getTarget().getNodesSet().iterator();
while (en.hasNext()) {
GraphObject o = (GraphObject) en.next();
if (m1.getInverseImage(o).hasMoreElements()) {
GraphObject go1 = m1.getInverseImage(o).nextElement();
if (m2.getInverseImage(o).hasMoreElements()) {
if (this.delete.contains(go1)) {
o.setCritical(true);
}
} else if (pi.second != null) {
// get PAC of r2
OrdinaryMorphism pac_r2 = pi.second.first.compose(pi.second.second);
if (pac_r2.getInverseImage(o).hasMoreElements()) {
GraphObject go2 = pac_r2
.getInverseImage(o).nextElement();
if (this.delete.contains(go1)) {
o.setCritical(true);
pacName = go2.getContext().getName();
}
}
}
}
}
en = m1.getTarget().getArcsSet().iterator();
while (en.hasNext()) {
GraphObject o = (GraphObject) en.next();
if (m1.getInverseImage(o).hasMoreElements()) {
GraphObject go1 = m1.getInverseImage(o).nextElement();
if (m2.getInverseImage(o).hasMoreElements()) {
if (this.delete.contains(go1))
o.setCritical(true);
} else if (pi.second != null) {
// get PAC of r2
OrdinaryMorphism pac_r2 = pi.second.first.compose(pi.second.second);
if (pac_r2.getInverseImage(o).hasMoreElements()) {
GraphObject go2 = pac_r2
.getInverseImage(o).nextElement();
if (this.delete.contains(go1)) {
o.setCritical(true);
pacName = go2.getContext().getName();
}
}
}
}
}
if (!"".equals(pacName)) {
// set name of overlap graph with PAC
if (this instanceof DependencyPair) {
m1.getTarget().setName(CriticalPairData.PRODUCE_NEED_D_TXT + " (PAC: " + pacName + ")");
} else {
m1.getTarget().setName(CriticalPairData.DELETE_NEED_C_TXT + " (PAC: " + pacName + ")");
}
}
}
private void markProduceForbidCriticalObject(
final Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>> p) {
Pair<OrdinaryMorphism, OrdinaryMorphism> p1 = p.first;
Pair<OrdinaryMorphism, OrdinaryMorphism> p2 = p.second;
OrdinaryMorphism m1 = p1.first;
OrdinaryMorphism m2 = p1.second;
OrdinaryMorphism isoL2 = p2.first;
OrdinaryMorphism isoNAC2 = p2.second;
Iterator<?> gos = m1.getTarget().getNodesSet().iterator();
while (gos.hasNext()) {
GraphObject o = (GraphObject) gos.next();
if (m1.getInverseImage(o).hasMoreElements()) {
if (m2.getInverseImage(o).hasMoreElements()) {
GraphObject go = m1.getInverseImage(o).nextElement();
if (this.produce.contains(go))
o.setCritical(true);
} else if (isoL2.getInverseImage(o).hasMoreElements()) {
GraphObject go = isoL2.getInverseImage(o).nextElement();
if (this.produce.contains(go))
o.setCritical(true);
} else if (isoNAC2 != null) {
if (isoNAC2.getInverseImage(o).hasMoreElements()) {
GraphObject go = isoNAC2.getInverseImage(o).nextElement();
if (this.produce.contains(go))
o.setCritical(true);
}
}
}
}
gos = m1.getTarget().getArcsSet().iterator();
while (gos.hasNext()) {
GraphObject o = (GraphObject) gos.next();
if (m1.getInverseImage(o).hasMoreElements()) {
if (m2.getInverseImage(o).hasMoreElements()) {
GraphObject go = m1.getInverseImage(o).nextElement();
if (this.produce.contains(go))
o.setCritical(true);
} else if (isoL2.getInverseImage(o).hasMoreElements()) {
GraphObject go = isoL2.getInverseImage(o).nextElement();
if (this.produce.contains(go))
o.setCritical(true);
} else if (isoNAC2 != null) {
if (isoNAC2.getInverseImage(o).hasMoreElements()) {
GraphObject go = isoNAC2.getInverseImage(o).nextElement();
if (this.produce.contains(go))
o.setCritical(true);
}
} else if (m1.getInverseImage(o).hasMoreElements()) {
GraphObject go = m1.getInverseImage(o).nextElement();
if (this.produce.contains(go))
o.setCritical(true);
}
}
}
}
@SuppressWarnings("unused")
private OrdinaryMorphism getPAC(Rule r, GraphObject goOfPAC) {
final List<OrdinaryMorphism> pacs = r.getPACsList();
for (int l=0; l<pacs.size(); l++) {
final OrdinaryMorphism pac = pacs.get(l);
Iterator<?> elems = pac.getTarget().getNodesSet().iterator();
while (elems.hasNext()) {
GraphObject go = (GraphObject) elems.next();
if (goOfPAC == go || goOfPAC.getContextUsage() == go.hashCode())
return pac;
}
elems = pac.getTarget().getArcsSet().iterator();
while (elems.hasNext()) {
GraphObject go = (GraphObject) elems.next();
if (goOfPAC == go || goOfPAC.getContextUsage() == go.hashCode())
return pac;
}
}
return null;
}
/*
private List<Type> getPotentialCriticalTypesOfProduceUse(final Rule r1, final Rule r2) {
final List<Type> list = new Vector<Type>();
final List<Type> list1 = r1.getTypeOfObjectToCreate();
final List<Type> list2 = r2.getTypesOfLeftGraph();
for (int i=0; i<list2.size(); i++) {
Type t2 = list2.get(i);
for (int j=0; j<list1.size(); j++) {
Type t1 = list1.get(j);
if (t2.isRelatedTo(t1)
&& !list.contains(t2)) {
list.add(t2);
}
}
}
return list;
}
private List<Type> getPotentialCriticalTypesOfDeleteUse(final Rule r1, final Rule r2) {
final List<Type> list = new Vector<Type>();
final List<Type> list1 = r1.getTypeOfObjectToDelete();
final List<Type> list2 = r2.getTypesOfLeftGraph();
for (int i=0; i<list2.size(); i++) {
Type t2 = list2.get(i);
for (int j=0; j<list1.size(); j++) {
Type t1 = list1.get(j);
if (t2.isRelatedTo(t1)
&& !list.contains(t2)) {
list.add(t2);
}
}
}
return list;
}
*/
private Vector<OrdinaryMorphism> getPotentialCriticalNACsOfR2(final Rule r,
final Vector<GraphObject> toproduce) {
Vector<OrdinaryMorphism> result = new Vector<OrdinaryMorphism>();
final List<OrdinaryMorphism> nacs = r.getNACsList();
for (int l=0; l<nacs.size(); l++) {
final OrdinaryMorphism nac = nacs.get(l);
if (!nac.isEnabled())
continue;
Hashtable<Type, Vector<GraphObject>>
type2gosNAC2 = new Hashtable<Type, Vector<GraphObject>>();
boolean nacMaybeCritical = false;
boolean nacAttrConst = false;
boolean attrConst = false;
for (int j = 0; j < toproduce.size() && !nacMaybeCritical; j++) {
GraphObject o = toproduce.get(j);
Vector<GraphObject> v = type2gosNAC2.get(o.getType());
if (v == null) {
v = nac.getTarget().getElementsOfTypeAsVector(o.getType());
type2gosNAC2.put(o.getType(), v);
for (int i=0; i<v.size(); i++) {
GraphObject go = v.get(i);
if (nac.getInverseImage(go).hasMoreElements()) {
v.remove(go);
i--;
}
}
}
for (int i=0; i<v.size() && !nacMaybeCritical; i++) {
GraphObject go = v.get(i);
if (!nac.getInverseImage(go).hasMoreElements()) {
if (go.getAttribute() != null) {
for (int k=0; k<go.getAttribute().getNumberOfEntries(); k++) {
ValueMember vm_nac = (ValueMember)go.getAttribute().getMemberAt(k);
if (vm_nac.isSet() /*&& vm_nac.getExpr().isConstant()*/) {
nacAttrConst = true;
attrConst = true;
ValueMember vm = (ValueMember)o.getAttribute().getMemberAt(vm_nac.getName());
if (vm.isSet()) {
if (vm_nac.getExpr().isConstant() && vm.getExpr().isConstant()
&& !vm.getExprAsText().equals(vm_nac.getExprAsText())) {
attrConst = false;
break;
}
}
}
}
nacMaybeCritical = nacAttrConst && attrConst;
}
else {
nacMaybeCritical = true;
}
}
}
}
if (nacMaybeCritical) {
// System.out.println("ExcludePair.getPotentialCriticalNACsOfR2: nac: "+nac.getName());
result.add(nac);
}
}
result.trimToSize();
return result;
}
private boolean danglingEdgeAfterFirstProduceSecondDelete(
final Rule r1,
final Rule r2) {
if (this instanceof DependencyPair) {
return false;
}
// System.out.println("ExcludePair.danglingEdgeAfterFirsProduceSecondDelete: of rule: "+r1.getName()+ " , "+r1.getName());
boolean result = false;
final List<GraphObject> objToDelete = r2.getElementsToDelete();
for (int i=0; i<objToDelete.size(); i++) {
final GraphObject go = objToDelete.get(i);
if (go.isNode()) {
final Enumeration<GraphObject> objsOfType = r1.getRight().getElementsOfType(go.getType());
while (objsOfType.hasMoreElements()) {
final GraphObject o = objsOfType.nextElement();
Iterator<Arc> arcs = ((Node)o).getOutgoingArcsSet().iterator();
while (arcs.hasNext()) {
final Arc arc = arcs.next();
if (!r1.getInverseImage(arc).hasMoreElements()) {
if (!this.danglingEdges.contains(go))
this.danglingEdges.add(go);
result = true;
}
}
arcs = ((Node)o).getIncomingArcsSet().iterator();
while (arcs.hasNext()) {
final Arc arc = arcs.next();
if (!r1.getInverseImage(arc).hasMoreElements()) {
if (!this.danglingEdges.contains(go))
this.danglingEdges.add(go);
result = true;
}
}
}
}
}
return result;
}
private boolean danglingEdge(
final Rule r1,
final Rule r2,
final OrdinaryMorphism m1,
final OrdinaryMorphism m2) {
// System.out.println("ExcludePair.danglingEdge: of rule: "+r1.getName()+ " , "+r2.getName());
boolean result = false;
final Iterator<Node> objs = m1.getTarget().getNodesSet().iterator();
while (objs.hasNext()) {
final Node go = objs.next();
if (!result && go.isCritical()) {
if (m1.getInverseImage(go).hasMoreElements()
&& m2.getInverseImage(go).hasMoreElements()) {
// final Node go1 = (Node) m1.getInverseImage(go).nextElement();
final Node go2 = (Node) m2.getInverseImage(go).nextElement();
final Node img2 = (Node) r2.getImage(go2);
if (img2 != null) {
Iterator<Arc> arcs = img2.getOutgoingArcsSet().iterator();
while (arcs.hasNext()) {
final Arc arc = arcs.next();
if (!r2.getInverseImage(arc).hasMoreElements()) {
result = true;
break;
}
}
arcs = img2.getIncomingArcsSet().iterator();
while (arcs.hasNext()) {
final Arc arc = arcs.next();
if (!r2.getInverseImage(arc).hasMoreElements()) {
result = true;
break;
}
}
}
}
}
}
final Iterator<Arc> objs1= m1.getTarget().getArcsSet().iterator();
while (objs1.hasNext()) {
final Arc go = objs1.next();
if (go.isCritical()) {
go.setCritical(false);
}
}
return result;
}
private int getPFIndx() {
try {
this.pfIndx = Integer.valueOf(this.pfIndxStr.split(":")[0]).intValue();
} catch (NumberFormatException ex) {
this.pfIndx = -1;
}
// System.out.println("getPFIndx: "+this.pfIndx+" "+this.pfIndxStr);
return this.pfIndx;
}
private String getPFNameIndx() {
try {
return this.pfIndxStr.split(":")[2];
} catch (ArrayIndexOutOfBoundsException ex) {}
return "";
}
private int getPFIndx2() {
try {
return Integer.valueOf(this.pfIndxStr.split(":")[1]).intValue();
} catch (ArrayIndexOutOfBoundsException ex) {}
return -1;
}
private void savePFIndx(int i, int pci, String s, boolean switchDep) {
//TODO also for switch dependency
this.pfIndx = i;
String swDep = switchDep? "1": "0";
this.pfIndxStr = String.valueOf(this.pfIndx)
.concat(":").concat(String.valueOf(pci))
.concat(":").concat(s)
.concat(":").concat(swDep);
}
private Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getProduceForbidConflicts(
final Rule r1,
final Rule r2) {
System.out.println(" ExcludePair.getProduceForbidConflicts:: [ "
+ r1.getName() + ", " + r2.getName() + " ] ... ");
final Vector<OrdinaryMorphism>
potentialCriticalNACsOfR2 = this.getPotentialCriticalNACsOfR2(r2, this.produce);
if (potentialCriticalNACsOfR2.isEmpty()) {
return null;
}
this.cpdKind = CriticalPairData.PRODUCE_FORBID_CONFLICT;
if (this.essential) {
return this.getEssentialProduceForbidConflicts(r1, r2, potentialCriticalNACsOfR2);
}
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlaps = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
// only for dependency check
if (this instanceof DependencyPair) {
if (!this.checkSwitchDependency
&& this.pfIndxStr.endsWith(":1")) {
return overlaps;
}
else if (this.checkSwitchDependency
&& this.pfIndxStr.endsWith(":0")) {
this.pfIndxStr = "";
}
}
this.inclCount = 0;
this.inclProgress = 0;
this.pfIndx = this.getPFIndx();
String pfNameIndx = this.getPFNameIndx();
int pfIndxPCI = this.getPFIndx2();
if (this.ac2leftExtended == null)
this.ac2leftExtended = new Hashtable<OrdinaryMorphism,Pair<OrdinaryMorphism, OrdinaryMorphism>>();
final Graph g = r1.getRight();
// generate critical inclusions as Hashtable:
// - key is Integer(size) of inclusion,
// - object is Vector with its GraphObjects;
// each inclusion should contain at least one graph object to be produced
this.inclAsGraph = false;
// make context combis
int size = this.contextC1_R1.size();
Vector<Vector<GraphObject>>
contextCombis = ExcludePairHelper.getInclusions(g, size, this.contextC1_R1, true);
checkInclusions(contextCombis, this.produce);
if (contextCombis.size() > 0) {
if (namedObjectOnly)
this.checkInclusionsDuetoNamedObject(contextCombis);
}
if (contextCombis.size() > 0) {
// make preserved combis
size = this.preservedK1_R1.size();
Vector<Vector<GraphObject>>
preservedCombisAll = ExcludePairHelper.getPlainCombinedInclusions(this.preservedK1_R1, size, g);
Vector<Vector<GraphObject>>
inclusions = new Vector<Vector<GraphObject>>();
// to start the while-loop
Vector<GraphObject> preservedCombis = null;
boolean contextCombisDone = (pfIndxPCI >= 0);
boolean perform = !contextCombis.isEmpty();
int pci = -1;
while (!this.stop && perform) {
// System.out.println(pfIndx+" "+pfIndxPCI+" "+pfNameIndx);
if (contextCombisDone) {
if (pfIndxPCI >= 0) {
int i = preservedCombisAll.size()-1;
while (i > pfIndxPCI) {
preservedCombisAll.remove(i);
i = preservedCombisAll.size()-1;
}
pfIndxPCI = -1;
}
pci = preservedCombisAll.size()-1;
if (!preservedCombisAll.isEmpty()) {
preservedCombis = preservedCombisAll.remove(pci);
}
else {
perform = false;
break;
}
}
int ncp = 0;
// do loop over NACs
final Enumeration<OrdinaryMorphism> nacs2 = potentialCriticalNACsOfR2.elements();
while (!this.stop && nacs2.hasMoreElements()) {
OrdinaryMorphism nac = nacs2.nextElement();
// to continue stopped CPA get the stopped NAC
if (!pfNameIndx.isEmpty()) {
if (this.pfIndx >= 0 && nac.getName().equals(pfNameIndx)) {
pfNameIndx = "";
if (this.pfIndx == 0) {
this.pfIndx = -1;
continue;
}
}
else
continue;
}
Pair<OrdinaryMorphism, OrdinaryMorphism>
extendedL2isoPair = this.ac2leftExtended.get(nac);
if (extendedL2isoPair == null)
extendedL2isoPair = extendGraphForProduceForbidConflict(r2.getLeft(), nac);
if (extendedL2isoPair != null)
this.ac2leftExtended.put(nac, extendedL2isoPair);
else
continue;
Vector<Vector<GraphObject>>
workInclusions = new Vector<Vector<GraphObject>>();
int maxSize = 0;
if (contextCombisDone) {
// combine context with preserved
if (extendedL2isoPair.first.getTarget().getSize() > maxSize) {
maxSize = extendedL2isoPair.first.getTarget().getSize();
inclusions = ExcludePairHelper.combineInclusionsOf(
maxSize, contextCombis,
preservedCombis, this.boundB1_R1);
workInclusions.addAll(inclusions);
}
// else if (extendedL2isoPair.first.getTarget().getSize() < maxSize) {
// maxSize = extendedL2isoPair.first.getTarget().getSize();
// workInclusions.addAll(removeInclusionBiggerMaxSize(maxSize, inclusions));
// }
// else {
// workInclusions.addAll(inclusions);
// }
} else {
workInclusions.addAll(contextCombis);
}
if (workInclusions.size() > 0) {
if (this.pfIndx > 0 && this.pfIndx < workInclusions.size()) {
// reduce inclusions up to this.pfIndx
int i = workInclusions.size()-1;
while (i >= 0 && i >= this.pfIndx) {
workInclusions.remove(i);
i = workInclusions.size()-1;
}
// unset this.pfIndx
this.pfIndx = -1;
}
this.inclCount = workInclusions.size();
System.out.println("to check inclusions: "+this.inclCount+" already checked: "+ncp+" of NAC: "+nac.getName());
this.checkInclsProduceForbidForNAC(r1, r2, nac, extendedL2isoPair, workInclusions, g, pci, overlaps);
// set the number of all valid inclusions
ncp = ncp + this.inclCount;
System.out.println(" ExcludePair.getProduceForbidConflicts:: [ "
+ r1.getName() + ", " + r2.getName()
+ " NAC: "+nac.getName()
+ " ] "
+ overlaps.size() + " critical overlapping(s)");
}
replaceVarAttrValueByConst(nac);
workInclusions = null;
if (!this.complete && !overlaps.isEmpty()) {
break;
}
} // while (!this.stop && nacs.hasMoreElements())
contextCombisDone = true;
} // while (!this.stop && perform)
contextCombis = null;
preservedCombis = null;
inclusions = null;
}
if (this.ac2leftExtended != null) {
this.ac2leftExtended.clear();
}
if (!stop) {
this.savePFIndx(-1, -1, "", false);
}
//test reduce isomorphic
if (!r1.getTypeSet().isArcDirected() && overlaps.size() > 0) {
reduceCriticalPairs(overlaps);
}
overlaps.trimToSize();
this.cpdKind = -1;
System.gc();
return overlaps;
}
private int checkInclsProduceForbidForNAC(
final Rule r1,
final Rule r2,
final OrdinaryMorphism nac,
final Pair<OrdinaryMorphism, OrdinaryMorphism> extendedL2isoPair,
final Vector<Vector<GraphObject>> workInclusions,
final Graph g,
int pci,
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
result) {
int overlapsOfNAC = 0;
// help for system.out.println
int n100 = 0, nn2 = 0;
boolean todo = workInclusions.size() > 0;
// do loop over inclusions
int i = workInclusions.size()-1;
while (i>=0 && !this.stop) {
Vector<GraphObject> inclSet = workInclusions.remove(i);
// workInclusions.remove(i);
i = workInclusions.size()-1;
OrdinaryMorphism inclMorphism = makeInclusionMorphism(inclSet, g);
if (inclMorphism != null)
overlapsOfNAC = overlapsOfNAC + this.checkProduceForbidForNAC(r1, r2, nac, inclMorphism, extendedL2isoPair, result);
this.inclProgress++;
n100++;
if (!this.complete && !result.isEmpty()) {
break;
}
if (n100 == 100) {
nn2++;
System.out.println("checked inclusions: "+n100*nn2+" to check: "+(i+1));
n100 = 0;
}
// TEST ONLY
// max bound will be checked for each NAC
if (this.maxBoundOfCriticCause > 0
&& overlapsOfNAC > this.maxBoundOfCriticCause) {
break;
}
}
if (stop) {
if (!todo || i==-1)
i = 0;
// set this.pfIndx
this.savePFIndx(i, pci, nac.getName(), this.checkSwitchDependency);
System.out.println("ProduceForbid conflict: stop at index: "+i+" of NAC: "+nac.getName());
}
return overlapsOfNAC;
}
private int checkProduceForbidForNAC(
final Rule r1,
final Rule r2,
final OrdinaryMorphism nac,
OrdinaryMorphism inclMorphism,
final Pair<OrdinaryMorphism, OrdinaryMorphism> extendedL2isoPair,
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
result) {
this.nacInsideOverlapGraph = nac;
markNacGraphObjects(nac);
if (this.withInheritance) {
extendTypeObjectsMapByParentObjects(extendedL2isoPair.first.getTarget());
}
// get overlapping morphisms
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlaps = getOverlappingsVectorProduceForbid(
r1, r2,
nac,
extendedL2isoPair,
inclMorphism);
if (!overlaps.isEmpty()) {
setGraphNameOfProduceForbidConflict(r1, r2, overlaps, nac);
result.addAll(overlaps);
}
inclMorphism.dispose(true, false); inclMorphism = null;
unmarkNacGraphObjects(nac);
this.nacInsideOverlapGraph = null;
return overlaps.size();
}
private Pair<OrdinaryMorphism, OrdinaryMorphism> extendGraphForProduceForbidConflict(
final Graph leftOfRule2,
final OrdinaryMorphism nacOfRule2) {
OrdinaryMorphism extendedL2iso = leftOfRule2.isomorphicCopy();
if (extendedL2iso == null)
return null;
// extend LHS of r2 by NAC,
// do not replace constant attribute value by variable
OrdinaryMorphism
extendedNAC2iso = extendLeftGraphByNAC(extendedL2iso, nacOfRule2, false); //true);
// extendedL2isoPair.first is embedding of LHS of r2 into extended LHS
// extendedL2isoPair.second is embedding of NAC of r2 into extended LHS
final Pair<OrdinaryMorphism, OrdinaryMorphism>
extendedL2isoPair = new Pair<OrdinaryMorphism, OrdinaryMorphism>(
extendedL2iso, extendedNAC2iso);
// note:
// extendedL2iso.getTarget() == extendedNAC2iso.getTarget() ==
// extendedL2isoPair.first.getTarget() == extendedL2isoPair.second.getTarget()
return extendedL2isoPair;
}
private void setGraphNameOfProduceForbidConflict(Rule r1, Rule r2,
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlaps,
final OrdinaryMorphism nac) {
// set name of the overlap graph
for (int i = 0; i < overlaps.size(); i++) {
final Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>> pi = overlaps.get(i);
final Graph overlapGraph = pi.first.first.getTarget();
if ((this instanceof DependencyPair)
&& !this.checkSwitchDependency) {
// overlapGraph.setName("delete-forbid-dependency (NAC: " + nac.getName()+ ")");
overlapGraph.setName(CriticalPairData.DELETE_FORBID_D_TXT+" (NAC: " + nac.getName()+ ")");
overlapGraph.setHelpInfo("NAC:"+nac.getName()+overlapGraph.getHelpInfo());
pi.first.first.setName("MorphOf_"+r1.getName());
pi.first.second.setName("MorphOf_"+r2.getName());
} else {
// overlapGraph.setName("produce-forbid-conflict (NAC: " + nac.getName()+ ")");
overlapGraph.setName(CriticalPairData.PRODUCE_FORBID_C_TXT+" (NAC: " + nac.getName()+ ")");
overlapGraph.setHelpInfo("NAC:"+nac.getName()+overlapGraph.getHelpInfo());
pi.first.first.setName("MorphOf_"+r1.getName());
pi.first.second.setName("MorphOf_"+r2.getName());
}
}
}
private Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getEssentialProduceForbidConflicts(
final Rule r1,
final Rule r2,
Vector<OrdinaryMorphism> potentialCriticalNACsOfR2) {
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
result = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
this.cpdKind = CriticalPairData.PRODUCE_FORBID_CONFLICT;
// only for dependency check
if (this instanceof DependencyPair) {
if (!this.checkSwitchDependency
&& this.pfIndxStr.endsWith(":1")) {
return result;
}
else if (this.checkSwitchDependency
&& this.pfIndxStr.endsWith(":0")) {
this.pfIndxStr = "";
}
}
this.inclCount = 0;
this.inclProgress = 0;
this.pfIndx = this.getPFIndx();
String pfNameIndx = this.getPFNameIndx();
final Graph g = r1.getRight();
this.inclAsGraph = false;
// if (this.essential) {
// check Nacs and add found objs to contextC1_r1
// and remove from preservedK1_r1
// findMorphismNACintoRHSAndAddToContext(r1, false, contextC1_r1,
// preservedK1_r1, this.typesTG_NAC2, this.produce);
// check multiplicity max=1 and add such objs to contextC1_r1
// and remove from preservedK1_r1
// addToContextIfTypeMaxMultiplicitySet(r1.getRight(), contextC1_r1,
// preservedK1_r1, this.typesTG_NAC2);
// }
int size = this.contextC1_R1.size();
Vector<Vector<GraphObject>>
contextCombis = ExcludePairHelper.getInclusions(g, size, this.contextC1_R1, true);
checkInclusions(contextCombis, this.produce);
if (contextCombis.size() > 0) {
if (namedObjectOnly)
this.checkInclusionsDuetoNamedObject(contextCombis);
}
if (contextCombis.size() > 0) {
// make loop over NACs
final Enumeration<OrdinaryMorphism> nacs = potentialCriticalNACsOfR2.elements();
if (nacs.hasMoreElements() && this.ac2leftExtended == null)
this.ac2leftExtended = new Hashtable<OrdinaryMorphism,Pair<OrdinaryMorphism, OrdinaryMorphism>>();
while (!this.stop && nacs.hasMoreElements()) {
OrdinaryMorphism nac = nacs.nextElement();
// to continue stopped CPA get the stopped NAC
if (!pfNameIndx.isEmpty()) {
if ((this.pfIndx > 0 && !nac.getName().equals(pfNameIndx))
|| (this.pfIndx == 0 && nac.getName().equals(pfNameIndx))) {
continue;
}
}
this.nacInsideOverlapGraph = nac;
markNacGraphObjects(nac);
Pair<OrdinaryMorphism, OrdinaryMorphism>
extendedL2isoPair = this.ac2leftExtended.get(nac);
if (extendedL2isoPair == null)
extendedL2isoPair = extendGraphForProduceForbidConflict(r2.getLeft(), nac);
if (extendedL2isoPair != null)
this.ac2leftExtended.put(nac, extendedL2isoPair);
else
continue;
Vector<Vector<GraphObject>>
workInclusions = new Vector<Vector<GraphObject>>(contextCombis);
if (this.pfIndx > 0) {
// reduce inclusions up to this.pfIndx
int i = workInclusions.size()-1;
while (i >= 0 && i >= this.pfIndx) {
workInclusions.remove(i);
i = workInclusions.size()-1;
}
// unset this.pfIndx
this.pfIndx = -1;
}
this.inclCount = workInclusions.size();
System.out.println("to check inclusions: "+this.inclCount+" of NAC: "+nac.getName());
this.checkInclsProduceForbidForNAC(r1, r2, nac, extendedL2isoPair, workInclusions, g, -1, result);
System.out.println(" ExcludePair.getProduceForbidConflicts:: [ "
+ r1.getName() + ", " + r2.getName()
+ " NAC: "+nac.getName()
+ " ] "
+ result.size() + " critical overlapping(s)");
replaceVarAttrValueByConst(nac);
workInclusions = null;
if ((!this.complete && !result.isEmpty())) {
break;
}
}
}
contextCombis = null;
if (this.ac2leftExtended != null) {
this.ac2leftExtended.clear();
}
if (!stop) {
this.savePFIndx(-1, -1, "", false);
}
result.trimToSize();
this.cpdKind = -1;
return result;
}
/**
* First extend the empty vector usedTypesNAC2
* by elements of the vector usedTypesL2,
* then search enabled NACs of the rule r
* and extend the vector usedTypesNAC2 by more types.
*/
void getTypeSubsetLeft_NACs(
final Rule r,
final Vector<Pair<Type, Pair<Type, Type>>> usedTypesL2,
final Vector<Pair<Type, Pair<Type, Type>>> usedTypesNAC2) {
usedTypesNAC2.addAll(usedTypesL2);
final List<OrdinaryMorphism> nacs = r.getNACsList();
for (int l=0; l<nacs.size(); l++) {
final OrdinaryMorphism nac = nacs.get(l);
if (nac.isEnabled())
fillTypeSubset(nac.getTarget(), usedTypesNAC2);
}
}
/**
* First extend the empty vector usedTypesPAC2
* by elements of the vector usedTypesL2,
* then search enabled PACs of the rule r
* and extend the vector usedTypesPAC2 by more types.
*/
void getTypeSubsetLeft_PACs(
final Rule r,
final Vector<Pair<Type, Pair<Type, Type>>> usedTypesL2,
final Vector<Pair<Type, Pair<Type, Type>>> usedTypesPAC2) {
usedTypesPAC2.addAll(usedTypesL2);
final List<OrdinaryMorphism> pacs = r.getPACsList();
for (int l=0; l<pacs.size(); l++) {
final OrdinaryMorphism pac = pacs.get(l);
if (pac.isEnabled())
fillTypeSubset(pac.getTarget(), usedTypesPAC2);
}
}
/**
* Search the graph g and fill the empty typeSubset by the node/edge types.
*/
void fillTypeSubset(final Graph g,
final Vector<Pair<Type, Pair<Type, Type>>> typeSubset) {
Iterator<Node> e = g.getNodesSet().iterator();
while (e.hasNext()) {
GraphObject o = e.next();
if (!isInTypes(typeSubset, o)) {
typeSubset.add(new Pair<Type, Pair<Type, Type>>(o.getType(),
null));
}
}
Iterator<Arc> e1 = g.getArcsSet().iterator();
while (e1.hasNext()) {
GraphObject o = e1.next();
Type src = ((Arc) o).getSource().getType();
Type tar = ((Arc) o).getTarget().getType();
if (!isInTypes(typeSubset, o)) {
Pair<Type, Type> srctar = new Pair<Type, Type>(src, tar);
typeSubset.add(new Pair<Type, Pair<Type, Type>>(o.getType(),
srctar));
}
}
}
private boolean isInTypes(
final Vector<Pair<Type, Pair<Type, Type>>> types,
final GraphObject go) {
for (int i = 0; i < types.size(); i++) {
Pair<Type, Pair<Type, Type>> p = types.get(i);
Type t = go.getType();
if (go.isNode()) {
if (t.isParentOf(p.first)) {//isRelatedTo
if (!types.contains(t) && !t.convertToKey().equals(p.first.convertToKey())){
this.withInheritance = true;
}
return true;
}
else if (t.isChildOf(p.first)) {
this.withInheritance = true;
return true;
}
} else {
Pair<Type, Type> p2 = p.second;
if (p.first.compareTo(t)) {
Type src_t = ((Arc)go).getSource().getType();
Type tar_t = ((Arc)go).getTarget().getType();
boolean srcTypeOK = false;
boolean tarTypeOK = false;
boolean srcT2parentT = false;
boolean tarT2parentT = false;
if (src_t.isParentOf(p2.first)) { //isRelatedTo
srcTypeOK = true;
// System.out.println("src node type "+src_t.getName()+" isParentOf "+p2.first.getName());
}
else if (src_t.isChildOf(p2.first)) {
srcT2parentT = true;
srcTypeOK = true;
}
if (tar_t.isParentOf(p2.second)) { //isRelatedTo
tarTypeOK = true;
// System.out.println("tar node type "+tar_t.getName()+" isParentOf "+p2.second.getName());
}
else if (tar_t.isChildOf(p2.second)){
tarT2parentT = true;
tarTypeOK = true;
}
if (srcTypeOK && tarTypeOK) {
if (srcT2parentT) {
// System.out.println("src node type "+src_t.getName()+" isChildOf "+p2.first.getName());
this.withInheritance = true;
}
if (tarT2parentT) {
// System.out.println("tar node type "+tar_t.getName()+" isChildOf "+p2.second.getName());
this.withInheritance = true;
}
return true;
}
}
}
}
return false;
}
private void markNacGraphObjects(OrdinaryMorphism nac) {
for (Iterator<Node> en = nac.getTarget().getNodesSet().iterator(); en.hasNext();) {
GraphObject go = en.next();
if (!nac.getInverseImage(go).hasMoreElements()) {
go.setContextUsage(nac.hashCode());
}
}
for (Iterator<Arc> en = nac.getTarget().getArcsSet().iterator(); en.hasNext();) {
GraphObject go = en.next();
if (!nac.getInverseImage(go).hasMoreElements()) {
go.setContextUsage(nac.hashCode());
}
}
}
private void unmarkNacGraphObjects(OrdinaryMorphism nac) {
for (Iterator<Node> en = nac.getTarget().getNodesSet().iterator(); en.hasNext();) {
GraphObject go = en.next();
if (go.getContextUsage() == nac.hashCode())
go.setContextUsage(-1);
}
for (Iterator<Arc> en = nac.getTarget().getArcsSet().iterator(); en.hasNext();) {
GraphObject go = en.next();
if (go.getContextUsage() == nac.hashCode())
go.setContextUsage(-1);
}
}
/*
private void markPacGraphObjects(OrdinaryMorphism pac) {
for (Iterator<Node> en = pac.getTarget().getNodesSet().iterator(); en.hasNext();) {
GraphObject go = en.next();
if (!pac.getInverseImage(go).hasMoreElements()) {
go.setContextUsage("" + pac.hashCode());
}
}
for (Iterator<Arc> en = pac.getTarget().getArcsSet().iterator(); en.hasNext();) {
GraphObject go = en.next();
if (!pac.getInverseImage(go).hasMoreElements()) {
go.setContextUsage("" + pac.hashCode());
}
}
}
private void unmarkPacGraphObjects(OrdinaryMorphism pac) {
for (Iterator<Node> en = pac.getTarget().getNodesSet().iterator(); en.hasNext();) {
GraphObject go = en.next();
if (go.getContextUsage().equals(String.valueOf(pac.hashCode())))
go.setContextUsage("");
}
for (Iterator<Arc> en = pac.getTarget().getArcsSet().iterator(); en.hasNext();) {
GraphObject go = en.next();
if (go.getContextUsage().equals(String.valueOf(pac.hashCode())))
go.setContextUsage("");
}
}
*/
private Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getLeftChangeAttrConflicts(
final Rule r1,
final Rule r2,
final String pacName,
final Graph g,
final Pair<OrdinaryMorphism, OrdinaryMorphism> lhs_pac_pair,
final Vector<Vector<GraphObject>> inclusions) {
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlapsL2 = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
int i = inclusions.size()-1;
while (i >= 0 && !this.stop) {
// Vector<GraphObject> inclSet = inclusions.remove(i);
// i = inclusions.size()-1;
Vector<GraphObject> inclSet = inclusions.get(i);
i--;
OrdinaryMorphism inclMorphism = makeInclusionMorphism(inclSet, g);
if (inclMorphism == null) {
continue;
}
// get overlapping morphisms
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
localOverlaps = null;
if (lhs_pac_pair == null) {
localOverlaps = getOverlappingsVectorChangeAttr(r1, r2, null,
r2.getLeft(), false, inclMorphism);
for (int in = 0; in < localOverlaps.size(); in++) {
final Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
pi = localOverlaps.get(in);
setGraphNameOfChangeAttrConflict(r1, r2, pi, "");
overlapsL2.add(pi);
}
} else {
localOverlaps = getOverlappingsVectorChangeAttr(r1, r2, null,
lhs_pac_pair, false, inclMorphism);
for (int x = 0; x < localOverlaps.size(); x++) {
final Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
pi = localOverlaps.get(x);
// if (this.tryExcludePAC(r1, r2, localOverlaps.get(x))) {
// // remove double LHS-critic pairs
// if (!lhsCritic) {
// setGraphNameOfChangeAttrConflict(pi, "");
// lhsCritic = true;
// }
// else {
// localOverlaps.remove(x);
// x--;
// }
// }
// else
setGraphNameOfChangeAttrConflict(r1, r2, pi, pacName);
overlapsL2.add(pi);
}
}
this.inclProgress++;
inclMorphism.dispose(true, false); inclMorphism = null;
localOverlaps.clear();
if (!this.complete && !overlapsL2.isEmpty()) {
break;
}
if (this.stop)
break;
// TEST ONLY
if (this.maxBoundOfCriticCause > 0
&& overlapsL2.size() > this.maxBoundOfCriticCause) {
break;
}
}
if (this.stop) {
// set this.caIndx
if (pacName.isEmpty()) {
this.saveCAIndx(i, "".concat(":LHS"), this.checkSwitchDependency);
System.out.println("ChangeAttribute conflict: stop at index: "+i);
}
else {
this.saveCAIndx(i, pacName.concat(":PAC"), this.checkSwitchDependency);
System.out.println("ChangeAttribute conflict: stop at index: "+i+" of PAC: "+pacName);
}
}
return overlapsL2;
}
protected void setGraphNameOfChangeAttrConflict(Rule r1, Rule r2,
final Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
overlap,
final String pacName) {
// mark critical objects
final Graph overlapGraph = overlap.first.first.getTarget();
// set name of overlap graph
if ((this instanceof DependencyPair)
&& !this.checkSwitchDependency) {
overlapGraph.setName(CriticalPairData.CHANGE_USE_ATTR_D_TXT);
if (pacName.length() > 0) {
overlapGraph.setName(CriticalPairData.CHANGE_NEED_ATTR_D_TXT+" (PAC: " + pacName + ")");
overlapGraph.setHelpInfo("PAC:"+pacName);
}
overlap.first.first.setName("MorphOf_"+r1.getName());
overlap.first.second.setName("MorphOf_"+r2.getName());
}
else {
overlapGraph.setName(CriticalPairData.CHANGE_USE_ATTR_C_TXT);
if (pacName.length() > 0) {
overlapGraph.setName(CriticalPairData.CHANGE_NEED_ATTR_C_TXT+" (PAC: " + pacName + ")");
overlapGraph.setHelpInfo("PAC:"+pacName);
}
overlap.first.first.setName("MorphOf_"+r1.getName());
overlap.first.second.setName("MorphOf_"+r2.getName());
}
}
private Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getNacChangeAttrConflicts(
final Rule r1,
final Rule r2,
final Graph g,
final Vector<Vector<GraphObject>> contextCombis,
final Vector<Vector<GraphObject>> preservedCombis,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> changedAttrsL1,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> changedAttrsL2) {
// second part: check attr conflicts over NACs
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlaps = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
Vector<Vector<GraphObject>> inclusions = null;
String caNameIndx = this.caIndxStr.contains(":NAC")? this.getCANameIndx(): "";
final List<OrdinaryMorphism> nacs2 = r2.getNACsList();
for (int j=0; j<nacs2.size() && !this.stop; j++) {
final OrdinaryMorphism nac = nacs2.get(j);
if (!nac.isEnabled()
|| (this.caIndx > 0 && !caNameIndx.isEmpty()
&& !nac.getName().equals(caNameIndx))) {
continue;
}
final Vector<GraphObject>
nacRestriction = nacRestrictsAttribute(nac,
(VarTuple) r2.getAttrContext().getVariables(),
(CondTuple) r2.getAttrContext().getConditions(),
changedAttrsL2, changedAttrsL1);
if (nacRestriction.size() == 0)
continue;
this.nacInsideOverlapGraph = nac;
markNacGraphObjects(this.nacInsideOverlapGraph);
final OrdinaryMorphism extendedL2iso = r2.getLeft().isomorphicCopy();
if (extendedL2iso == null)
continue;
final OrdinaryMorphism
extendedNAC2iso = extendLeftGraphByNAC(extendedL2iso, nac, false);
final Pair<OrdinaryMorphism, OrdinaryMorphism>
extendedL2isoPair = new Pair<OrdinaryMorphism, OrdinaryMorphism>(
extendedL2iso, extendedNAC2iso);
int maxSize = extendedL2iso.getTarget().getSize();
Vector<Vector<GraphObject>>
workContextCombis = checkInclusionsAgainstNac(contextCombis, nacRestriction);
if (this.essential) {
inclusions = contextCombis;
}
else {
inclusions = ExcludePairHelper.combineInclusions(maxSize, workContextCombis,
preservedCombis, this.boundB1_L1);
}
if (this.caIndx > 0 && inclusions.size() > 0
&& this.caIndx < inclusions.size()) {
// reduce inclusions up to this.pfIndx
int i = inclusions.size()-1;
while (i >= 0 && i >= this.caIndx) {
inclusions.remove(i);
i = inclusions.size()-1;
}
// unset this.caIndx
this.caIndx = -1;
}
this.inclCount = inclusions.size();
System.out.println("to check inclusions: "+inclusions.size());
int i = inclusions.size()-1;
while (i >= 0 && !this.stop) {
Vector<GraphObject> inclSet = inclusions.remove(i);
i = inclusions.size()-1;
OrdinaryMorphism inclMorphism = makeInclusionMorphism(inclSet, g);
if (inclMorphism == null) {
continue;
}
// get overlapping morphisms
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlapsN2 = getOverlappingsVectorChangeAttr(r1, r2, nac, extendedL2isoPair, true, inclMorphism);
this.inclProgress++;
inclMorphism.dispose(true, false); inclMorphism = null;
for (int in = 0; in < overlapsN2.size(); in++) {
final Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
pi = overlapsN2.get(in);
final Graph overlapGraph = pi.first.first.getTarget();
if (this instanceof DependencyPair
&& !this.checkSwitchDependency) {
// overlapGraph.setName("change-forbid-attr-dependency (NAC: " + nac.getName()+ ")");
overlapGraph.setName(CriticalPairData.CHANGE_FORBID_ATTR_D_TXT+" (NAC: " + nac.getName()+ ")");
overlapGraph.setHelpInfo("NAC:"+nac.getName()+overlapGraph.getHelpInfo());
} else {
// overlapGraph.setName("change-forbid-attr-conflict (NAC: " + nac.getName()+ ")");
overlapGraph.setName(CriticalPairData.CHANGE_FORBID_ATTR_C_TXT+" (NAC: " + nac.getName()+ ")");
overlapGraph.setHelpInfo("NAC:"+nac.getName()+overlapGraph.getHelpInfo());
}
}
overlaps.addAll(overlapsN2);
overlapsN2.clear();
if (!this.complete && !overlaps.isEmpty()) {
break;
}
// TEST ONLY
// max bound will be checked for each NAC
if (this.maxBoundOfCriticCause > 0
&& overlaps.size() > this.maxBoundOfCriticCause) {
break;
}
}
inclusions = null;
if (stop) {
// set this.caIndx
this.saveCAIndx(i, nac.getName().concat(":NAC"), this.checkSwitchDependency);
System.out.println("ChangeAttribute conflict: stop at index: "+i+" of NAC: "+nac.getName());
}
unmarkNacGraphObjects(this.nacInsideOverlapGraph);
// restore constant attribute value
replaceVarAttrValueByConst(nac);
this.nacInsideOverlapGraph = null;
if (!this.complete && !overlaps.isEmpty()) {
break;
}
}
overlaps.trimToSize();
return overlaps;
}
private int getCAIndx() {
try {
this.caIndx = Integer.valueOf(this.caIndxStr.split(":")[0]).intValue();
} catch (NumberFormatException ex) {
this.caIndx = -1;
}
return this.caIndx;
}
private String getCANameIndx() {
try {
return this.caIndxStr.split(":")[1];
} catch (ArrayIndexOutOfBoundsException ex) {}
return "";
}
private void saveCAIndx(int i, String s, boolean switchDep) {
this.caIndx = i;
String swDep = switchDep? "1": "0";
this.caIndxStr = String.valueOf(this.caIndx)
.concat(":").concat(s)
.concat(":").concat(swDep);
}
protected Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getChangeAttributeConflicts(
final Rule r1,
final Rule r2,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> changedAttrsL1,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> changedAttrsL2) {
System.out.println(" ExcludePair.getChangeAttributeConflicts:: [ "
+ r1.getName() + ", " + r2.getName() + " ] ... ");
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlaps = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
// only for dependency check
if (this instanceof DependencyPair) {
if (!this.checkSwitchDependency
&& this.caIndxStr.endsWith(":1")) {
return overlaps;
}
else if (this.checkSwitchDependency
&& this.caIndxStr.endsWith(":0")) {
this.caIndxStr = "";
}
}
this.inclAsGraph = false;
this.cpdKind = CriticalPairData.CHANGE_ATTR_CONFLICT;
this.inclCount = 0;
this.inclProgress = 0;
this.caIndx = this.getCAIndx();
String caNameIndx = this.caIndxStr.contains(":PAC")? this.getCANameIndx(): "";
final Graph g = r1.getLeft();
int maxSize = r2.getLeft().getSize();
int size = 0;
Enumeration<OrdinaryMorphism> pacs2 = r2.getPACs();
boolean lhs_done = false;
boolean perform = true;
while (perform && !this.stop) {
OrdinaryMorphism L2isoL2ExtendedByPACs = null;
Pair<OrdinaryMorphism, OrdinaryMorphism> lhs_pac_pair = null;
String pacName = "";
boolean needToReduce = (this.caIndx > 0 && this.caIndxStr.contains(":LHS"))? true: false;
OrdinaryMorphism pac = null;
if (this.withPACs && pacs2.hasMoreElements()) {
pac = pacs2.nextElement();
if (!pac.isEnabled()
|| (this.caIndx > 0 && !caNameIndx.isEmpty()
&& !pac.getName().equals(caNameIndx))) {
continue;
}
}
size = this.contextC1_L1.size();
// 3 == edge+src+tar
if (maxSize > 3 && size > maxSize) size = maxSize;
Vector<Vector<GraphObject>>
contextCombis = ExcludePairHelper.getInclusions(g, size, this.contextC1_L1, true);
checkInclusions(contextCombis, this.preservedChanged);
if (contextCombis.size() == 0)
break;
if (pac != null) {
boolean pacCritical = ExcludePairHelper.isCriticalPAC(pac, this.preservedChanged);
if (pacCritical) {
L2isoL2ExtendedByPACs = r2.getLeft().isomorphicCopy();
if (L2isoL2ExtendedByPACs != null) {
// disjoint union of own objects of PAC and LHS of r2
lhs_pac_pair = extendLeftGraphByPAC(L2isoL2ExtendedByPACs, pac, false);
pacName = pac.getName();
maxSize = L2isoL2ExtendedByPACs.getTarget().getSize();
lhs_done = true;
}
}
}
Vector<Vector<GraphObject>> preservedCombis = null;
Vector<Vector<GraphObject>> inclusions = null;
if (namedObjectOnly) {
this.checkInclusionsDuetoNamedObject(contextCombis);
if (contextCombis.size() == 0)
break;
}
if (this.essential) {
inclusions = contextCombis;
}
else {
size = this.preservedK1_L1.size();
if (size > maxSize) size = maxSize;
preservedCombis = ExcludePairHelper.getPlainCombinedInclusions(
new Vector<GraphObject>(this.preservedK1_L1), size, g);
inclusions = ExcludePairHelper.combineInclusions(maxSize, contextCombis,
preservedCombis, this.boundB1_L1);
}
if (needToReduce) {
int i = inclusions.size()-1;
while (i >= 0 && i >= this.caIndx) {
inclusions.remove(i);
i = inclusions.size()-1;
}
// unset this.caIndx
this.caIndx = -1;
}
this.inclCount = inclusions.size();
System.out.println("to check inclusions: "+this.inclCount);
//first part: check attr conflicts of left (+PAC) graphs of the rules
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlapsL2 = getLeftChangeAttrConflicts(r1, r2, pacName, g,
lhs_pac_pair, inclusions);
lhs_done = true;
// add to common list of overlappings
overlaps.addAll(overlapsL2);
if (!this.stop && (overlapsL2.isEmpty() || this.complete)) {
this.inclCount = 0;
this.inclProgress = 0;
// second part: check attr conflicts over NACs
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlapsNAC = getNacChangeAttrConflicts(r1, r2, g,
contextCombis, preservedCombis,
changedAttrsL1, changedAttrsL2);
// add to common list of overlappings
overlaps.addAll(overlapsNAC);
}
if (!this.complete && !overlaps.isEmpty()) {
break;
}
contextCombis = null;
preservedCombis = null;
inclusions = null;
perform = (this.withPACs && pacs2.hasMoreElements()) || !lhs_done;
}
if (!stop) {
this.saveCAIndx(-1, "", false);
}
if (this.withPACs) {
pacs2 = r2.getPACs();
while (pacs2.hasMoreElements()) {
// restore constant attribute value
this.replaceVarAttrValueByConst(pacs2.nextElement());
}
}
//test all overlap graphs (directed and undirected) and reduce isomorphic
if (/*!r1.getTypeSet().isArcDirected() && */overlaps.size() > 0) {
reduceCriticalPairs(overlaps);
}
System.out.println(" ExcludePair.getChangeAttributeConflicts:: [ "
+ r1.getName() + ", " + r2.getName() + " ] " + overlaps.size()
+ " critical overlapping(s)");
overlaps.trimToSize();
this.cpdKind = -1;
System.gc();
return overlaps;
}
protected void ruleChangesAttributes(
final Rule r1,
final Rule r2,
final Vector<GraphObject> context,
final Vector<GraphObject> boundary,
final Vector<GraphObject> preserved,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> changedAttrs,
final Vector<Pair<Type, Pair<Type, Type>>> neededTypes) {
context.clear();
boundary.clear();
this.preservedChanged.clear();
for (Enumeration<GraphObject> en = r1.getDomain(); en.hasMoreElements();) {
GraphObject goLeft = en.nextElement();
if (isInTypes(neededTypes, goLeft)) {
if (!preserved.contains(goLeft))
preserved.add(goLeft);
// now check if attrs of r1 have been changed
GraphObject goRight = r1.getImage(goLeft);
AttrInstance leftAttr = goLeft.getAttribute();
AttrInstance rightAttr = goRight.getAttribute();
if (leftAttr == null)
continue;
Vector<Pair<ValueMember, ValueMember>> members = changedAttrs
.get(goLeft.getType().getAttrType());
if (members == null)
members = new Vector<Pair<ValueMember, ValueMember>>(2);
boolean changed = false;
for (int i = 0; i < leftAttr.getNumberOfEntries(); i++) {
ValueMember
leftMember = (ValueMember) leftAttr.getMemberAt(i);
ValueMember
rightMember = (ValueMember) rightAttr.getMemberAt(i);
boolean toadd = false;
if (rightMember.isSet()) {
if (!leftMember.isSet())
toadd = true;
else if (rightMember.getExpr().isVariable()) {
if ((leftMember.getExpr().isVariable()
&& !leftMember.getExprAsText().equals(
rightMember.getExprAsText()))
|| leftMember.getExpr().isConstant())
toadd = true;
} else if (rightMember.getExpr().isConstant()) {
if ((leftMember.getExpr().isConstant()
&& !leftMember.getExprAsText().equals(
rightMember.getExprAsText()))
|| leftMember.getExpr().isVariable()) {
toadd = true;
}
} else if (rightMember.getExpr().isComplex()) {
toadd = true;
}
if (toadd) {
changed = true;
Pair<ValueMember, ValueMember> p = new Pair<ValueMember, ValueMember>(
leftMember, rightMember);
members.add(p);
}
}
}
/*
boolean contained = true;
if (!changed) { // NEW
// additionally, check against the LHS of r2
Iterator<?> elems = r2.getLeft().getNodesSet().iterator();
while (contained && elems.hasNext()) {
GraphObject o = (GraphObject) elems.next();
if (o.getType().compareTo(goLeft.getType())) {
if (ExcludePairHelper.isAttributeRestricted(//this.strongAttrCheck,
r2, o)) {
contained = typeContainedIn(o.getType(), this.preservedChanged);
}
}
}
elems = r2.getLeft().getArcsSet().iterator();
while (contained && elems.hasNext()) {
GraphObject o = (GraphObject) elems.next();
if (o.getType().compareTo(goLeft.getType())) {
if (ExcludePairHelper.isAttributeRestricted(//this.strongAttrCheck,
r2, o)) {
contained = typeContainedIn(o.getType(), this.preservedChanged);
}
}
}
if (contained) {
// additionally, check against the nacs of r2
final List<OrdinaryMorphism> nacs = r2.getNACsList();
for (int l=0; l<nacs.size(); l++) {
final OrdinaryMorphism nac = nacs.get(l);
if (!nac.isEnabled())
continue;
// System.out.println("nac: "+nac.getName());
elems = nac.getTarget().getNodesSet().iterator();
while (contained && elems.hasNext()) {
GraphObject o = (GraphObject) elems.next();
if (o.getType().compareTo(goLeft.getType())) {
if (!nac.getInverseImage(o)
.hasMoreElements()) {
if (ExcludePairHelper.isAttributeRestricted(//this.strongAttrCheck,
r2, o)) {
contained = typeContainedIn(o.getType(), this.preservedChanged);
}
}
}
}
elems = nac.getTarget().getArcsSet().iterator();
while (contained && elems.hasNext()) {
GraphObject o = (GraphObject) elems
.next();
if (o.getType().compareTo(goLeft.getType())) {
if (!nac.getInverseImage(o)
.hasMoreElements()) {
if (ExcludePairHelper.isAttributeRestricted(//this.strongAttrCheck,
r2, o)) {
contained = typeContainedIn(o.getType(), this.preservedChanged);
}
}
}
}
}
}
}
*/
if (changed /*|| !contained*/) {
if (!members.isEmpty())
changedAttrs.put(goLeft.getType().getAttrType(), members);
context.add(goLeft);
this.preservedChanged.add(goLeft);
preserved.remove(goLeft);
if (goLeft.isArc()) {
GraphObject src = ((Arc) goLeft).getSource();
GraphObject tar = ((Arc) goLeft).getTarget();
if (!context.contains(src))
context.add(src);
if (!context.contains(tar))
context.add(tar);
/*
* if(!boundary.contains(src)) boundary.add(src);
* if(!boundary.contains(tar)) boundary.add(tar);
*/
preserved.remove(src);
preserved.remove(tar);
}
}
}
}
restrictedAttributes(r1, r2, context, boundary, preserved, neededTypes);
// at the end: preservedChanged contains nodes, edges to change;
// context (== contextC1_l1) contains nodes to change and edges to
// change with source and target as boundary objects;
// preserved (== preservedK1_l1) contains unchanged nodes and edges
}
private void restrictedAttributes(
final Rule r1,
final Rule r2,
final Vector<GraphObject> context,
final Vector<GraphObject> boundary,
final Vector<GraphObject> preserved,
final Vector<Pair<Type, Pair<Type, Type>>> neededTypes) {
for (Enumeration<GraphObject> en = r1.getDomain(); en.hasMoreElements();) {
GraphObject goLeft = en.nextElement();
if (isInTypes(neededTypes, goLeft)) {
if (goLeft.getAttribute() == null)
continue;
boolean added = true;
// additionally, check against the LHS of r2
Iterator<?> elems = r2.getLeft().getNodesSet().iterator();
while (added && elems.hasNext()) {
GraphObject o = (GraphObject) elems.next();
if (o.getType().compareTo(goLeft.getType())) {
if (ExcludePairHelper.isAttributeRestricted(r2, o)) {
added = typeContainedIn(o.getType(), this.preservedChanged);
}
}
}
elems = r2.getLeft().getArcsSet().iterator();
while (added && elems.hasNext()) {
GraphObject o = (GraphObject) elems.next();
if (o.getType().compareTo(goLeft.getType())) {
if (ExcludePairHelper.isAttributeRestricted(r2, o)) {
added = typeContainedIn(o.getType(), this.preservedChanged);
}
}
}
if (added) {
// additionally, check against the nacs of r2
final List<OrdinaryMorphism> nacs = r2.getNACsList();
for (int l=0; l<nacs.size(); l++) {
final OrdinaryMorphism nac = nacs.get(l);
if (!nac.isEnabled())
continue;
// System.out.println("nac: "+nac.getName());
elems = nac.getTarget().getNodesSet().iterator();
while (added && elems.hasNext()) {
GraphObject o = (GraphObject) elems.next();
if (o.getType().compareTo(goLeft.getType())) {
if (!nac.getInverseImage(o)
.hasMoreElements()) {
if (ExcludePairHelper.isAttributeRestricted(r2, o)) {
added = typeContainedIn(o.getType(), this.preservedChanged);
}
}
}
}
elems = nac.getTarget().getArcsSet().iterator();
while (added && elems.hasNext()) {
GraphObject o = (GraphObject) elems
.next();
if (o.getType().compareTo(goLeft.getType())) {
if (!nac.getInverseImage(o).hasMoreElements()) {
if (ExcludePairHelper.isAttributeRestricted(r2, o)) {
added = typeContainedIn(o.getType(), this.preservedChanged);
}
}
}
}
}
}
if (!added) {
GraphObject goRight = r1.getImage(goLeft);
if (goRight.doesChangeAttr(goLeft)) {
context.add(goLeft);
this.preservedChanged.add(goLeft);
preserved.remove(goLeft);
if (goLeft.isArc()) {
GraphObject src = ((Arc) goLeft).getSource();
GraphObject tar = ((Arc) goLeft).getTarget();
if (!context.contains(src))
context.add(src);
if (!context.contains(tar))
context.add(tar);
preserved.remove(src);
preserved.remove(tar);
}
}
}
}
}
}
private boolean typeContainedIn(Type t, final Vector<GraphObject> vec) {
boolean found = false;
for (int j=0; j<vec.size(); j++) {
if (t.isParentOf(vec.get(j).getType())) {
found = true;
break;
}
}
return found;
}
void ruleChangesAttributes(
final Rule r,
final Vector<GraphObject> preserved,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> changedAttrs) {
for (Enumeration<GraphObject> en = r.getDomain(); en.hasMoreElements();) {
GraphObject goLeft = en.nextElement();
if (goLeft.isNode()) {
if (!preserved.contains(goLeft))
preserved.add(goLeft);
// now check if attrs have been changed
GraphObject goRight = r.getImage(goLeft);
AttrInstance leftAttr = goLeft.getAttribute();
AttrInstance rightAttr = goRight.getAttribute();
if (leftAttr != null) {
Vector<Pair<ValueMember, ValueMember>> members = changedAttrs
.get(goLeft.getType().getAttrType());
if (members == null)
members = new Vector<Pair<ValueMember, ValueMember>>(2);
boolean changed = false;
for (int i = 0; i < leftAttr.getNumberOfEntries(); i++) {
ValueMember leftMember = (ValueMember) leftAttr
.getMemberAt(i);
ValueMember rightMember = (ValueMember) rightAttr
.getMemberAt(i);
boolean bool = false;
if (rightMember.isSet()) {
if (!leftMember.isSet()) {
bool = true;
} else if (rightMember.getExpr().isVariable()) {
if ((leftMember.getExpr().isVariable() && !leftMember
.getExprAsText().equals(
rightMember.getExprAsText()))
|| leftMember.getExpr().isConstant())
bool = true;
} else if (rightMember.getExpr().isConstant()) {
if ((leftMember.getExpr().isConstant() && !leftMember
.getExprAsText().equals(
rightMember.getExprAsText()))
|| leftMember.getExpr().isVariable()) {
bool = true;
}
} else if (rightMember.getExpr().isComplex()) {
bool = true;
}
if (bool) {
changed = true;
Pair<ValueMember, ValueMember> p = new Pair<ValueMember, ValueMember>(
leftMember, rightMember);
members.add(p);
}
}
}
if (changed) {
changedAttrs.put(goLeft.getType().getAttrType(),
members);
}
}
}
}
}
boolean ruleRestrictsAttributes(
boolean strongCheck,
final Rule r,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> leftChangedAttrs,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> otherChangedAttrs) {
final VarTuple vars = (VarTuple) r.getAttrContext().getVariables();
final CondTuple conds = (CondTuple) r.getAttrContext().getConditions();
ruleRestrictsAtts(strongCheck, r, leftChangedAttrs, otherChangedAttrs,
vars, conds, r.getLeft().getNodesSet().iterator());
ruleRestrictsAtts(strongCheck, r, leftChangedAttrs, otherChangedAttrs,
vars, conds, r.getLeft().getArcsSet().iterator());
// check attr. setting (LHS) of r against otherChangedAttrs (RHS)
Enumeration<AttrType> keys = leftChangedAttrs.keys();
while (keys.hasMoreElements()) {
agg.attribute.AttrType key = keys.nextElement();
Vector<Pair<ValueMember, ValueMember>> v = leftChangedAttrs
.get(key);
Vector<Pair<ValueMember, ValueMember>> otherv = otherChangedAttrs
.get(key);
if (v != null && otherv != null) {
for (int i = 0; i < v.size(); i++) {
Pair<ValueMember, ValueMember> p = v.get(i);
ValueMember mL = p.first;
if (mL != null && mL.getExpr() != null) {
for (int j = 0; j < otherv.size(); j++) {
Pair<ValueMember, ValueMember>
otherp = otherv.get(j);
ValueMember othermR = otherp.second;
if (othermR != null && othermR.getExpr() != null
&&!othermR.getExprAsText().equals(mL.getExprAsText())) {
return true;
} else {
othermR = otherp.first;
if (othermR != null && othermR.getExpr() != null
&& !othermR.getExprAsText().equals(mL.getExprAsText())) {
return true;
}
}
}
}
}
}
}
final List<OrdinaryMorphism> nacs = r.getNACsList();
for (int l=0; l<nacs.size(); l++) {
final OrdinaryMorphism nac = nacs.get(l);
if (nac.isEnabled()
&& nacRestrictsAttribute(nac, vars, conds, leftChangedAttrs,
otherChangedAttrs).size() != 0) {
return true;
}
}
final List<OrdinaryMorphism> pacs = r.getPACsList();
for (int l=0; l<pacs.size(); l++) {
final OrdinaryMorphism pac = pacs.get(l);
if (pac.isEnabled()
&& pacRestrictsAttribute(pac, vars, conds, leftChangedAttrs,
otherChangedAttrs).size() != 0) {
return true;
}
}
return false;
}
private void ruleRestrictsAtts(
boolean strongCheck,
final Rule r,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> leftChangedAttrs,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> otherChangedAttrs,
final VarTuple vars,
final CondTuple conds,
final Iterator<?> en) {
while (en.hasNext()) {
GraphObject goLeft = (GraphObject) en.next();
AttrInstance leftAttr = goLeft.getAttribute();
boolean bool = false;
if (leftAttr != null) {
Vector<Pair<ValueMember, ValueMember>> members = leftChangedAttrs
.get(goLeft.getType().getAttrType());
if (members == null) {
members = new Vector<Pair<ValueMember, ValueMember>>(2);
}
for (int i = 0; i < leftAttr.getNumberOfEntries(); i++) {
ValueMember leftMember = (ValueMember) leftAttr
.getMemberAt(i);
if (leftMember.isSet()) {
if (leftMember.getExpr().isConstant()) {
Vector<Pair<ValueMember, ValueMember>> otherv = otherChangedAttrs
.get(leftAttr.getType());
if (otherv != null) {
for (int j = 0; j < otherv.size(); j++) {
Pair<ValueMember, ValueMember>
otherp = otherv.get(j);
ValueMember othermR = otherp.second;
if (othermR != null
&& othermR.getName().equals(leftMember.getName())
&& othermR.getExpr() != null
&& !othermR.getExprAsText().equals(
leftMember.getExprAsText())) {
bool = true;
}
}
}
}
else if (leftMember.getExpr().isVariable()) {
if (strongCheck) {
final VarMember var = (VarMember)vars.getMemberAt(leftMember.getExprAsText());
bool = (var != null)
&& (var.isInputParameter()
|| isVariableUsedInAttrCondition(var.getName(), conds));
} else {
bool = true;
}
}
if (bool) {
Pair<ValueMember, ValueMember>
p = new Pair<ValueMember, ValueMember>(leftMember, null);
members.add(p);
}
}
else if (r.getImage(goLeft) == null) {
Pair<ValueMember, ValueMember>
p = new Pair<ValueMember, ValueMember>(leftMember, null);
members.add(p);
}
}
if (!members.isEmpty()) {
leftChangedAttrs.put(goLeft.getType().getAttrType(),
members);
}
}
}
}
private boolean isVariableUsedInAttrCondition(final String varName, final CondTuple conds) {
final Vector<String> varsOfConditions = conds.getAllVariables();
for (int j=0; j<varsOfConditions.size(); j++) {
if (varName.equals(varsOfConditions.get(j))) {
return true;
}
}
return false;
}
private Vector<GraphObject> nacRestrictsAttribute(
final OrdinaryMorphism nac,
final VarTuple vars,
final CondTuple conds,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> leftChangedAttrs,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> otherChangedAttrs) {
final Vector<GraphObject> result = new Vector<GraphObject>(5);
final Vector<String> varNames = conds.getAllVariables();
nacRestrictsAttr(nac, vars, conds, leftChangedAttrs, otherChangedAttrs,
result, varNames, nac.getTarget().getNodesSet().iterator());
nacRestrictsAttr(nac, vars, conds, leftChangedAttrs, otherChangedAttrs,
result, varNames, nac.getTarget().getArcsSet().iterator());
return result;
}
private Vector<GraphObject> nacRestrictsAttr(
final OrdinaryMorphism nac,
final VarTuple vars,
final CondTuple conds,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> leftChangedAttrs,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> otherChangedAttrs,
final Vector<GraphObject> res,
final Vector<String> varNames,
final Iterator<?> en) {
while (en.hasNext()) {
GraphObject go = (GraphObject) en.next();
if (go.getAttribute() != null) {
AttrInstance attr = go.getAttribute();
Vector<Pair<ValueMember, ValueMember>> changedMembers = null;
if (!leftChangedAttrs.isEmpty()) {
changedMembers = leftChangedAttrs.get(go.getType()
.getAttrType());
}
if (!otherChangedAttrs.isEmpty()) {
changedMembers = otherChangedAttrs.get(go.getType()
.getAttrType());
}
for (int i = 0; i < attr.getNumberOfEntries(); i++) {
ValueMember member = (ValueMember) attr.getMemberAt(i);
if (member.isSet()) {
if (changedMembers != null) {
for (int j = 0; j < changedMembers.size(); j++) {
Pair<ValueMember, ValueMember> p = changedMembers
.get(j);
ValueMember vm1 = p.first;
ValueMember vm2 = p.second;
if (member.getName().equals(vm1.getName())
|| ((vm2 != null) && member.getName()
.equals(vm2.getName()))) {
res.add(go);
}
}
}
}
}
}
}
return res;
}
private Vector<GraphObject> pacRestrictsAttribute(
final OrdinaryMorphism pac,
final VarTuple vars,
final CondTuple conds,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> leftChangedAttrs,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> otherChangedAttrs) {
Vector<GraphObject> result = new Vector<GraphObject>(5);
final Vector<String> varsNames = conds.getAllVariables();
pacRestrictsAttr(pac, vars, conds, leftChangedAttrs, otherChangedAttrs,
result, varsNames, pac.getTarget().getNodesSet().iterator());
pacRestrictsAttr(pac, vars, conds, leftChangedAttrs, otherChangedAttrs,
result, varsNames, pac.getTarget().getArcsSet().iterator());
return result;
}
private Vector<GraphObject> pacRestrictsAttr(
final OrdinaryMorphism pac,
final VarTuple vars,
final CondTuple conds,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> leftChangedAttrs,
final Hashtable<AttrType, Vector<Pair<ValueMember, ValueMember>>> otherChangedAttrs,
final Vector<GraphObject> res,
final Vector<String> varsNames,
final Iterator<?> en) {
while (en.hasNext()) {
GraphObject go = (GraphObject) en.next();
if (go.getAttribute() != null) {
AttrInstance attr = go.getAttribute();
Vector<Pair<ValueMember, ValueMember>>
changedMembers = new Vector<Pair<ValueMember, ValueMember>>();
if (!leftChangedAttrs.isEmpty()
&& leftChangedAttrs.get(go.getType()
.getAttrType()) != null) {
changedMembers.addAll(leftChangedAttrs.get(go.getType()
.getAttrType()));
}
else if (!otherChangedAttrs.isEmpty()
&& otherChangedAttrs.get(go.getType()
.getAttrType()) != null) {
changedMembers.addAll(otherChangedAttrs.get(go.getType()
.getAttrType()));
}
for (int i = 0; i < attr.getNumberOfEntries(); i++) {
ValueMember member = (ValueMember) attr.getMemberAt(i);
if (member.isSet()) {
for (int j = 0; j < changedMembers.size(); j++) {
Pair<ValueMember, ValueMember> p = changedMembers
.get(j);
ValueMember vm1 = p.first;
ValueMember vm2 = p.second;
if (member.getName().equals(vm1.getName())
|| ((vm2 != null) && member.getName()
.equals(vm2.getName()))) {
res.add(go);
}
}
}
}
}
}
return res;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getOverlappingsVectorChangeAttr(
final Rule r1,
final Rule r2,
final OrdinaryMorphism ac,
Object testObject,
boolean isNAC,
final OrdinaryMorphism inclusionMorphism) {
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
result = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>(1);
if ((testObject instanceof Graph) && (r2.getLeft() == (Graph) testObject)) {
result = getOverlappingsVectorAttr(r1, r2, inclusionMorphism);
}
else if (isNAC && testObject instanceof Pair) {
result = getOverlappingsVectorAttr(r1, r2, ac, (Pair) testObject, inclusionMorphism);
}
else if (testObject instanceof Pair) {
result = getOverlappingsVectorAttr(r1, r2, (Pair) testObject, inclusionMorphism);
}
System.gc();
return result;
}
private Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getOverlappingsVectorAttr(
final Rule r1,
final Rule r2,
final OrdinaryMorphism nac,
Pair<?,?> extendedL2isoPair,
final OrdinaryMorphism inclusionMorphism) {
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
result = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
OrdinaryMorphism extendedL2iso = (OrdinaryMorphism) extendedL2isoPair.first;
OrdinaryMorphism extendedNAC2iso = (OrdinaryMorphism) extendedL2isoPair.second;
Pair<Rule, Pair<OrdinaryMorphism, OrdinaryMorphism>>
rulePair = (BaseFactory.theFactory()).constructIsomorphicRule(inclusionMorphism, true, false);
if (rulePair == null)
return result;
// rulePair.first is a rule which helps to create an overlapping graph
// mark Conflict Objects
for (Iterator<Node> en = inclusionMorphism.getSource().getNodesSet().iterator(); en
.hasNext();) {
GraphObject o = en.next();
// get object from LHS of r1
GraphObject i_o = inclusionMorphism.getImage(o);
// set critical if i_o should be changed
if (this.contextC1_L1.contains(i_o)) {
GraphObject obj = rulePair.second.first.getImage(o);
obj.setCritical(true);
}
}
for (Iterator<Arc> en = inclusionMorphism.getSource().getArcsSet().iterator();
en.hasNext();) {
GraphObject o = en.next();
// get object from LHS of r1
GraphObject i_o = inclusionMorphism.getImage(o);
// set critical if i_o should be changed
if (this.contextC1_L1.contains(i_o)) {
GraphObject obj = rulePair.second.first.getImage(o);
obj.setCritical(true);
}
}
Graph ograph = extendedL2iso.getTarget(); // overlap graph
MorphCompletionStrategy localStrategy = getLocalMorphismCompletionStrategy();
Match testm = (BaseFactory.theFactory()).createMatch(rulePair.first, ograph, true, "1");
testm.getTarget().setCompleteGraph(false);
testm.setCompletionStrategy(localStrategy, true);
testm.getCompletionStrategy().initialize(testm);
if (namedObjectOnly)
this.addNamedObjectConstraint(testm);
// TODO: find objs which changed by r1 and forbiden by nac of r2
List<GraphObject> changedObjs = getChangedObjs(r1);
List<GraphObject> newNACobj = ExcludePairHelper.getNewObjsWithConstAttr(nac);
List<GraphObject> criticDuetoNAC = ExcludePairHelper.getImgOfObj(extendedNAC2iso, newNACobj);
List<Triple<GraphObject,ValueMember,String>>
withVarDuetoNAC = ExcludePairHelper.getObjsWithVarDuetoImg(
testm.getAttrContext(), criticDuetoNAC, changedObjs, r1);
OrdinaryMorphism rStar = null;
Match m = null;
boolean nextMatch = true;
while (nextMatch) {
nextMatch = testm.nextCompletion();
nextMatch = nextMatch && testm.isMappingChanged();
nextMatch = nextMatch && testm.isTypeMaxMultiplicitySatisfied();
if (nextMatch) {
// BaseFactory.theFactory().replaceTransientTarVarBySrcVar(testm);
rStar = ograph.isomorphicCopy();
if (rStar == null)
break;
m = BaseFactory.theFactory().createMatch(rulePair.first, rStar.getTarget());
if (doCompose(localStrategy, m, testm, rStar)) {
if (!(localStrategy instanceof Completion_InheritCSP)
|| BaseFactory.theFactory().replaceParentByChild(rulePair.first, m, rStar)) {
m.adaptAttrContextValues(testm.getAttrContext());
// check whether at least one of critical objects matchs into N2-L2
boolean criticalOK = false;
Iterator<Node> en = m.getSource().getNodesSet().iterator();
while (en.hasNext()) {
GraphObject o = en.next();
if (o.isCritical()) {
GraphObject i_o = m.getImage(o);
Enumeration<GraphObject> en1 = rStar.getInverseImage(i_o);
if (en1.hasMoreElements()) {
GraphObject obj = en1.nextElement();
if (!extendedL2iso.getInverseImage(obj).hasMoreElements())
criticalOK = true;
else if (extendedNAC2isoContainsImageObjWithAttrConstant(extendedNAC2iso, obj))
criticalOK = true;
}
}
}
Iterator<Arc> ea = m.getSource().getArcsSet().iterator();
while (ea.hasNext()) {
GraphObject o = ea.next();
if (o.isCritical()) {
GraphObject i_o = m.getImage(o);
Enumeration<GraphObject> en1 = rStar.getInverseImage(i_o);
if (en1.hasMoreElements()) {
GraphObject obj = en1.nextElement();
if (!extendedL2iso.getInverseImage(obj).hasMoreElements())
criticalOK = true;
else if (extendedNAC2isoContainsImageObjWithAttrConstant(extendedNAC2iso, obj))
criticalOK = true;
}
}
}
if (criticalOK) {
try {
// Variables in work graph are allowed
OrdinaryMorphism
ms = (OrdinaryMorphism) TestStep.execute(m, true,this.equalVariableNameOfAttrMapping);
if ((this.grammar == null)
|| (!this.grammar.getConstraints().hasMoreElements()))
this.consistentOnly = false;
// the overlapping graph
boolean consistentOverlap = true;
if (ms != null && this.consistentOnly) {
if (!checkGraphConsistency(ms.getTarget(), r1.getLayer()))
consistentOverlap = false;
}
if (ms != null && consistentOverlap) {
OrdinaryMorphism mStar = rulePair.second.second.compose(ms);
ms.dispose(); ms = null; // ms - not more needed
if (mStar != null) {
boolean nac_critical = ExcludePairHelper.markObjDuetoNAC(withVarDuetoNAC, extendedNAC2iso, rStar);
if (nac_critical)
nac.setTextualComment(String.valueOf(CriticalPairData.CHANGE_FORBID_ATTR_CONFLICT));
Pair<OrdinaryMorphism, OrdinaryMorphism>
p = getValidMatchChangeAttr(r1, r2,
nac, extendedL2iso, extendedNAC2iso, mStar, rStar);
nac.setTextualComment("");
if (p != null) {
if (namedObjectOnly && !namedObjsConform(p))
p = null;
}
// p contains valid match1 and match2,
// now check attributes against r2 XXX
if (p != null && (attributeCritical(r1, r2, p, null)
|| nac_critical)) {
// now result pair contains 2 pairs:
// in this case: first is p1;
// second is a help pair p2 with
// morphisms:
// first = r2.left -> N2;
// second = nac.target -> N2
Pair<OrdinaryMorphism, OrdinaryMorphism>
p1 = new Pair<OrdinaryMorphism, OrdinaryMorphism>(mStar, rStar);
Pair<OrdinaryMorphism, OrdinaryMorphism>
p2 = new Pair<OrdinaryMorphism, OrdinaryMorphism>(
extendedL2iso, extendedNAC2iso);
Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
resultp = new Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>(
p1, p2);
result.addElement(resultp);
if (!this.complete)
nextMatch = false;
} else {
mStar.dispose(); mStar = null;
rStar.dispose(); rStar = null;
}
}
} else {
rStar.dispose(); rStar = null;
}
} catch (TypeException e) {}
} else {
rStar.dispose(); rStar = null;
}
} else {
rStar.dispose(); rStar = null;
}
} else {
rStar.dispose(); rStar = null;
}
m.dispose(); m = null;
}
} // while
// dispose helpers
testm.dispose(); testm = null;
localStrategy = null;
rulePair.second.first.dispose();
rulePair.second.second.dispose();
rulePair.first.disposeSuper();
rulePair.second.first = null;
rulePair.second.second = null;
rulePair.first = null;
rulePair = null;
changedObjs = null;
newNACobj = null;
criticDuetoNAC = null;
withVarDuetoNAC = null;
return result;
}
private boolean extendedNAC2isoContainsImageObjWithAttrConstant(
final OrdinaryMorphism extendedNACiso,
final GraphObject obj){
Enumeration<GraphObject> dom = extendedNACiso.getDomain();
while (dom.hasMoreElements()) {
GraphObject x = dom.nextElement();
if (extendedNACiso.getImage(x) == obj
&& x.getAttribute() != null) {
ValueTuple vt = (ValueTuple) x.getAttribute();
for (int i=0; i<vt.getNumberOfEntries(); i++) {
ValueMember vm = vt.getValueMemberAt(i);
if (this.attrMember2Expr.get(vm) != null) {
// System.out.println("#### morphAttrMember2Constant contains: "+x.getType().getName());
return true;
}
}
}
}
return false;
}
/*
private void replaceExprAttrValueByVariable(final AttrInstance attrInstance) {
if (attrInstance == null)
return;
final ValueTuple valTuple = (ValueTuple) attrInstance;
for (int i=0; i<valTuple.getNumberOfEntries(); i++) {
final ValueMember mem = valTuple.getValueMemberAt(i);
if (mem.isSet() && mem.getExpr().isComplex()) {
final String var = "val_".concat(mem.getExprAsText());
this.morphAttrMember2Expr.put(mem, new Pair<String,String>(var, mem.getExprAsText()));
System.out.println("### "+mem.getExprAsText()+" replaced by: "+var);
mem.setExpr(null);
mem.setExprAsText(var);
mem.setTransient(true);
}
}
}
*/
private void replaceConstAttrValByVar(final AttrInstance attrInstance) {
if (attrInstance == null)
return;
final ValueTuple valTuple = (ValueTuple) attrInstance;
for (int i=0; i<valTuple.getNumberOfEntries(); i++) {
final ValueMember mem = valTuple.getValueMemberAt(i);
if (mem.isSet() && mem.getExpr().isConstant()) {
final String var = "val_".concat(mem.getExprAsText());
this.attrMember2Expr.put(mem, new Pair<String,String>(var, mem.getExprAsText()));
// System.out.println("### "+mem.getExprAsText()+" replaced by: "+var);
mem.setExprAsText(var);
mem.setTransient(true);
}
}
}
protected void replaceVarAttrValueByConst(final OrdinaryMorphism morph) {
final Iterator<Node> nodes = morph.getTarget().getNodesSet().iterator();
while (nodes.hasNext()) {
final Node n = nodes.next();
doReplaceVarAttrValueByConst(n.getAttribute(), morph);
}
final Iterator<Arc> arcs = morph.getTarget().getArcsSet().iterator();
while (arcs.hasNext()) {
final Arc a = arcs.next();
doReplaceVarAttrValueByConst(a.getAttribute(), morph);
}
}
private void doReplaceVarAttrValueByConst(
final AttrInstance attrInstance,
final OrdinaryMorphism morph) {
if (attrInstance == null || this.attrMember2Expr.isEmpty())
return;
final ValueTuple valTuple = (ValueTuple) attrInstance;
for (int i=0; i<valTuple.getNumberOfEntries(); i++) {
final ValueMember mem = valTuple.getValueMemberAt(i);
if (mem.isSet() && mem.getExpr().isVariable()) {
final Pair<String,String> p = this.attrMember2Expr.get(mem);
if (p != null) {
final String expr = p.second;
final String var = mem.getExprAsText();
// System.out.println("### "+mem.getExprAsText()+" replaced by: "+expr);
mem.setExprAsText(expr);
mem.setTransient(false);
((VarTuple) morph.getAttrContext().getVariables()).deleteLeafDeclaration(var);
}
}
}
}
protected OrdinaryMorphism extendLeftGraphByNAC(
final OrdinaryMorphism isoLeft,
final OrdinaryMorphism nac,
boolean replaceConstantAttrByVariable) {
Graph extLeft = isoLeft.getTarget();
OrdinaryMorphism isoNAC = BaseFactory.theFactory().createMorphism(
nac.getTarget(), extLeft);
Hashtable<Node, Node> tmp = new Hashtable<Node, Node>(5);
// first iterate over nodes
Iterator<?> e = nac.getTarget().getNodesSet().iterator();
while (e.hasNext()) {
GraphObject o = (GraphObject) e.next();
// replaceExprAttrValueByVariable(o.getAttribute());
if (replaceConstantAttrByVariable) {
// replace and store constant attribute value
replaceConstAttrValByVar(o.getAttribute());
}
Node n = null;
if (!nac.getInverseImage(o).hasMoreElements()) {
try {
n = extLeft.copyNode((Node) o);
n.setContextUsage(nac.hashCode());
o.setContextUsage(nac.hashCode());
tmp.put((Node) o, n);
} catch (TypeException ex) {
// System.out.println("extendLeftGraphByNAC:TypeException:copyNode "+ex.getStackTrace());
}
} else {
n = (Node) isoLeft.getImage(nac.getInverseImage(o).nextElement());
}
if (n != null) {
try {
isoNAC.addMapping(o, n);
} catch (BadMappingException exc) {
//// System.out.println("extendLeftGraphByNAC:BadMappingException:Node "+exc.getStackTrace());
}
}
}
// now iterate over arcs
e = nac.getTarget().getArcsSet().iterator();
while (e.hasNext()) {
GraphObject o = (GraphObject) e.next();
// replaceExprAttrValueByVariable(o.getAttribute());
if (replaceConstantAttrByVariable)
replaceConstAttrValByVar(o.getAttribute());
Arc a = null;
if (!nac.getInverseImage(o).hasMoreElements()) {
Node src = tmp.get(((Arc) o).getSource());
if (src == null) {
if (nac.getInverseImage(((Arc) o).getSource()).hasMoreElements())
src = (Node) isoLeft.getImage(nac.getInverseImage(
((Arc) o).getSource()).nextElement());
}
Node tar = tmp.get(((Arc) o).getTarget());
if (tar == null) {
if (nac.getInverseImage(((Arc) o).getTarget()).hasMoreElements())
tar = (Node) isoLeft.getImage(nac.getInverseImage(
((Arc) o).getTarget()).nextElement());
}
try {
a = extLeft.copyArc((Arc) o, src, tar);
a.setContextUsage(nac.hashCode());
o.setContextUsage(nac.hashCode());
} catch (TypeException ex) {
// System.out.println("extendLeftGraphByNAC:TypeException:copyArc "+ex.getStackTrace());
}
} else {
a = (Arc) isoLeft.getImage(nac.getInverseImage(o).nextElement());
}
if (a != null) {
try {
isoNAC.addMapping(o, a);
} catch (BadMappingException exc) {
// System.out.println("extendLeftGraphByNAC:BadMappingException exc:NAC "+exc.getStackTrace());
}
}
}
return isoNAC;
}
protected Pair<OrdinaryMorphism, OrdinaryMorphism> extendLeftGraphByPAC(
final OrdinaryMorphism isoLeft,
final OrdinaryMorphism pac,
boolean replaceConstantAttrByVariable) {
Graph extLeft = isoLeft.getTarget();
OrdinaryMorphism embedPAC = BaseFactory.theFactory().createMorphism(
pac.getTarget(), extLeft);
final Hashtable<Node, Node> tmp = new Hashtable<Node, Node>(5);
Iterator<?> e = pac.getTarget().getNodesSet().iterator();
while (e.hasNext()) {
GraphObject o = (GraphObject) e.next();
if (!pac.getInverseImage(o).hasMoreElements()) {
try {
if (replaceConstantAttrByVariable) {
// replace and store constant attribute value
replaceConstAttrValByVar(o.getAttribute());
}
Node n = extLeft.copyNode((Node) o);
n.setContextUsage(o.hashCode());
o.setContextUsage(n.hashCode());
tmp.put((Node) o, n);
try {
embedPAC.addMapping(o, n);
} catch (BadMappingException exc) {
// System.out.println(exc.getStackTrace());
}
} catch (TypeException ex) {
// System.out.println(ex.getStackTrace());
}
} else {
try {
embedPAC.addMapping(o, isoLeft.getImage(pac
.getInverseImage(o).nextElement()));
} catch (BadMappingException exc) {
// System.out.println(exc.getStackTrace());
}
}
}
e = pac.getTarget().getArcsSet().iterator();
while (e.hasNext()) {
GraphObject o = (GraphObject) e.next();
if (!pac.getInverseImage(o).hasMoreElements()) {
Node src = tmp.get(((Arc) o).getSource());
if (src == null) {
src = (Node) isoLeft.getImage(pac.getInverseImage(
((Arc) o).getSource()).nextElement());
}
Node tar = tmp.get(((Arc) o).getTarget());
if (tar == null) {
tar = (Node) isoLeft.getImage(pac.getInverseImage(
((Arc) o).getTarget()).nextElement());
}
try {
if (replaceConstantAttrByVariable)
replaceConstAttrValByVar(o.getAttribute());
Arc a = extLeft.copyArc((Arc) o, src, tar);
a.setContextUsage(o.hashCode());
o.setContextUsage(a.hashCode());
try {
embedPAC.addMapping(o, a);
} catch (BadMappingException exc) {
// System.out.println(exc.getStackTrace());
}
} catch (TypeException ex) {
// System.out.println(ex.getStackTrace());
}
} else {
try {
embedPAC.addMapping(o, isoLeft.getImage(
pac.getInverseImage(o).nextElement()));
} catch (BadMappingException exc) {
// System.out.println(exc.getStackTrace());
}
}
}
return new Pair<OrdinaryMorphism, OrdinaryMorphism>(isoLeft, embedPAC);
}
private OrdinaryMorphism extendOverlapGraphByPACs(
final OrdinaryMorphism overlap,
final Rule r) {
boolean failed = false;
OrdinaryMorphism iso = overlap.getTarget().isoCopy();
Graph extLeft = iso.getTarget();
final Hashtable<Node, Node> tmp = new Hashtable<Node, Node>(5);
Enumeration<OrdinaryMorphism> pacs = r.getPACs();
while (!failed && pacs.hasMoreElements()) {
OrdinaryMorphism pac = pacs.nextElement();
Iterator<?> e = pac.getTarget().getNodesSet().iterator();
while (!failed && e.hasNext()) {
GraphObject o = (GraphObject) e.next();
if (!pac.getInverseImage(o).hasMoreElements()) {
try {
Node n = extLeft.copyNode((Node) o);
n.setContextUsage(o.hashCode());
o.setContextUsage(n.hashCode());
tmp.put((Node) o, n);
} catch (TypeException ex) {
failed = true;
}
}
}
e = pac.getTarget().getArcsSet().iterator();
while (!failed && e.hasNext()) {
GraphObject o = (GraphObject) e.next();
if (!pac.getInverseImage(o).hasMoreElements()) {
Node src = tmp.get(((Arc) o).getSource());
if (src == null) {
Enumeration<GraphObject> inv = pac.getInverseImage(((Arc) o).getSource());
if (inv.hasMoreElements()) {
GraphObject n = inv.nextElement();
src = (Node) iso.getImage(overlap.getImage(n));
}
}
failed = (src == null);
if (!failed) {
Node tar = tmp.get(((Arc) o).getTarget());
if (tar == null) {
Enumeration<GraphObject> inv = pac.getInverseImage(((Arc) o).getTarget());
if (inv.hasMoreElements()) {
GraphObject n = inv.nextElement();
tar = (Node) iso.getImage(overlap.getImage(n));
}
}
failed = (tar == null);
if (!failed) {
try {
Arc a = extLeft.copyArc((Arc) o, src, tar);
a.setContextUsage(o.hashCode());
o.setContextUsage(a.hashCode());
} catch (TypeException ex) {
failed = true;
}
}
}
}
}
tmp.clear();
if (failed) {
iso.dispose(false, true);
iso = null;
}
}
return iso;
}
/*
private boolean deleteUseType(Rule r1, Rule r2) {
Iterator<?> e = r1.getLeft().getNodesSet().iterator();
while (e.hasNext() && !this.stop) {
GraphObject o = (GraphObject) e.next();
if (r1.getImage(o) == null) {
Vector<GraphObject> v = r2.getLeft().getElementsOfTypeAsVector(o);
if (!v.isEmpty())
return true;
}
}
e = r1.getLeft().getArcsSet().iterator();
while (e.hasNext() && !this.stop) {
GraphObject o = (GraphObject) e.next();
if (r1.getImage(o) == null) {
Vector<GraphObject> v = r2.getLeft().getElementsOfTypeAsVector(o);
if (!v.isEmpty())
return true;
}
}
return false;
}
private boolean produceForbidType(Rule r1, Rule r2) {
Iterator<?> e = r1.getRight().getNodesSet().iterator();
while (e.hasNext() && !this.stop) {
GraphObject o = (GraphObject) e.next();
if (!r1.getInverseImage(o).hasMoreElements()) {
final List<OrdinaryMorphism> nacs = r2.getNACsList();
for (int l=0; l<nacs.size(); l++) {
final OrdinaryMorphism nac = nacs.get(l);
Vector<GraphObject> v = nac.getTarget().getElementsOfTypeAsVector(o);
if (!v.isEmpty()) {
for (int i = 0; i < v.size(); i++) {
GraphObject go = v.get(i);
if (!nac.getInverseImage(go).hasMoreElements())
return true;
}
}
}
}
}
e = r1.getRight().getArcsSet().iterator();
while (e.hasNext() && !this.stop) {
GraphObject o = (GraphObject) e.next();
if (!r1.getInverseImage(o).hasMoreElements()) {
final List<OrdinaryMorphism> nacs = r2.getNACsList();
for (int l=0; l<nacs.size(); l++) {
final OrdinaryMorphism nac = nacs.get(l);
Vector<GraphObject> v = nac.getTarget().getElementsOfTypeAsVector(o);
if (!v.isEmpty()) {
for (int i = 0; i < v.size(); i++) {
GraphObject go = v.get(i);
if (!nac.getInverseImage(go).hasMoreElements())
return true;
}
}
}
}
}
return false;
}
*/
private Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getOverlappingsVectorAttr(
final Rule r1,
final Rule r2,
final OrdinaryMorphism inclusionMorphism) {
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
result = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
final OrdinaryMorphism r2LeftIso = r2.getLeft().isomorphicCopy();
if (r2LeftIso == null)
return result;
Pair<Rule, Pair<OrdinaryMorphism, OrdinaryMorphism>>
rulePair = (BaseFactory.theFactory()).constructIsomorphicRule(inclusionMorphism, true, false);
if (rulePair == null)
return result;
// rulePair.first is a rule which helps to create an overlapping graph
final Graph ograph = r2LeftIso.getTarget(); // the overlap graph
MorphCompletionStrategy localStrategy = getLocalMorphismCompletionStrategy();
Match testm = (BaseFactory.theFactory()).createMatch(rulePair.first, ograph, true, "1");
testm.getTarget().setCompleteGraph(false);
testm.setCompletionStrategy(localStrategy, true);
testm.getCompletionStrategy().initialize(testm);
if (namedObjectOnly)
this.addNamedObjectConstraint(testm);
// r2.reflectTransientOfSimilarVar((VarTuple) testm.getAttrContext().getVariables());
OrdinaryMorphism rStar = null;
Match m = null;
boolean nextMatch = true;
while (nextMatch) {
nextMatch = testm.nextCompletion();
nextMatch = nextMatch && testm.isMappingChanged();
nextMatch = nextMatch && testm.isTypeMaxMultiplicitySatisfied();
if (nextMatch) {
// BaseFactory.theFactory().replaceTransientTarVarBySrcVar(testm);
rStar = ograph.isomorphicCopy();
m = (BaseFactory.theFactory()).createMatch(rulePair.first, rStar
.getTarget());
if (doCompose(localStrategy, m, testm, rStar)) {
if (!(localStrategy instanceof Completion_InheritCSP)
|| BaseFactory.theFactory().replaceParentByChild(rulePair.first, m, rStar)) {
m.adaptAttrContextValues(testm.getAttrContext());
try {
// Variables inside of testm.getTarget() graph are allowed
OrdinaryMorphism
ms = (OrdinaryMorphism) TestStep.execute(m,true,this.equalVariableNameOfAttrMapping);
if ((this.grammar == null)
|| (!this.grammar.getConstraints().hasMoreElements()))
this.consistentOnly = false;
boolean consistentOverlap = true;
if (ms != null && this.consistentOnly) {
if (!checkGraphConsistency(ms.getTarget(), r1.getLayer()))
consistentOverlap = false;
}
if (ms != null && consistentOverlap) {
OrdinaryMorphism mStar = rulePair.second.second.compose(ms);
ms.dispose(); ms = null; // ms - not more needed
if (mStar != null) {
Pair<OrdinaryMorphism, OrdinaryMorphism>
p = getValidMatchChangeAttr(r1, r2, r2LeftIso, mStar, rStar);
if (p != null) {
if (namedObjectOnly && !namedObjsConform(p)) {
p.first.dispose();
p.second.dispose();
p = null;
}
}
if (p != null && attributeCritical(r1, r2, p, null)) {
p.first.unsetCompletionStrategy();
p.second.unsetCompletionStrategy();
Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
resultp = new Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>(
p, null);
result.addElement(resultp);
if (!this.complete)
nextMatch = false;
} else {
if (p != null) {
p.first.dispose();
p.second.dispose();
}
mStar.dispose(); mStar = null;
rStar.dispose(); rStar = null;
}
}
} else {
rStar.dispose(); rStar = null;
}
} catch (TypeException e) {
// System.out.println(e.getLocalizedMessage());
}
} else {
rStar.dispose(); rStar = null;
}
} else {
rStar.dispose(); rStar = null;
}
m.dispose(); m = null;
}
} // while
// dispose helpers
testm.dispose(); testm = null;
localStrategy = null;
rulePair.second.first.dispose();
rulePair.second.second.dispose();
rulePair.first.disposeSuper();
rulePair.second.first = null;
rulePair.second.second = null;
rulePair.first = null;
rulePair = null;
return result;
}
private Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getOverlappingsVectorAttr(
final Rule r1,
final Rule r2,
// final OrdinaryMorphism extendedByPACsL2iso,
Pair<OrdinaryMorphism, OrdinaryMorphism> extendedByPACsL2iso,
final OrdinaryMorphism inclusionMorphism) {
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
result = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
Pair<Rule, Pair<OrdinaryMorphism, OrdinaryMorphism>>
rulePair = (BaseFactory.theFactory()).constructIsomorphicRule(inclusionMorphism, true, false);
if (rulePair == null)
return result;
// rulePair.first is a rule which helps to create an overlapping graph
Graph ograph = extendedByPACsL2iso.first.getTarget();
MorphCompletionStrategy localStrategy = getLocalMorphismCompletionStrategy();
Match testm = (BaseFactory.theFactory()).createMatch(rulePair.first, ograph, true, "1");
testm.getTarget().setCompleteGraph(false);
testm.setCompletionStrategy(localStrategy, true);
testm.getCompletionStrategy().initialize(testm);
if (namedObjectOnly)
this.addNamedObjectConstraint(testm);
OrdinaryMorphism rStar = null;
Match m = null;
boolean nextMatch = true;
while (nextMatch) {
nextMatch = testm.nextCompletion();
nextMatch = nextMatch && testm.isMappingChanged();
nextMatch = nextMatch && testm.isTypeMaxMultiplicitySatisfied();
if (nextMatch) {
// BaseFactory.theFactory().replaceTransientTarVarBySrcVar(testm);
rStar = ograph.isomorphicCopy();
if (rStar == null)
break;
m = (BaseFactory.theFactory()).
createMatch(rulePair.first, rStar.getTarget());
if (doCompose(localStrategy, m, testm, rStar)) {
if (!(localStrategy instanceof Completion_InheritCSP)
|| BaseFactory.theFactory().replaceParentByChild(rulePair.first, m, rStar)) {
m.adaptAttrContextValues(testm.getAttrContext());
try {
// Variables in testm.getTarget() graph are allowed
OrdinaryMorphism
ms = (OrdinaryMorphism) TestStep.execute(m,true,this.equalVariableNameOfAttrMapping);
if ((this.grammar == null)
|| (!this.grammar.getConstraints().hasMoreElements()))
this.consistentOnly = false;
// overlapping graph
boolean consistentOverlap = true;
if (ms != null && this.consistentOnly) {
if (!checkGraphConsistency(ms.getTarget(), r1.getLayer()))
consistentOverlap = false;
}
if (ms != null && consistentOverlap) {
OrdinaryMorphism mStar = rulePair.second.second.compose(ms);
ms.dispose(); ms = null; // ms - not more needed
if (mStar != null) {
Pair<OrdinaryMorphism, OrdinaryMorphism>
p = getValidMatchChangeAttr(r1, r2,
extendedByPACsL2iso.first, mStar, rStar);
if (p != null) {
if (namedObjectOnly && !namedObjsConform(p)) {
p = null;
}
}
if (p != null
&& attributeCritical(r1,r2,p,
new Pair<OrdinaryMorphism, OrdinaryMorphism>(
extendedByPACsL2iso.first, rStar))) {
p.first.unsetCompletionStrategy();
p.second.unsetCompletionStrategy();
Pair<OrdinaryMorphism, OrdinaryMorphism>
p2 = new Pair<OrdinaryMorphism, OrdinaryMorphism>(
extendedByPACsL2iso.second, rStar);
p2.first.unsetCompletionStrategy();
p2.second.unsetCompletionStrategy();
Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
resultp = new Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>(
p, p2);
result.addElement(resultp);
if (!this.complete)
nextMatch = false;
} else {
mStar.dispose(); mStar = null;
rStar.dispose(); rStar = null;
}
}
} else {
rStar.dispose(); rStar = null;
}
} catch (TypeException e) {}
} else {
rStar.dispose(); rStar = null;
}
} else {
rStar.dispose(); rStar = null;
}
m.dispose(); m = null;
}
} // while
// dispose helpers
testm.dispose(); testm = null;
localStrategy = null;
rulePair.second.first.dispose();
rulePair.second.second.dispose();
rulePair.first.disposeSuper();
rulePair.first = null;
rulePair.second.first = null;
rulePair.second.second = null;
rulePair = null;
return result;
}
@SuppressWarnings("unused")
private int getSizeOfCriticalOverlapping(final Pair<OrdinaryMorphism, OrdinaryMorphism> criticalPair) {
int nn = 0;
int criticals = 0;
final OrdinaryMorphism m1 = criticalPair.first;
final OrdinaryMorphism m2 = criticalPair.second;
final Graph g = m1.getTarget();
Iterator<Node> nodes = g.getNodesSet().iterator();
while (nodes.hasNext()) {
GraphObject o = nodes.next();
if (m1.getInverseImage(o).hasMoreElements()
&& m2.getInverseImage(o).hasMoreElements()) {
nn++;
// if (o.isCritical())
criticals++;
}
}
Iterator<Arc> arcs = g.getArcsSet().iterator();
while (arcs.hasNext()) {
GraphObject o = arcs.next();
if (m1.getInverseImage(o).hasMoreElements()
&& m2.getInverseImage(o).hasMoreElements()) {
nn++;
// if (o.isCritical())
criticals++;
}
}
// System.out.println("ExclutePair.getSizeOfCriticalOverlapping:: nn: "+nn+" criticals: "+criticals);
return nn;
}
@SuppressWarnings("unused")
private boolean ruleCreatesNamedObject(Rule r) {
List<GraphObject> newObjs = r.getElementsToCreate();
for (int i=0; i<newObjs.size(); i++) {
GraphObject go = newObjs.get(i);
if (go.getObjectName() != null
&& !go.getObjectName().equals("")) {
return true;
}
}
return false;
}
private boolean namedObjsConform(Pair<OrdinaryMorphism, OrdinaryMorphism> p) {
Iterator<Node> nodes = p.first.getTarget().getNodesSet().iterator();
while (nodes.hasNext()) {
Node n = nodes.next();
if (n.getObjectName() != null && !n.getObjectName().equals("")) {
List<GraphObject> l1 = p.first.getInverseImageList(n);
List<GraphObject> l2 = p.second.getInverseImageList(n);
if (l1.size() == 0 || l2.size() == 0) {
return false;
}
else if (!l1.get(0).getObjectName().equals(l2.get(0).getObjectName())) {
return false;
}
}
}
return true;
}
protected Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getOverlappingsVectorDeleteUse(
final Rule r1,
final Rule r2,
final OrdinaryMorphism inclusionMorphism) {
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
result = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
final OrdinaryMorphism r2LeftIso = r2.getLeft().isomorphicCopy();
if (r2LeftIso == null)
return result;
Pair<Rule, Pair<OrdinaryMorphism, OrdinaryMorphism>>
rulePair = (BaseFactory.theFactory()).constructIsomorphicRule(inclusionMorphism, true, false);
if (rulePair == null)
return result;
// if (ruleCreatesNamedObject(rulePair.first))
// return result;
// rulePair.first is a rule which helps to create an overlapping graph
// ((VarTuple) rulePair.first.getAttrContext().getVariables()).showVariables();
// ((VarTuple) r1.getAttrContext().getVariables()).showVariables();
// ((VarTuple) r2.getAttrContext().getVariables()).showVariables();
Graph ograph = r2LeftIso.getTarget(); // overlap graph
MorphCompletionStrategy localStrategy = getLocalMorphismCompletionStrategy();
Match testm = BaseFactory.theFactory().createMatch(rulePair.first, ograph, true, "1");
testm.getTarget().setCompleteGraph(false);
testm.setCompletionStrategy(localStrategy, true);
testm.getCompletionStrategy().initialize(testm);
if (namedObjectOnly)
this.addNamedObjectConstraint(testm);
// r2.reflectTransientOfSimilarVar((VarTuple) testm.getAttrContext().getVariables());
// ((VarTuple) r1.getAttrContext().getVariables()).showVariables();
// ((VarTuple) r2.getAttrContext().getVariables()).showVariables();
OrdinaryMorphism rStar = null;
Match m = null;
boolean nextMatch = true;
while (nextMatch) {
nextMatch = testm.nextCompletion();
// System.out.println(testm.getErrorMsg());
nextMatch = nextMatch && testm.isMappingChanged();
nextMatch = nextMatch && testm.isTypeMaxMultiplicitySatisfied();
// System.out.println(testm.getErrorMsg());
if (nextMatch) {
BaseFactory.theFactory().replaceTransientTarVarBySrcVar(testm);
rStar = ograph.isomorphicCopy();
// rStar.getTarget() == m.getTarget is the overlap graph
m = (BaseFactory.theFactory()).createMatch(rulePair.first, rStar.getTarget());
if (doCompose(localStrategy, m, testm, rStar)) {
if (!(localStrategy instanceof Completion_InheritCSP)
|| BaseFactory.theFactory().replaceParentByChild(rulePair.first, m, rStar)) {
m.adaptAttrContextValues(testm.getAttrContext());
try {
// Variables in testm.getTarget() graph are allowed
OrdinaryMorphism ms = (OrdinaryMorphism) TestStep.execute(m, true, this.equalVariableNameOfAttrMapping);
if (ms != null) {
if ((this.grammar == null)
|| (!this.grammar.getConstraints().hasMoreElements()))
this.consistentOnly = false;
boolean consistentOverlap = true;
if (this.consistentOnly) {
// check consistency of the overlapping graph
// ms.getTarget() == m.getTarget is the overlap graph
ms.getTarget().setCompleteGraph(false);
if (!checkGraphConsistency(ms.getTarget(), r1.getLayer())){
consistentOverlap = false;
}
}
if (consistentOverlap) {
OrdinaryMorphism mStar = rulePair.second.second.compose(ms);
ms.dispose(); ms = null; // ms - not more needed
if (mStar != null) {
// mStart is the first overlap morphism
// rStart is the second overlap morphism
Pair<OrdinaryMorphism, OrdinaryMorphism>
p = getValidMatchDeleteUse(r1, r2, r2LeftIso, mStar, rStar);
if (p != null) {
if (namedObjectOnly && !namedObjsConform(p)) {
p = null;
}
}
// now result pair contains 2 pairs:
// in this case: first is p; second is null
if (p != null) {
Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
resultp = new Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>(
p, null);
markDeleteUseCriticalObject(r2, resultp);
result.add(resultp);
if (!this.complete)
nextMatch = false;
} else {
mStar.dispose(); mStar = null;
rStar.dispose(); rStar = null;
}
}
} else {
rStar.dispose(); rStar = null;
}
}
} catch (TypeException e) {}
} else {
rStar.dispose(); rStar = null;
}
} else {
rStar.dispose(); rStar = null;
}
m.dispose(); m = null;
}
} // while
// dispose helpers
testm.dispose(); testm = null;
localStrategy = null;
rulePair.second.first.dispose();
rulePair.second.second.dispose();
rulePair.first.disposeSuper();
rulePair.second.first = null;
rulePair.second.second = null;
rulePair = null;
r2LeftIso.dispose();
return result;
}
protected Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getOverlappingsVectorDeleteUse(
final Rule r1,
final Rule r2,
final Pair<OrdinaryMorphism, OrdinaryMorphism> extendedByPACsL2iso,
final OrdinaryMorphism inclusionMorphism) {
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
result = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
Graph other = extendedByPACsL2iso.first.getTarget();
Pair<Rule, Pair<OrdinaryMorphism, OrdinaryMorphism>>
rulePair = (BaseFactory.theFactory()).constructIsomorphicRule(inclusionMorphism, true, false);
if (rulePair == null)
return result;
// if (ruleCreatesNamedObject(rulePair.first))
// return result;
// rulePair.first is a rule which helps to create an overlapping graph
MorphCompletionStrategy localStrategy = getLocalMorphismCompletionStrategy();
Match testm = (BaseFactory.theFactory()).createMatch(rulePair.first, other, true, "1");
testm.getTarget().setCompleteGraph(false);
testm.setCompletionStrategy(localStrategy, true);
testm.getCompletionStrategy().initialize(testm);
if (namedObjectOnly)
this.addNamedObjectConstraint(testm);
OrdinaryMorphism rStar = null;
Match m = null;
boolean nextMatch = true;
while (nextMatch) {
nextMatch = testm.nextCompletion();
nextMatch = nextMatch && testm.isMappingChanged();
nextMatch = nextMatch && testm.isTypeMaxMultiplicitySatisfied();
if (nextMatch) {
// BaseFactory.theFactory().replaceTransientTarVarBySrcVar(testm);
rStar = other.isomorphicCopy();
if (rStar == null)
break;
m = (BaseFactory.theFactory()).createMatch(rulePair.first, rStar.getTarget());
if (doCompose(localStrategy, m, testm, rStar)) {
if (!(localStrategy instanceof Completion_InheritCSP)
|| BaseFactory.theFactory().replaceParentByChild(rulePair.first, m, rStar)) {
m.adaptAttrContextValues(testm.getAttrContext());
try {
// Variables in testm.getTarget() graph are allowed
OrdinaryMorphism
ms = (OrdinaryMorphism) TestStep.execute(m,true,this.equalVariableNameOfAttrMapping);
if (ms != null) {
if ((this.grammar == null)
|| (!this.grammar.getConstraints().hasMoreElements()))
this.consistentOnly = false;
// overlapping graph
boolean consistentOverlap = true;
if (this.consistentOnly) {
ms.getTarget().setCompleteGraph(false);
if (!checkGraphConsistency(ms.getTarget(), r1.getLayer())) {
consistentOverlap = false;
}
}
if (consistentOverlap) {
OrdinaryMorphism mStar = rulePair.second.second.compose(ms);
ms.dispose(); ms = null; // ms - not more needed
if (mStar != null) {
Pair<OrdinaryMorphism, OrdinaryMorphism>
p = getValidMatchDeleteUse(r1, r2,
extendedByPACsL2iso.first, mStar, rStar);
if (p != null) {
if (namedObjectOnly && !namedObjsConform(p)) {
p = null;
}
}
// now result pair contains 2 pairs:
if (p != null) {
Pair<OrdinaryMorphism, OrdinaryMorphism>
p2 = new Pair<OrdinaryMorphism, OrdinaryMorphism>(
extendedByPACsL2iso.second, rStar);
Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
resultp = new Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>(
p, p2);
markDeleteUseCriticalObject(r2, resultp);
result.add(resultp);
if (!this.complete)
nextMatch = false;
} else {
mStar.dispose(); mStar = null;
rStar.dispose(); rStar = null;
}
}
} else {
rStar.dispose(); rStar = null;
}
}
} catch (TypeException e) {}
} else {
rStar.dispose(); rStar = null;
}
} else {
rStar.dispose(); rStar = null;
}
m.dispose(); m = null;
}
} // while
testm.dispose(); testm = null;
localStrategy = null;
rulePair.second.first.dispose();
rulePair.second.second.dispose();
rulePair.first.disposeSuper();
rulePair.first = null;
rulePair.second.first = null;
rulePair.second.second = null;
rulePair = null;
return result;
}
private void extendTypeObjectsMapByParentObjects(Graph g) {
Iterator<Node> nodes = g.getNodesSet().iterator();
while (nodes.hasNext()) {
Node n = nodes.next();
Vector<Type> childTypes = n.getType().getChildren();
for (int i=0; i<childTypes.size(); i++) {
Type childT = childTypes.get(i);
HashSet<GraphObject> objs = g.getTypeObjectsMap().get(childT.convertToKey());
if (objs != null && !objs.contains(n)) {
objs.add(n);
}
}
}
// Enumeration<Arc> arcs = g.getArcs();
// while (arcs.hasMoreElements()) {
// Arc a = arcs.nextElement();
// Type t = a.getType();
// Type srcT = a.getSource().getType();
// Type tarT = a.getTarget().getType();
//
// Vector<Type> mySrcParents = srcT.getAllParents();
// Vector<Type> myTarParents = tarT.getAllParents();
// for (int i = 0; i < mySrcParents.size(); ++i) {
// srcT = mySrcParents.get(i);
// for (int j = 0; j < myTarParents.size(); ++j) {
// tarT = myTarParents.get(j);
// String keystr = srcT.convertToKey()
// + t.convertToKey()
// + tarT.convertToKey();
// Vector<GraphObject> objs = g.getTypeObjectsMap().get(keystr);
// if (objs != null) {
// String str = srcT.getName()+"-"+t.getName()+"-"+tarT.getName();
// System.out.println(str+" "+objs);
// }
// }
// }
// Vector<Type> srcChildTypes = srcT.getChildren();
// Vector<Type> tarChildTypes = tarT.getChildren();
// for (int i = 0; i < srcChildTypes.size(); ++i) {
// srcT = srcChildTypes.get(i);
// for (int j = 0; j < tarChildTypes.size(); ++j) {
// tarT = tarChildTypes.get(j);
// String keystr = srcT.convertToKey()
// + t.convertToKey()
// + tarT.convertToKey();
// Vector<GraphObject> objs = g.getTypeObjectsMap().get(keystr);
// if (objs == null) {
// objs = new Vector<GraphObject>();
// g.getTypeObjectsMap().put(keystr, objs);
// }
// if (!objs.contains(a)) {
// objs.add(a);
// System.out.println(keystr+" "+objs);
// }
// }
// }
// }
}
private boolean tryValidateNACAttrCond(
final Rule r2,
final OrdinaryMorphism nac,
final OrdinaryMorphism nacEmbedding,
final Match match) {
boolean result = true;
if (nac.getAttrContext().getConditions().getNumberOfEntries() > 0) {
final List<VarMember> list = new Vector<VarMember>(1);
final Enumeration<GraphObject> nacdom = nacEmbedding.getDomain();
while (nacdom.hasMoreElements()) {
final GraphObject nacobj = nacdom.nextElement();
final GraphObject obj2 = nacEmbedding.getImage(nacobj);
if (match.getInverseImage(obj2).hasMoreElements()) {
final GraphObject obj1 = match.getInverseImage(obj2).nextElement();
if (obj2.getAttribute() != null) {
for (int i=0; i<obj2.getAttribute().getNumberOfEntries(); i++) {
ValueMember obj2mem = (ValueMember) obj2.getAttribute().getMemberAt(i);
ValueMember obj1mem = (ValueMember) obj1.getAttribute().getMemberAt(obj2mem.getName());
if (obj1mem != null && obj1mem.isSet() && obj1mem.getExpr().isConstant()
&& obj2mem.isSet() && obj2mem.getExpr().isVariable()) {
VarMember var = nac.getAttrContext().getVariables().getVarMemberAt(obj2mem.getExprAsText());
if (var != null) {
var.setExprAsText(obj1mem.getExprAsText());
list.add(var);
}
}
}
}
}
}
// ((VarTuple) nac.getAttrContext().getVariables()).showVariables();
// ((CondTuple) nac.getAttrContext().getConditions()).showConditions();
result = this.checkAttrCondOfApplCond(nac);
for (int i=0; i<list.size(); i++) {
list.get(i).undoUnification();
list.get(i).setExpr(null);
}
}
return result;
}
private Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getOverlappingsVectorProduceForbid(
final Rule r1,
final Rule r2,
final OrdinaryMorphism nac,
final Pair<OrdinaryMorphism, OrdinaryMorphism> extendedL2isoPair,
final OrdinaryMorphism inclusionMorphism) {
//System.out.println("getOverlappingsVectorProduceForbid(5) "+r1.getName()+" & "+r2.getName());
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
result = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
OrdinaryMorphism extendedL2iso = extendedL2isoPair.first;
OrdinaryMorphism extendedNAC2iso = extendedL2isoPair.second;
// construct rule from h
Pair<Rule, Pair<OrdinaryMorphism, OrdinaryMorphism>>
rulePair = (BaseFactory.theFactory()).constructIsomorphicRule(inclusionMorphism, true, true);
if (rulePair == null)
return result;
Rule hr = rulePair.first; // help rule to create overlappings
OrdinaryMorphism isoLHShr = rulePair.second.first;
OrdinaryMorphism isoRHShr = rulePair.second.second;
// mark Conflict Objects
for (Iterator<Node> en = inclusionMorphism.getSource().getNodesSet().iterator(); en
.hasNext();) {
GraphObject o = en.next();
GraphObject i_o = inclusionMorphism.getImage(o);
if (!r1.getInverseImage(i_o).hasMoreElements()) {
GraphObject obj = isoLHShr.getImage(o);
obj.setCritical(true);
}
}
for (Iterator<Arc> en = inclusionMorphism.getSource().getArcsSet().iterator();
en.hasNext();) {
GraphObject o = en.next();
GraphObject i_o = inclusionMorphism.getImage(o);
if (!r1.getInverseImage(i_o).hasMoreElements()) {
GraphObject obj = isoLHShr.getImage(o);
obj.setCritical(true);
}
}
MorphCompletionStrategy localStrategy = getLocalMorphismCompletionStrategy();
Match testm = (BaseFactory.theFactory()).createMatch(hr,
extendedL2iso.getTarget(), true, "1");
testm.getTarget().setCompleteGraph(false);
testm.setCompletionStrategy(localStrategy, true);
testm.getCompletionStrategy().initialize(testm);
if (namedObjectOnly)
this.addNamedObjectConstraint(testm);
OrdinaryMorphism rStar = null;
Match m = null;
boolean nextMatch = true;
while (nextMatch) {
nextMatch = testm.nextCompletion();
nextMatch = nextMatch && testm.isMappingChanged();
nextMatch = nextMatch && testm.isTypeMaxMultiplicitySatisfied();
boolean condOK = this.tryValidateNACAttrCond(r2, nac, extendedNAC2iso, testm);
if (nextMatch && condOK) {
// BaseFactory.theFactory().replaceTransientTarVarBySrcVar(testm);
rStar = extendedL2iso.getTarget().isomorphicCopy();
if (rStar == null)
break;
if (this.withInheritance)
this.extendTypeObjectsMapByParentObjects(rStar.getTarget());
m = (BaseFactory.theFactory()).createMatch(hr, rStar.getTarget());
if (doCompose(localStrategy, m, testm, rStar)) {
if (!(localStrategy instanceof Completion_InheritCSP)
|| BaseFactory.theFactory().replaceParentByChild(hr, m, rStar)) {
m.adaptAttrContextValues(testm.getAttrContext());
// check whether at least one of critical objects matches
// into N2-L2
boolean criticalOK = false;
Iterator<?> en = testm.getSource().getNodesSet().iterator();
while (en.hasNext()) {
GraphObject o = (GraphObject) en.next();
if (o.isCritical()) {
GraphObject i_o = testm.getImage(o);
if (!extendedL2iso.
getInverseImage(i_o).hasMoreElements()) {
criticalOK = true;
m.getImage(o).setCritical(true);
}
}
}
en = testm.getSource().getArcsSet().iterator();
while (en.hasNext()) {
GraphObject o = (GraphObject) en.next();
if (o.isCritical()) {
GraphObject i_o = testm.getImage(o);
if (!extendedL2iso.
getInverseImage(i_o).hasMoreElements()) {
criticalOK = true;
m.getImage(o).setCritical(true);
}
}
}
if (criticalOK) {
try {
// Variables in work graph are allowed
OrdinaryMorphism
ms = (OrdinaryMorphism) TestStep.execute(m, true ,this.equalVariableNameOfAttrMapping);
if ((this.grammar == null)
|| (!this.grammar.getConstraints()
.hasMoreElements()))
this.consistentOnly = false;
boolean consistentOverlap = true;
if (ms != null && this.consistentOnly) {
ms.getTarget().setCompleteGraph(false);
if (!checkGraphConsistency(
ms.getTarget(), r1.getLayer()))
consistentOverlap = false;
}
if (ms != null && consistentOverlap) {
// make help mStar of first overlap morphism
OrdinaryMorphism mStar = isoRHShr.compose(ms);
ms.dispose(); ms = null; // ms - not more needed
if (mStar != null) {
Pair<OrdinaryMorphism, OrdinaryMorphism>
p = getValidMatchProduceForbid(
r1, r2, nac, mStar, rStar,
extendedL2iso);
if (p != null) {
if (namedObjectOnly && !namedObjsConform(p)) {
p = null;
}
}
if (p != null) {
// now result pair contains 2 pairs:
// in this case: first is p1;
// second is a help pair p2 with two
// morphisms:
// first = r2.left -> N2;
// second = nac.target -> N2
Pair<OrdinaryMorphism, OrdinaryMorphism>
p1 = new Pair<OrdinaryMorphism, OrdinaryMorphism>(
// p.first, p.second);
mStar, rStar);
Pair<OrdinaryMorphism, OrdinaryMorphism>
p2 = new Pair<OrdinaryMorphism, OrdinaryMorphism>(
extendedL2iso,
extendedNAC2iso);
Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
resultp = new Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>(
p1, p2);
markProduceForbidCriticalObject(resultp);
result.add(resultp);
if (!this.complete)
nextMatch = false;
} else {
mStar.dispose(); mStar = null;
rStar.dispose(); rStar = null;
}
}
} else {
rStar.dispose(); rStar = null;
}
} catch (TypeException e) {}
}
} else {
rStar.dispose(); rStar = null;
}
} else {
rStar.dispose(); rStar = null;
}
m.dispose(); m = null;
} else
nextMatch = false;
} // while
// dispose helpers
testm.dispose(); testm = null;
localStrategy = null;
isoLHShr.dispose();
isoRHShr.dispose();
hr.disposeSuper();
isoLHShr = null;
isoRHShr = null;
hr = null;
rulePair = null;
return result;
}
/*
private Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
isIsomorphicOverlapping(
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> overlapPairs,
Pair<OrdinaryMorphism, OrdinaryMorphism> overlapPair) {
Graph overlapGraph = overlapPair.first.getTarget();
for (int j = 0; j < overlapPairs.size() && !this.stop; j++) {
Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>> pj = overlapPairs.elementAt(j);
Pair<OrdinaryMorphism, OrdinaryMorphism> p1 = pj.first;
Graph g = p1.first.getTarget();
Vector<OrdinaryMorphism> overlapIsos = g.getIsomorphicWith(overlapGraph, true);
for (int i = 0; i < overlapIsos.size(); i++) {
OrdinaryMorphism overlapIso = overlapIsos.get(i);
if (overlapIso != null) {
if (p1.first.isIsomorphicTo(overlapPair.first, overlapIso)) {
if (p1.second.isIsomorphicTo(overlapPair.second,overlapIso)) {
return pj;
}
}
}
}
}
return null;
}
*/
/*
* Return inclusions with size <= maxSize.
* @param maxSize
* @param inclusions a Vector with inclusions
* @return
*/
// @SuppressWarnings("unused")
// private Vector<Vector<GraphObject>> removeInclusionBiggerMaxSize(
// int maxSize,
// final Vector<Vector<GraphObject>> inclusions) {
// final Vector<Vector<GraphObject>> result = new Vector<Vector<GraphObject>>();
// for (int i=0; i<inclusions.size(); i++) {
// Vector<GraphObject> vec = inclusions.get(i);
// if (vec.size() <= maxSize)
// result.add(vec);
// }
// inclusions.trimToSize();
// return result;
// }
/*
private void removeEqualInclusion(final Vector<Vector<GraphObject>> incls) {
final Vector<Vector<GraphObject>> tmp = new Vector<Vector<GraphObject>>();
for (int i=incls.size()-1; i>=0; i--) {
final Vector<GraphObject> vi = incls.get(i);
for (int j=incls.size()-1; j>=0; j--) {
final Vector<GraphObject> vj = incls.get(j);
if (vj != vi) {
if (vj.size() == vi.size()) {
// System.out.println("removeEqualInclusion:: "+vj.size()+" == "+vi.size());
boolean found = true;
for (int k=0; k<vj.size() && found; k++) {
GraphObject go = vj.get(k);
if (!vi.contains(go)) {
found = false;
}
}
for (int k=0; k<vi.size() && found; k++) {
GraphObject go = vi.get(k);
if (!vj.contains(go)) {
found = false;
}
}
if (found)
tmp.add(vj);
}
}
}
if (!tmp.isEmpty()) {
incls.removeAll(tmp);
// System.out.println("removeEqualInclusion:: tmp.size: "+tmp.size());
tmp.clear();
}
}
}
*/
/*
* Compute left critical (delete) context, boundary and preserved sets of rule objects
* due to the given neededTypes.
* Fill also set toDelete.
*/
void computeLeftC_B_K(final Rule r,
final Vector<GraphObject> context,
final Vector<GraphObject> boundary,
final Vector<GraphObject> preserved,
final Vector<GraphObject> toDelete,
final Vector<Pair<Type, Pair<Type, Type>>> neededTypes) {
// first handle nodes
// use eventualy typesTG_N2
Iterator<?> e = r.getLeft().getNodesSet().iterator();
while (e.hasNext()) {
GraphObject o = (GraphObject) e.next();
if (isInTypes(neededTypes, o)) {
if (r.getImage(o) == null) {
context.add(o);
toDelete.add(o);
} else
preserved.add(o);
}
}
// now handle edges
e = r.getLeft().getArcsSet().iterator();
while (e.hasNext()) {
GraphObject o = (GraphObject) e.next();
if (isInTypes(neededTypes, o)) {
if (r.getImage(o) == null) {
/*
* boundary is not used now
* if(r.getImage(((Arc)o).getSource()) != null){
* if(!boundary.contains(((Arc)o).getSource()))
* boundary.add(((Arc)o).getSource()); }
* if(r.getImage(((Arc)o).getTarget()) != null){
* if(!boundary.contains(((Arc)o).getTarget()))
* boundary.add(((Arc)o).getTarget()); }
*/
if (!context.contains(((Arc) o).getSource())) {
context.add(((Arc) o).getSource());
}
if (!context.contains(((Arc) o).getTarget())) {
context.add(((Arc) o).getTarget());
}
context.add(o);
toDelete.add(o);
// remove preserved src, tar of delete edge from preserved
// container
// src, tar of delete edge are in context container only
preserved.remove(((Arc) o).getSource());
preserved.remove(((Arc) o).getTarget());
} else {
preserved.add(o);
// if (!context.contains(((Arc) o).getSource())
// && !preserved.contains(((Arc) o).getSource()))
// preserved.add(((Arc) o).getSource());
// if (!context.contains(((Arc) o).getTarget())
// && !preserved.contains(((Arc) o).getTarget()))
// preserved.add(((Arc) o).getTarget());
}
}
}
}
/*
* Compute rifht critical (produce) context, boundary and preserved sets of rule objects
* due to the given neededTypes.
* Fill also set toProduce.
*/
void computeRightC_B_K(final Rule r,
final Vector<GraphObject> context,
final Vector<GraphObject> boundary,
final Vector<GraphObject> preserved,
final Vector<GraphObject> toProduce,
final Vector<Pair<Type, Pair<Type, Type>>> neededTypes) {
// first handle nodes
Iterator<?> e = r.getRight().getNodesSet().iterator();
while (e.hasNext()) {
GraphObject o = (GraphObject) e.next();
if (isInTypes(neededTypes, o)) {
if (!r.getInverseImage(o).hasMoreElements()) {
context.add(o);
toProduce.add(o);
} else {
if (!this.essential)
preserved.add(o);
// else //if (o.getType().getSourceMax() > 0)
// context.add(o);
}
} else {
// if (o.getType().getSourceMax() > 0)
{
if (!this.essential) {
if (!r.getInverseImage(o).hasMoreElements())
toProduce.add(o);
else
preserved.add(o);
}
// else
// context.add(o);
}
}
}
// now handle edges
e = r.getRight().getArcsSet().iterator();
while (e.hasNext()) {
GraphObject o = (GraphObject) e.next();
// Type src_t = ((Arc) o).getSource().getType();
// Type tar_t = ((Arc) o).getTarget().getType();
if (isInTypes(neededTypes, o)) {
if (!r.getInverseImage(o).hasMoreElements()) {
/*
* boundary is not used now
* if(r.getInverseImage(((Arc)o).getSource()).hasMoreElements()){
* if(!boundary.contains(((Arc)o).getSource()))
* boundary.add(((Arc)o).getSource()); }
* if(r.getInverseImage(((Arc)o).getTarget()).hasMoreElements()){
* if(!boundary.contains(((Arc)o).getTarget()))
* boundary.add(((Arc)o).getTarget()); }
*/
if (!context.contains(((Arc) o).getSource()))
context.add(((Arc) o).getSource());
if (!context.contains(((Arc) o).getTarget()))
context.add(((Arc) o).getTarget());
context.add(o);
toProduce.add(o);
// remove preserved src, tar of new edge from preserved
// container
// src, tar of new edge are in context container only
preserved.remove(((Arc) o).getSource());
preserved.remove(((Arc) o).getTarget());
} else {
if (!this.essential) {
preserved.add(o);
}
}
}
else {
// if (o.getType().getSourceMax(src_t, tar_t) > 0
// || o.getType().getTargetMax(src_t, tar_t) > 0)
{
if (!this.essential) {
if (!r.getInverseImage(o).hasMoreElements())
toProduce.add(o);
else {
preserved.add(o);
if (!preserved.contains(((Arc) o).getSource())
&& !context.contains(((Arc) o).getSource()))
preserved.add(((Arc) o).getSource());
if (!preserved.contains(((Arc) o).getTarget())
&& !context.contains(((Arc) o).getTarget()))
preserved.add(((Arc) o).getTarget());
}
}
// else {
// context.add(o);
// if (!context.contains(((Arc) o).getTarget()))
// context.add (((Arc) o).getTarget());
// if (!context.contains(((Arc) o).getSource()))
// context.add (((Arc) o).getSource());
// }
}
}
}
}
protected OrdinaryMorphism makeInclusionMorphism(
final Vector<GraphObject> inclusion,
final Graph g) {
Node source = null;
Node target = null;
Graph subGraph = BaseFactory.theFactory().createGraph(g.getTypeSet());
OrdinaryMorphism inclMorph = (BaseFactory.theFactory()).createMorphism(
subGraph, g);
for (int i = 0; i < inclusion.size(); i++) {
GraphObject go = inclusion.elementAt(i);
if (go.isNode()) {
Node n = null;
try {
n = subGraph.copyNode((Node) go);
n.setContextUsage(((Node) go).getContextUsage());
} catch (TypeException e) {
// System.out.println(e.getStackTrace());
}
try {
inclMorph.addMapping(n, go);
} catch (BadMappingException e) {
System.out.println("makeInclusionMorphism:: "+e.getLocalizedMessage());
}
}
}
for (int i = 0; i < inclusion.size(); i++) {
GraphObject go = inclusion.elementAt(i);
if (go.isArc()) {
Enumeration<GraphObject> sources = inclMorph.getInverseImage(((Arc) go)
.getSource());
if (sources.hasMoreElements()) {
source = (Node) sources.nextElement();
}
Enumeration<GraphObject> targets = inclMorph.getInverseImage(((Arc) go)
.getTarget());
if (targets.hasMoreElements()) {
target = (Node) targets.nextElement();
}
if (source == null || target == null)
return null;
Arc a = null;
try {
a = subGraph.copyArc((Arc) go, source, target);
if (a != null) {
a.setContextUsage(((Arc) go).getContextUsage());
try {
inclMorph.addMapping(a, go);
} catch (BadMappingException e) {
System.out.println(e.getLocalizedMessage());
}
}
} catch (TypeException e) {
// System.out.println(e.getStackTrace());
}
}
}
if (inclMorph.getSize() != inclMorph.getSource().getSize()) {
return null;
}
return inclMorph;
}
/**
* Each inner vector of given incls must contain at least one GraphObject from the
* given neededGOs. Otherwise it is removed from the Vector incls.
*/
protected void checkInclusions(
final Vector<Vector<GraphObject>> incls,
final Vector<GraphObject> neededGOs) {
for (int i = 0; i < incls.size(); i++) {
Vector<GraphObject> v = incls.get(i);
boolean inclOK = false;
for (int j = 0; j < v.size(); j++) {
GraphObject o = v.get(j);
if (neededGOs.contains(o)) {
inclOK = true;
break;
}
}
if (!inclOK) {
incls.remove(v);
i--;
}
}
incls.trimToSize();
}
/**
* Each inner vector of given incls must contain at least one named GraphObject
* (the name of a GraphObject is not null or empty).
* Otherwise it is removed from the Vector incls.
*/
protected void checkInclusionsDuetoNamedObject(final Vector<Vector<GraphObject>> incls) {
for (int i = 0; i < incls.size(); i++) {
Vector<GraphObject> v = incls.get(i);
boolean inclOK = false;
for (int j = 0; j < v.size(); j++) {
GraphObject o = v.get(j);
if (//(o instanceof Node) &&
!o.getObjectName().isEmpty() ) {
inclOK = true;
break;
}
}
if (!inclOK) {
incls.remove(v);
i--;
}
}
incls.trimToSize();
}
protected void addNamedObjectConstraint(final Match m) {
Iterator<Node> iter1 = m.getSource().getNodesSet().iterator();
while (iter1.hasNext()) {
Node go = iter1.next();
if (!"".equals(go.getObjectName()))
m.getCompletionStrategy().addObjectNameConstraint(go);
}
}
protected void removeNamedObjectConstraint(final Match m) {
Iterator<Node> iter1 = m.getSource().getNodesSet().iterator();
while (iter1.hasNext()) {
Node go = iter1.next();
if (!"".equals(go.getObjectName()))
m.getCompletionStrategy().removeObjectNameConstraint(go);
}
}
private Vector<Vector<GraphObject>> checkInclusionsAgainstNac(
final Vector<Vector<GraphObject>> incls,
final Vector<GraphObject> nacRestriction) {
Vector<Vector<GraphObject>> result = new Vector<Vector<GraphObject>>();
for (int i = 0; i < incls.size(); i++) {
Vector<GraphObject> v = incls.get(i);
boolean inclOK = false;
for (int j = 0; j < v.size(); j++) {
GraphObject o = v.get(j);
for (int k = 0; k < nacRestriction.size(); k++) {
GraphObject o_k = nacRestriction.get(k);
if (o.getType().compareTo(o_k.getType())) {
if (o.isArc()) {
/* test only!!!
Vector<GraphObject> tmp = new Vector<GraphObject>();
tmp.add(((Arc)o).getSource());
boolean added = false;
for (int r = 0; r<result.size(); r++) {
if (result.get(r).size() == 1
&& (result.get(r).get(0) != ((Arc)o).getSource())) {
result.add(tmp);
added = true;
break;
}
}
if (!added) {
result.add(tmp);
}
tmp = new Vector<GraphObject>();
tmp.add(((Arc)o).getTarget());
added = false;
for (int r = 0; r<result.size(); r++) {
if (result.get(r).size() == 1
&& (result.get(r).get(0) != ((Arc)o).getTarget())) {
result.add(tmp);
added = true;
break;
}
}
if (!added) {
result.add(tmp);
}
*/
}
inclOK = true;
break;
}
}
if (inclOK)
break;
}
if (inclOK) {
result.add(v);
}
}
return result;
}
protected boolean checkGraphConsistency(final Graph g, int l) {
if (this instanceof LayeredExcludePair)
return ((LayeredExcludePair) this).checkGraphConsistency(g, l);
// boolean res = this.grammar.checkGraphConsistency(g);
// if (!res) {
// System.out.println("consistentOverlap: "+this.grammar.getConsistencyErrorMsg());
// }
// return res;
return this.grammar.checkGraphConsistency(g);
}
/**
* Checks the attributes if they are critic.
*
* @param r1
* The first rule
* @param r2
* The second rule
* @param overlapping
* The pair of overlapping morphisms
* @return true if r1 excludes r2
*/
protected boolean attributeCritical(
final Rule r1,
final Rule r2,
final Pair<OrdinaryMorphism, OrdinaryMorphism> overlapping,
final Pair<OrdinaryMorphism, OrdinaryMorphism> helpPair) {
boolean result = false;
// global container of rule r1
if (this.preservedChanged.isEmpty()) {
return false;
}
// changed attributes of r1
List<GraphObject> changedAttributesR1 = new Vector<GraphObject>(5);
for (int i = 0; i < this.preservedChanged.size(); i++) {
if (ExcludePairHelper.doesRuleChangeAttr(
r1, this.preservedChanged.elementAt(i))) {
changedAttributesR1.add(this.preservedChanged.elementAt(i));
}
}
if (changedAttributesR1.isEmpty()) {
changedAttributesR1 = null;
return false;
}
// forbidden attributes of r2
List<Type> forbiddenTypesR2 = ExcludePairHelper.getForbiddenTypesRule2(
r2,
this.attrMember2Expr);
// check all changed attributes
for (int i = 0; i < changedAttributesR1.size() /*&& !result*/; i++) {
final GraphObject l1Object = changedAttributesR1.get(i);
final OrdinaryMorphism l1G = overlapping.first;
final GraphObject overlapObject = l1G.getImage(l1Object);
final OrdinaryMorphism l2G = overlapping.second;
Enumeration<GraphObject> l2Objects = l2G.getInverseImage(overlapObject);
// es werden nur injektiv erzeugte ueberlappungsgraphen betrachtet
// daher kann es nicht mehrere objekte geben.
if (l2Objects.hasMoreElements()) {
final GraphObject l2Object = l2Objects.nextElement();
Vector<ValueMember>
changedMembersR1 = ExcludePairHelper.getChangedAttributeMember(r1, l1Object);
if (changedMembersR1 != null) {
for (int j = 0; j < changedMembersR1.size() && !result; j++) {
/* Members links und rechts pruefen */
result = ExcludePairHelper.isAttrMemberChangedFromLeftToRight(
r1, r2,
changedMembersR1.elementAt(j),
l1Object,
l2Object,
this.nacInsideOverlapGraph,
overlapObject);
}
changedMembersR1 = null;
}
if (result) {
overlapObject.setCritical(true);
}
}
else if (helpPair != null && helpPair.second != null) {
// when l2Objects are not found inside of LHS2
// try to find it inside of PAC part of the extended LHS2
// helpPair: Pair(extendedByPACsL2iso, rStar)
result = ExcludePairHelper.isAttrMemberChangedFromPACRule2ToRight(
r1,
r2,
l1Object,
overlapObject,
helpPair);
if (result) {
overlapObject.setCritical(true);
}
}
} // for (int i = 0; i < changedAttributesR1.size()
if (!result && !r2.getNACsList().isEmpty()) {
result = ExcludePairHelper.isAttrMemberChangedFromNACRule2ToRight(
r1,
r2,
overlapping,
this.nacInsideOverlapGraph,
changedAttributesR1,
forbiddenTypesR2,
this.attrMember2Expr);
}
changedAttributesR1 = null;
forbiddenTypesR2 = null;
return result;
}
/*
private void unsetAllTransientAttrValuesOfOverlapGrah(
final Pair<OrdinaryMorphism, OrdinaryMorphism> overlapPair) {
// remove all implicit transient declared variables in overlapgraph
Graph g = overlapPair.second.getImage();
Iterator<?> e1 = g.getNodesSet().iterator();
while (e1.hasNext()) {
GraphObject obj = (GraphObject) e1.next();
if (obj.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) obj.getAttribute();
for (int i = 0; i < value.getNumberOfEntries(); i++) {
ValueMember valuem = value.getValueMemberAt(i);
if ((valuem.getExpr() != null) && valuem.getExpr().isVariable()
&& valuem.isTransient()) {
valuem.setExpr(null);
}
}
}
e1 = g.getArcsSet().iterator();
while (e1.hasNext()) {
GraphObject obj = (GraphObject) e1.next();
if (obj.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) obj.getAttribute();
for (int i = 0; i < value.getNumberOfEntries(); i++) {
ValueMember valuem = value.getValueMemberAt(i);
if ((valuem.getExpr() != null) && valuem.getExpr().isVariable()
&& valuem.isTransient()) {
valuem.setExpr(null);
}
}
}
}
*/
protected void unsetAllTransientAttrValuesOfOverlapGrah(final Graph g) {
// remove all implicit transient declared variables in overlapgraph
Iterator<?> e1 = g.getNodesSet().iterator();
while (e1.hasNext()) {
GraphObject obj = (GraphObject) e1.next();
if (obj.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) obj.getAttribute();
for (int i = 0; i < value.getNumberOfEntries(); i++) {
ValueMember valuem = value.getValueMemberAt(i);
if ((valuem.getExpr() != null)
&& valuem.getExpr().isVariable() && valuem.isTransient()) {
valuem.setExpr(null);
}
}
}
e1 = g.getArcsSet().iterator();
while (e1.hasNext()) {
GraphObject obj = (GraphObject) e1.next();
if (obj.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) obj.getAttribute();
for (int i = 0; i < value.getNumberOfEntries(); i++) {
ValueMember valuem = value.getValueMemberAt(i);
if ((valuem.getExpr() != null)
&& valuem.getExpr().isVariable() && valuem.isTransient()) {
valuem.setExpr(null);
}
}
}
}
protected void unsetAllTransientAttrValuesOfRule(final Rule r) {
if (r.getLeft().isAttributed()) {
Iterator<?> e1 = r.getLeft().getNodesSet().iterator();
while (e1.hasNext()) {
GraphObject obj = (GraphObject) e1.next();
if (obj.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) obj.getAttribute();
for (int i = 0; i < value.getNumberOfEntries(); i++) {
ValueMember valuem = value.getValueMemberAt(i);
if ((valuem.getExpr() != null)
&& valuem.getExpr().isVariable()
&& valuem.isTransient()) {
String tmpname = valuem.getExprAsText();
valuem.setExpr(null);
if (((VarTuple) r.getAttrContext().getVariables())
.getMemberAt(tmpname) != null)
((VarTuple) r.getAttrContext().getVariables())
.getTupleType().deleteMemberAt(tmpname);
}
}
}
e1 = r.getLeft().getArcsSet().iterator();
while (e1.hasNext()) {
GraphObject obj = (GraphObject) e1.next();
if (obj.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) obj.getAttribute();
for (int i = 0; i < value.getNumberOfEntries(); i++) {
ValueMember valuem = value.getValueMemberAt(i);
if ((valuem.getExpr() != null)
&& valuem.getExpr().isVariable()
&& valuem.isTransient()) {
String tmpname = valuem.getExprAsText();
valuem.setExpr(null);
if (((VarTuple) r.getAttrContext().getVariables())
.getMemberAt(tmpname) != null)
((VarTuple) r.getAttrContext().getVariables())
.getTupleType().deleteMemberAt(tmpname);
}
}
}
}
if (r.getRight().isAttributed()) {
Iterator<?> e1 = r.getRight().getNodesSet().iterator();
while (e1.hasNext()) {
GraphObject obj = (GraphObject) e1.next();
if (obj.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) obj.getAttribute();
for (int i = 0; i < value.getNumberOfEntries(); i++) {
ValueMember valuem = value.getValueMemberAt(i);
if ((valuem.getExpr() != null)
&& valuem.getExpr().isVariable()
&& valuem.isTransient()) {
String tmpname = valuem.getExprAsText();
valuem.setExpr(null);
if (((VarTuple) r.getAttrContext().getVariables())
.getMemberAt(tmpname) != null)
((VarTuple) r.getAttrContext().getVariables())
.getTupleType().deleteMemberAt(tmpname);
}
}
}
e1 = r.getRight().getArcsSet().iterator();
while (e1.hasNext()) {
GraphObject obj = (GraphObject) e1.next();
if (obj.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) obj.getAttribute();
for (int i = 0; i < value.getNumberOfEntries(); i++) {
ValueMember valuem = value.getValueMemberAt(i);
if ((valuem.getExpr() != null)
&& valuem.getExpr().isVariable()
&& valuem.isTransient()) {
String tmpname = valuem.getExprAsText();
valuem.setExpr(null);
if (((VarTuple) r.getAttrContext().getVariables())
.getMemberAt(tmpname) != null)
((VarTuple) r.getAttrContext().getVariables())
.getTupleType().deleteMemberAt(tmpname);
}
}
}
}
final List<OrdinaryMorphism> nacs = r.getNACsList();
for (int l=0; l<nacs.size(); l++) {
final OrdinaryMorphism nac = nacs.get(l);
if (nac.getTarget().isAttributed()) {
Iterator<?> e1 = nac.getTarget().getNodesSet().iterator();
while (e1.hasNext()) {
GraphObject obj = (GraphObject) e1.next();
if (obj.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) obj.getAttribute();
for (int i = 0; i < value.getNumberOfEntries(); i++) {
ValueMember valuem = value.getValueMemberAt(i);
if ((valuem.getExpr() != null)
&& valuem.getExpr().isVariable()
&& valuem.isTransient()) {
String tmpname = valuem.getExprAsText();
valuem.setExpr(null);
if (((VarTuple) r.getAttrContext().getVariables())
.getMemberAt(tmpname) != null)
((VarTuple) r.getAttrContext().getVariables())
.getTupleType().deleteMemberAt(tmpname);
}
}
}
e1 = nac.getTarget().getArcsSet().iterator();
while (e1.hasNext()) {
GraphObject obj = (GraphObject) e1.next();
if (obj.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) obj.getAttribute();
for (int i = 0; i < value.getNumberOfEntries(); i++) {
ValueMember valuem = value.getValueMemberAt(i);
if ((valuem.getExpr() != null)
&& valuem.getExpr().isVariable()
&& valuem.isTransient()) {
String tmpname = valuem.getExprAsText();
valuem.setExpr(null);
if (((VarTuple) r.getAttrContext().getVariables())
.getMemberAt(tmpname) != null)
((VarTuple) r.getAttrContext().getVariables())
.getTupleType().deleteMemberAt(tmpname);
}
}
}
}
}
final List<OrdinaryMorphism> pacs = r.getPACsList();
for (int l=0; l<pacs.size(); l++) {
final OrdinaryMorphism pac = pacs.get(l);
if (pac.getTarget().isAttributed()) {
Iterator<?> e1 = pac.getTarget().getNodesSet().iterator();
while (e1.hasNext()) {
GraphObject obj = (GraphObject) e1.next();
if (obj.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) obj.getAttribute();
for (int i = 0; i < value.getNumberOfEntries(); i++) {
ValueMember valuem = value.getValueMemberAt(i);
if ((valuem.getExpr() != null)
&& valuem.getExpr().isVariable()
&& valuem.isTransient()) {
String tmpname = valuem.getExprAsText();
valuem.setExpr(null);
if (((VarTuple) r.getAttrContext().getVariables())
.getMemberAt(tmpname) != null)
((VarTuple) r.getAttrContext().getVariables())
.getTupleType().deleteMemberAt(tmpname);
}
}
}
e1 = pac.getTarget().getArcsSet().iterator();
while (e1.hasNext()) {
GraphObject obj = (GraphObject) e1.next();
if (obj.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) obj.getAttribute();
for (int i = 0; i < value.getNumberOfEntries(); i++) {
ValueMember valuem = value.getValueMemberAt(i);
if ((valuem.getExpr() != null)
&& valuem.getExpr().isVariable()
&& valuem.isTransient()) {
String tmpname = valuem.getExprAsText();
valuem.setExpr(null);
if (((VarTuple) r.getAttrContext().getVariables())
.getMemberAt(tmpname) != null)
((VarTuple) r.getAttrContext().getVariables())
.getTupleType().deleteMemberAt(tmpname);
}
}
}
}
}
}
/*
private void reduceIfSimilar(
final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlappings) {
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
vec = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>(overlappings.size());
vec.addAll(overlappings);
while (!vec.isEmpty()) {
Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>> p0 = vec.get(0);
for (int i=0; i<overlappings.size(); i++) {
Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>> pi = overlappings.get(i);
if (pi != p0) {
Pair<OrdinaryMorphism, OrdinaryMorphism> p = checkIfSimilar(p0.first, pi.first);
if (p != null) {
overlappings.remove(pi);
i--;
}
}
}
vec.remove(p0);
}
}
// not used now
protected boolean reduce;
private Pair<OrdinaryMorphism, OrdinaryMorphism> checkIfSimilar(
final Pair<OrdinaryMorphism, OrdinaryMorphism> p1,
final Pair<OrdinaryMorphism, OrdinaryMorphism> p2) {
Pair<OrdinaryMorphism, OrdinaryMorphism> p = null;
OrdinaryMorphism first1 = null;
OrdinaryMorphism second1 = null;
OrdinaryMorphism first2 = null;
OrdinaryMorphism second2 = null;
OrdinaryMorphism morph1 = null;
OrdinaryMorphism morph2 = null;
Graph overlap1 = p1.first.getImage();
int gSize1 = overlap1.getSize();
int mSize1 = 0;
Iterator<?> e = overlap1.getNodesSet().iterator();
while (e.hasNext() && !this.stop) {
GraphObject o = (GraphObject) e.next();
if (p1.first.getInverseImage(o).hasMoreElements()
|| p1.second.getInverseImage(o).hasMoreElements())
mSize1++;
}
e = overlap1.getArcsSet().iterator();
while (e.hasNext() && !this.stop) {
GraphObject o = (GraphObject) e.next();
if (p1.first.getInverseImage(o).hasMoreElements()
|| p1.second.getInverseImage(o).hasMoreElements())
mSize1++;
}
Graph overlap2 = p2.first.getImage();
int gSize2 = overlap2.getSize();
int mSize2 = 0;
e = overlap2.getNodesSet().iterator();
while (e.hasNext() && !this.stop) {
GraphObject o = (GraphObject) e.next();
if (p2.first.getInverseImage(o).hasMoreElements()
|| p2.second.getInverseImage(o).hasMoreElements())
mSize2++;
}
e = overlap2.getArcsSet().iterator();
while (e.hasNext() && !this.stop) {
GraphObject o = (GraphObject) e.next();
if (p2.first.getInverseImage(o).hasMoreElements()
|| p2.second.getInverseImage(o).hasMoreElements())
mSize2++;
}
if (mSize1 != mSize2)
return null;
if ((!reduce && (gSize1 == gSize2)) || reduce) {
if (gSize1 < gSize2) {
morph1 = (BaseFactory.theFactory()).createMorphism(overlap1,
overlap2);
morph2 = (BaseFactory.theFactory()).createMorphism(overlap1,
overlap2);
first1 = p1.first;
first2 = p2.first;
second1 = p1.second;
second2 = p2.second;
if (morph1.makeDiagram(first1, first2)) {
// System.out.println("1:makeDiagram: "+morph1);
if (morph2.makeDiagram(second1, second2)) {
if (morph1.isPartialIsomorphicTo(morph2)) {
p = p2;
}
}
}
} else {
morph1 = (BaseFactory.theFactory()).createMorphism(overlap2,
overlap1);
morph2 = (BaseFactory.theFactory()).createMorphism(overlap2,
overlap1);
first2 = p2.first;
first1 = p1.first;
second2 = p2.second;
second1 = p1.second;
if (morph1.makeDiagram(first2, first1)) {
if (morph2.makeDiagram(second2, second1)) {
if (morph1.isPartialIsomorphicTo(morph2)) {
p = p1;
}
}
}
}
}
if (morph1 != null)
morph1.dispose();
morph1 = null;
if (morph2 != null)
morph2.dispose();
morph2 = null;
return p;
}
private Pair<OrdinaryMorphism, OrdinaryMorphism> getValidMatchChangeAttr(
final Rule r1,
final Rule r2,
final Pair<OrdinaryMorphism, OrdinaryMorphism> overlapping) {
// System.out.println("### getValidMatch1Match2ChangeAttr(Rule,Rule, ...");
OrdinaryMorphism morph1 = overlapping.first;
((ContextView) morph1.getAttrContext()).setVariableContext(true);
Match m1 = BaseFactory.theFactory().makeMatch(r1, morph1);
if (m1 == null)
return null;
// System.out.println(m1.getSource());
// System.out.println(m1.getTarget());
m1.setCompletionStrategy(this.strategy, true);
boolean isValid = isChangeAttrMatchValid(r1, m1, null, true, overlapping);
if (!isValid) {
m1.dispose();
m1 = null;
return null;
}
OrdinaryMorphism morph2 = overlapping.second;
((ContextView) morph2.getAttrContext()).setVariableContext(true);
Match m2 = BaseFactory.theFactory().makeMatch(r2, morph2);
if (m2 == null) {
m1.dispose();
m1 = null;
return null;
}
m2.setCompletionStrategy(this.strategy, true);
isValid = isChangeAttrMatchValid(r2, m2, null, false, overlapping);
if (!isValid) {
m1.dispose();
m1 = null;
m2.dispose();
m2 = null;
return null;
}
if (this.reduceSameMatch)
if (isSameRuleAndSameMatch(r1, r2, m1, m2)) {
m1.dispose();
m1 = null;
m2.dispose();
m2 = null;
return null;
}
return new Pair<OrdinaryMorphism, OrdinaryMorphism>(m1, m2);
}
*/
private Pair<OrdinaryMorphism, OrdinaryMorphism> getValidMatchChangeAttr(
final Rule r1,
final Rule r2,
final OrdinaryMorphism isoL2Ext,
final OrdinaryMorphism overlap1,
final OrdinaryMorphism overlap2) {
OrdinaryMorphism mo1 = overlap1;
((ContextView) mo1.getAttrContext()).setVariableContext(true);
Match m1 = BaseFactory.theFactory().makeMatch(r1, mo1);
if (m1 == null)
return null;
m1.setCompletionStrategy(this.strategy, true);
boolean isValid = isChangeAttrMatchValid(r1, r2, m1, null, null, true, overlap1, overlap2);
if (!isValid) {
m1.dispose(); m1 = null;
return null;
}
// make match of rule2
OrdinaryMorphism mo2 = BaseFactory.theFactory().createMorphism(
isoL2Ext.getSource(), overlap2.getTarget());
mo2.doCompose(isoL2Ext, overlap2);
((ContextView) mo2.getAttrContext()).setVariableContext(true);
Match m2 = BaseFactory.theFactory().makeMatch(r2, mo2);
if (m2 == null) {
m1.dispose(); m1 = null;
mo2.dispose(); mo2 = null;
return null;
}
m2.setCompletionStrategy(this.strategy, true);
isValid = isChangeAttrMatchValid(r1, r2, m2, null, null, false, overlap1, overlap2);
if (!isValid) {
mo2.dispose(); mo2 = null;
m1.dispose(); m1 = null;
m2.dispose(); m2 = null;
return null;
}
// additionally: if rule1 has PACs and rule2 has NACs,
// extend the graph overlapping.first.getTarget() by PACs of rule1
// and check NACs of rule2
if (r1.hasPACs() && r2.hasNACs()) {
OrdinaryMorphism extOverlap = extendOverlapGraphByPACs(overlap1, r1);
if (extOverlap != null) {
OrdinaryMorphism mo2p = BaseFactory.theFactory().createMorphism(m2.getSource(), extOverlap.getTarget());
mo2p.doCompose(m2, extOverlap);
Match m2p = BaseFactory.theFactory().makeMatch(r2, mo2p);
if (m2p != null) {
isValid = checkNACs(r2, m2p, null, false);
m2p.dispose(); m2p = null;
mo2p.dispose(); mo2p = null;
extOverlap.dispose(); extOverlap = null;
if (!isValid) {
m1.dispose(); m1 = null;
m2.dispose(); m2 = null;
return null;
}
}
}
}
if (this.reduceSameMatch) {
if (isSameRuleAndSameMatch(r1, r2, m1, m2)) {
m1.dispose(); m1 = null;
m2.dispose(); m2 = null;
return null;
}
}
if (this.directStrctCnfl || this.directStrctCnflUpToIso) {
Pair<OrdinaryMorphism,OrdinaryMorphism> pair1 = BaseFactory.theFactory().makePO(r1, m1, true, false);
Pair<OrdinaryMorphism,OrdinaryMorphism> pair2 = BaseFactory.theFactory().makePO(r2, m2, true, false);
if (pair1 != null && pair2 != null) {
OrdinaryMorphism po1 = pair1.first;
OrdinaryMorphism po2 = pair2.first;
if (isDirectlyStrictConfluent(po1, po2)
// test
|| (this.directStrctCnflUpToIso
&& isIsomorphicTo(pair1.second.getImage(), pair2.second.getImage())) ) {
po1.dispose();
po2.dispose();
m1.dispose(); m1 = null;
m2.dispose(); m2 = null;
return null;
}
}
}
return new Pair<OrdinaryMorphism, OrdinaryMorphism>(m1, m2);
}
private boolean isIsomorphicTo(Graph g1, Graph g2) {
if (g1 == g2) {
return true;
}
Vector<OrdinaryMorphism> list = g1.getIsomorphicWith(g2, true);
if (list != null && list.size() > 0) {
for (int i=0; i<list.size(); i++) {
OrdinaryMorphism h = list.get(i);
if (h != null && h.checkConstants()) {
return true;
}
}
}
return false;
}
private Pair<OrdinaryMorphism, OrdinaryMorphism> getValidMatchDeleteUse(
final Rule r1,
final Rule r2,
final OrdinaryMorphism isoL2ext,
final OrdinaryMorphism overlap1,
final OrdinaryMorphism overlap2) {
OrdinaryMorphism mo1 = overlap1;
((ContextView) mo1.getAttrContext()).setVariableContext(true);
Match m1 = BaseFactory.theFactory().makeMatch(r1, mo1);
if (m1 == null)
return null;
if (this instanceof DependencyPair)
m1.setCompletionStrategy(new Completion_InjCSP(), true);
else
m1.setCompletionStrategy(this.strategy, true);
boolean isValid = isDeleteUseMatchValid(r1, m1, null, true, overlap1, overlap2);
if (!isValid) {
m1.dispose();
m1 = null;
return null;
}
// prepare morphisms for match of rule2
OrdinaryMorphism mo2t = BaseFactory.theFactory().createMorphism(
isoL2ext.getSource(), overlap2.getTarget());
mo2t.doCompose(isoL2ext, overlap2);
if (this.cpdKind == CriticalPairData.PRODUCE_EDGE_DELTE_NODE_CONFLICT) {
// for this check the rules are switched: the first rule is now the second and vice versa
// additionally: if rule2 has PACs and rule1 has NACs,
// extend the graph overlapping.second.getTarget() by PACs
// and check NACs of rule1
if (r1.hasNACs() && r2.hasPACs()) {
OrdinaryMorphism extOverlap = extendOverlapGraphByPACs(mo2t, r2);
if (extOverlap != null) {
OrdinaryMorphism mo1p = BaseFactory.theFactory().createMorphism(m1.getSource(), extOverlap.getTarget());
mo1p.doCompose(m1, extOverlap);
Match m1p = BaseFactory.theFactory().makeMatch(r1, mo1p);
if (m1p != null) {
isValid = checkNACs(r1, m1p, null, true);
if (!isValid) {
m1p.dispose(); m1p = null;
mo1p.dispose(); mo1p = null;
extOverlap.dispose(); extOverlap = null;
mo2t.dispose(); mo2t = null;
m1.dispose(); m1 = null;
return null;
}
m1p.dispose(); m1p = null;
mo1p.dispose(); mo1p = null;
extOverlap.dispose(); extOverlap = null;
}
}
}
}
// make match of rule2
((ContextView) mo2t.getAttrContext()).setVariableContext(true);
Match m2 = BaseFactory.theFactory().makeMatch(r2, mo2t);
if (m2 == null) {
m1.dispose(); m1 = null;
mo2t.dispose(); mo2t = null;
return null;
}
m2.setCompletionStrategy(this.strategy, true);
isValid = isDeleteUseMatchValid(r2, m2, null, false, overlap1, overlap2);
if (!isValid) {
m1.dispose(); m1 = null;
mo2t.dispose();
m2.dispose(); m2 = null;
return null;
}
// additionally: if rule1 has PACs and rule2 has NACs,
// extend the graph overlapping.first.getTarget() by PACs
// and check NACs of rule2
if (this.cpdKind != CriticalPairData.PRODUCE_EDGE_DELTE_NODE_CONFLICT) {
if (r1.hasPACs() && r2.hasNACs()) {
OrdinaryMorphism extOverlap = extendOverlapGraphByPACs(overlap1, r1);
if (extOverlap != null) {
OrdinaryMorphism mo2p = BaseFactory.theFactory().createMorphism(m2.getSource(), extOverlap.getTarget());
mo2p.doCompose(m2, extOverlap);
Match m2p = BaseFactory.theFactory().makeMatch(r2, mo2p);
if (m2p != null) {
isValid = checkNACs(r2, m2p, null, false);
m2p.dispose(); m2p = null;
mo2p.dispose(); mo2p = null;
extOverlap.dispose(); extOverlap = null;
if (!isValid) {
m1.dispose(); m1 = null;
mo2t.dispose(); mo2t = null;
m2.dispose(); m2 = null;
return null;
}
}
}
}
}
if (this.reduceSameMatch
&& isSameRuleAndSameMatch(r1, r2, m1, m2)) {
m1.dispose(); m1 = null;
mo2t.dispose();
m2.dispose(); m2 = null;
return null;
}
if (this.directStrctCnfl || this.directStrctCnflUpToIso) {
Pair<OrdinaryMorphism,OrdinaryMorphism> pair1 = BaseFactory.theFactory().makePO(r1, m1, true, false);
Pair<OrdinaryMorphism,OrdinaryMorphism> pair2 = BaseFactory.theFactory().makePO(r2, m2, true, false);
if (pair1 != null && pair2 != null) {
OrdinaryMorphism po1 = pair1.first;
OrdinaryMorphism po2 = pair2.first;
if (isDirectlyStrictConfluent(po1, po2)
// test
|| (this.directStrctCnflUpToIso
&& isIsomorphicTo(pair1.second.getImage(), pair2.second.getImage())) ) {
po1.dispose();
po2.dispose();
m1.dispose(); m1 = null;
m2.dispose(); m2 = null;
return null;
}
}
}
return new Pair<OrdinaryMorphism, OrdinaryMorphism>(m1, m2);
}
private boolean isSameRuleAndSameMatch(
final Rule r1,
final Rule r2,
final Match m1,
final Match m2) {
if (r1 != r2)
return false;
if (m1.getTarget() != m2.getTarget()){
return false;
}
int nn = 0;
Enumeration<GraphObject> dom1 = m1.getDomain();
while (dom1.hasMoreElements()) {
GraphObject img1 = m1.getImage(dom1.nextElement());
if (m2.getInverseImage(img1).hasMoreElements())
nn++;
}
if (nn == m2.getSize())
return true;
return false;
}
private Pair<OrdinaryMorphism, OrdinaryMorphism> getValidMatchProduceForbid(
final Rule r1,
final Rule r2,
final OrdinaryMorphism nac2,
final OrdinaryMorphism overlap1p,
final OrdinaryMorphism overlap2p,
final OrdinaryMorphism isoL2ext) {
// make inverse rule1
Pair<Pair<Rule,Boolean>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
inverseR1pair = BaseFactory.theFactory().reverseRule(r1);
if (inverseR1pair == null)
return null;
OrdinaryMorphism isoE = overlap1p.getTarget().isomorphicCopy();
if (isoE == null)
return null;
Rule inverseR1 = inverseR1pair.first.first;
OrdinaryMorphism isoLHS1 = inverseR1pair.second.first;
OrdinaryMorphism isoRHS1 = inverseR1pair.second.second;
OrdinaryMorphism mo1p = overlap1p.completeDiagram(isoRHS1);
// make match of inverse rule1
OrdinaryMorphism mo1pt = mo1p.compose(isoE);
((ContextView) mo1pt.getAttrContext()).setVariableContext(true);
Match m1pt = BaseFactory.theFactory().makeMatch(inverseR1, mo1pt, "");
boolean isValid = false;
if (m1pt != null) {
m1pt.setCompletionStrategy(new Completion_InjCSP(), true);
isValid = isInverseMatchValid(true, m1pt);
if (!isValid) {
m1pt.dispose(); m1pt = null;
return null;
}
} else {
return null;
}
// apply inverse r1 at extended overlapGraph
OrdinaryMorphism ms1 = null;
try {
ms1 = (OrdinaryMorphism) TestStep.execute(m1pt, true, this.equalVariableNameOfAttrMapping);
} catch (TypeException e) {}
if (ms1 == null) {
m1pt.dispose(); m1pt = null;
mo1pt.dispose(); mo1pt = null;
return null;
}
// make match m1 : L1 -> overlapGraph
OrdinaryMorphism mo1t = isoLHS1.compose(ms1);
// ms1.dispose(); ms1 = null;
Match m1t = BaseFactory.theFactory().makeMatch(r1, mo1t, "");
if (m1t == null) {
m1pt.dispose(); m1pt = null;
mo1pt.dispose(); mo1pt = null;
mo1t.dispose(); mo1t = null;
return null;
}
Pair<OrdinaryMorphism, OrdinaryMorphism>
overlapping = new Pair<OrdinaryMorphism, OrdinaryMorphism> (overlap1p, overlap2p);
isValid = isProduceForbidMatchValid(r1, m1t, null, true, overlapping);
if (!isValid) {
m1pt.dispose(); m1pt = null;
mo1pt.dispose(); mo1pt = null;
mo1t.dispose(); mo1t = null;
m1t.dispose(); m1t = null;
return null;
}
final Hashtable<GraphObject,GraphObject> adjusted = new Hashtable<GraphObject,GraphObject>();
final OrdinaryMorphism mo1 = BaseFactory.theFactory().createMorphism(
m1t.getSource(), isoE.getSource());
final Enumeration<GraphObject> e = m1t.getDomain();
while (e.hasMoreElements()) {
final GraphObject o = e.nextElement();
final GraphObject i = m1t.getImage(o);
if (isoE.getInverseImage(i).hasMoreElements()) {
final GraphObject img = isoE.getInverseImage(i).nextElement();
if (adjustAttrOfObjFromObjIfConstValue(img, i)) {
adjusted.put(img, i);
}
try {
mo1.addMapping(o, img);
} catch (BadMappingException ex) {}
}
}
Match m1 = BaseFactory.theFactory().makeMatch(r1, mo1, "");
if (m1 == null) {
return null;
}
OrdinaryMorphism po1 = isoE.invert();
final Enumeration<GraphObject> keys = adjusted.keys();
while (keys.hasMoreElements()) {
final GraphObject o1 = keys.nextElement();
final GraphObject o2 = adjusted.get(o1);
adjustAttrOfObjFromObjIfConstValue(o2, o1);
}
// make match of rule2
OrdinaryMorphism mo2pt = overlap2p.compose(isoE);
OrdinaryMorphism mo2t = isoL2ext.compose(mo2pt);
Match m2t = BaseFactory.theFactory().makeMatch(r2, mo2t, "");
if (m2t != null) {
// to check m2 is needed because of other NACs
m2t.setCompletionStrategy(this.strategy, true);
isValid = isProduceForbidMatchValid(r2, m2t, nac2, false, overlapping);
}
else {
m1t.dispose();
mo1.dispose();
m1.dispose(); m1 = null;
mo2t.dispose(); mo2t = null;
mo2pt.dispose(); mo2pt = null;
return null;
}
if (!isValid) {
m1t.dispose();
mo1.dispose();
m1.dispose(); m1 = null;
m2t.dispose(); m2t = null;
mo2t.dispose(); mo2t = null;
mo2pt.dispose(); mo2pt = null;
return null;
}
OrdinaryMorphism mo2 = BaseFactory.theFactory()
.createMorphism(m2t.getSource(), isoE.getSource());
Enumeration<GraphObject> e2 = m2t.getDomain();
while (e2.hasMoreElements()) {
GraphObject o = e2.nextElement();
GraphObject i = m2t.getImage(o);
if (isoE.getInverseImage(i).hasMoreElements()) {
try {
mo2.addMapping(o, isoE.getInverseImage(i)
.nextElement());
} catch (BadMappingException ex) {}
}
}
Match m2 = BaseFactory.theFactory().makeMatch(r2, mo2, "");
if (m2 == null) {
m1t.dispose();
mo1.dispose();
m1.dispose(); m1 = null;
m2t.dispose();
mo2.dispose(); mo2 = null;
return null;
}
// additionally: if rule1 has PACs and rule2 has NACs,
// extend the graph overlapping.first.getTarget() by PACs
// and check NACs of rule2
if (r1.hasPACs() && r2.hasNACs()) {
OrdinaryMorphism extOverlap = extendOverlapGraphByPACs(overlapping.first, r1);
if (extOverlap != null) {
OrdinaryMorphism mo2p = BaseFactory.theFactory()
.createMorphism(m2.getSource(), extOverlap.getTarget());
mo2p.doCompose(m2, extOverlap);
Match m2p = BaseFactory.theFactory().makeMatch(r2, mo2p);
if (m2p != null) {
isValid = checkNACs(r2, m2p, null, false);
if (!isValid) {
m2p.dispose(); m2p = null;
mo2p.dispose(); mo2p = null;
extOverlap.dispose(); extOverlap = null;
m1.dispose(); m1 = null;
mo2t.dispose(); mo2t = null;
m2.dispose(); m2 = null;
return null;
}
m2p.dispose(); m2p = null;
mo2p.dispose(); mo2p = null;
extOverlap.dispose(); extOverlap = null;
}
}
}
if (this.reduceSameMatch
&& isSameRuleAndSameMatch(r1, r2, m1, m2)) {
m1t.dispose();
mo1.dispose();
m1.dispose(); m1 = null;
m2t.dispose();
mo2.dispose();
m2.dispose(); m2 = null;
return null;
}
if (this.directStrctCnfl
&& !r1.isDeleting() && !r2.isDeleting()) {
Pair<OrdinaryMorphism,OrdinaryMorphism> pair2 = BaseFactory.theFactory().makePO(m2t.getRule(), m2t, true, false);
if (pair2 != null) {
OrdinaryMorphism po2 = pair2.first;
if (isDirectlyStrictConfluent(po1, po2)) {
po2.dispose();
ms1.dispose();
m1t.dispose();
mo1.dispose();
m1.dispose(); m1 = null;
m2t.dispose();
mo2.dispose();
m2.dispose(); m2 = null;
return null;
}
}
}
return new Pair<OrdinaryMorphism, OrdinaryMorphism>(m1, m2);
}
private boolean isDirectlyStrictConfluent(OrdinaryMorphism m1, OrdinaryMorphism m2) {
if (m1.getOriginal() == m2.getOriginal()) {
OrdinaryMorphism iso = new OrdinaryMorphism(m1.getImage(), m2.getImage(),
m1.getAttrManager().newContext(AttrMapping.MATCH_MAP));
((ContextView) iso.getAttrContext()).setVariableContext(true);
Iterator<Node> nodes = m1.getOriginal().getNodesCollection().iterator();
while (nodes.hasNext()) {
GraphObject go = nodes.next();
GraphObject img1 = m1.getImage(go);
GraphObject img2 = m2.getImage(go);
if (img1 == null && img2 == null)
continue;
try {
iso.addMapping(img1, img2);
} catch(BadMappingException ex) {
return false;
}
}
Iterator<Arc> arcs = m1.getOriginal().getArcsCollection().iterator();
while (arcs.hasNext()) {
GraphObject go = arcs.next();
GraphObject img1 = m1.getImage(go);
GraphObject img2 = m2.getImage(go);
if (img1 == null && img2 == null)
continue;
try {
iso.addMapping(img1, img2);
} catch(BadMappingException ex) {
return false;
}
}
if (!iso.checkConstants()) {
iso.dispose();
return false;
}
// if (iso.makeIsomorphic() && m1.isCommutative(m2, iso)) {
if (isIsoAndCommutative(iso, m1, m2)) {
return true;
}
}
return false;
}
public boolean isIsoAndCommutative(
final OrdinaryMorphism iso,
final OrdinaryMorphism m1,
final OrdinaryMorphism m2) {
// vergleiche Knotenanzahl
if (iso.getOriginal().getNodesCount() != iso.getImage().getNodesCount()) {
return false;
}
// vergleiche Kantenanzahl
if (iso.getOriginal().getArcsCount() != iso.getOriginal().getArcsCount()) {
return false;
}
if (iso.isTotal() && m1.isCommutative(m2, iso)) {
return true;
}
boolean result = false;
iso.setCompletionStrategy(new Completion_InjCSP());
while (iso.nextCompletion()) {
result = true;
// additionally, check type of source - target nodes in case of
// Typegraph with Node Type Inheritance
if (iso.getOriginal().getTypeSet().getTypeGraph() != null
&& iso.getOriginal().getTypeSet().hasInheritance()) {
Iterator<Node> origs = iso.getOriginal().getNodesCollection().iterator();
while (origs.hasNext() && result) {
final Node orig = origs.next();
if (!orig.getType().compareTo(iso.getImage(orig).getType())) {
result = false;
}
}
}
if (result && m1.isCommutative(m2, iso)) {
return true;
}
}
return true;
}
private boolean adjustAttrOfObjFromObjIfConstValue(
final GraphObject src,
final GraphObject tar) {
boolean result = false;
if (src.getAttribute() != null) {
final ValueTuple srcValue = (ValueTuple) src.getAttribute();
final ValueTuple tarValue = (ValueTuple) tar.getAttribute();
for (int i = 0; i < srcValue.getNumberOfEntries(); i++) {
final ValueMember srcMem = srcValue.getValueMemberAt(i);
final ValueMember tarMem = tarValue.getValueMemberAt(i);
if (srcMem.isSet() && tarMem.isSet()
&& srcMem.getExpr().isConstant() && tarMem.getExpr().isConstant()
&& !srcMem.getExprAsText().equals(tarMem.getExprAsText())) {
// TODO: check this attr value setting
HandlerExpr srcexpr = srcMem.getExpr().getCopy();
HandlerExpr tarexpr = tarMem.getExpr().getCopy();
srcMem.setExprAsObject(tarexpr);
tarMem.setExprAsObject(srcexpr);
result = true;
}
}
}
return result;
}
private Pair<OrdinaryMorphism, OrdinaryMorphism> getValidMatchChangeAttr(
final Rule r1,
final Rule r2,
final OrdinaryMorphism nac,
final OrdinaryMorphism isoL2ext,
final OrdinaryMorphism isoNAC2ext,
final OrdinaryMorphism overlap1,
final OrdinaryMorphism overlap2) {
// make match of rule1
Match m1 = BaseFactory.theFactory().makeMatch(r1, overlap1);
if (m1 != null) {
m1.setCompletionStrategy(this.strategy, true);
boolean isValid = isChangeAttrMatchValid(r1, r2, m1, null, null, true, overlap1, overlap2);
if (!isValid) {
m1.dispose(); m1 = null;
return null;
}
}
else return null;
// make match of rule2
OrdinaryMorphism mo2 = isoL2ext.compose(overlap2);
Match m2 = BaseFactory.theFactory().makeMatch(r2, mo2);
// to check m2 is needed because of the NACs
if (m2 != null) {
m2.setCompletionStrategy(this.strategy, true);
boolean isValid = isChangeAttrMatchValid(r1, r2, m2, nac, isoNAC2ext, false, overlap1, overlap2);
if (!isValid) {
m1.dispose(); m1 = null;
m2.dispose(); m2 = null;
return null;
}
}
else {
m1.dispose(); m1 = null;
mo2.dispose(); mo2 = null;
return null;
}
// additional test: make step of rule1 because of the critical NAC of rule2
if (nac.getTextualComment().equals(String.valueOf(CriticalPairData.CHANGE_FORBID_ATTR_CONFLICT))) {
OrdinaryMorphism t1 = overlap1.getTarget().isomorphicCopy();
OrdinaryMorphism tom1 = overlap1.compose(t1);
Match tm1 = BaseFactory.theFactory().makeMatch(r1, tom1);
OrdinaryMorphism ms1 = null;
try {
ms1 = (OrdinaryMorphism) TestStep.execute(tm1, true);
} catch (TypeException e) {}
if (ms1 == null) {
tm1.dispose(); tm1 = null;
tom1.dispose(); tom1 = null;
t1.dispose(); t1 = null;
return null;
}
// make test match of rule2 because of its NACs
OrdinaryMorphism tom2 = overlap2.compose(t1);
OrdinaryMorphism ttom2 = isoL2ext.compose(tom2);
Match tm2 = BaseFactory.theFactory().makeMatch(r2, ttom2);
if (tm2 != null) {
// if the NAC is not more satisfied (nacStar != null) after step of rule1, then overlapping - critical
// boolean isValid = tm2.areNACsSatisfied(true);
OrdinaryMorphism nacStar = (OrdinaryMorphism)tm2.checkNAC(nac, false);
boolean isValid = (nacStar == null);
if (isValid) {
m1.dispose(); m1 = null;
m2.dispose(); m2 = null;
tm2.dispose(); tm2 = null;
ttom2.dispose(); ttom2 = null;
tom2.dispose(); tom2 = null;
return null;
}
}
else {
m1.dispose(); m1 = null;
m2.dispose(); m2 = null;
ttom2.dispose(); ttom2 = null;
tom2.dispose(); tom2 = null;
return null;
}
}
//
// additionally: if rule1 has PACs and rule2 has NACs,
// extend the graph overlapping.first.getTarget() by PACs of rule1
// and check NACs of rule2
if (r1.hasPACs() && r2.hasNACs()) {
OrdinaryMorphism extOverlap = extendOverlapGraphByPACs(overlap1, r1);
if (extOverlap != null) {
OrdinaryMorphism mo2p = BaseFactory.theFactory().createMorphism(m2.getSource(), extOverlap.getTarget());
mo2p.doCompose(m2, extOverlap);
Match m2p = BaseFactory.theFactory().makeMatch(r2, mo2p);
if (m2p != null) {
boolean isValid = checkNACs(r2, m2p, null, false);
m2p.dispose(); m2p = null;
mo2p.dispose(); mo2p = null;
extOverlap.dispose(); extOverlap = null;
if (!isValid) {
m1.dispose(); m1 = null;
m2.dispose(); m2 = null;
return null;
}
}
}
}
if (this.reduceSameMatch) {
if (isSameRuleAndSameMatch(r1, r2, m1, m2)) {
m1.dispose(); m1 = null;
m2.dispose(); m2 = null;
return null;
}
}
if (this.directStrctCnfl || this.directStrctCnflUpToIso) {
Pair<OrdinaryMorphism,OrdinaryMorphism> pair1 = BaseFactory.theFactory().makePO(r1, m1, true, false);
Pair<OrdinaryMorphism,OrdinaryMorphism> pair2 = BaseFactory.theFactory().makePO(r2, m2, true, false);
if (pair1 != null && pair2 != null) {
OrdinaryMorphism po1 = pair1.first;
OrdinaryMorphism po2 = pair2.first;
if (isDirectlyStrictConfluent(po1, po2)
// test
|| (this.directStrctCnflUpToIso
&& isIsomorphicTo(pair1.second.getImage(), pair2.second.getImage())) ) {
po1.dispose();
po2.dispose();
m1.dispose(); m1 = null;
m2.dispose(); m2 = null;
return null;
}
}
}
return new Pair<OrdinaryMorphism, OrdinaryMorphism>(m1, m2);
}
private List<GraphObject> getChangedObjs(Rule r1) {
// global container of rule r1
if (!this.preservedChanged.isEmpty()) {
// changed attributes of r1
List<GraphObject> changedAttributesR1 = new Vector<GraphObject>(5);
for (int i = 0; i < this.preservedChanged.size(); i++) {
if (ExcludePairHelper.doesRuleChangeAttr(
r1, this.preservedChanged.elementAt(i))) {
changedAttributesR1.add(this.preservedChanged.elementAt(i));
}
}
return changedAttributesR1;
}
return null;
}
private GraphObject getChangedObjOfCriticalObj(
final GraphObject critObj,
final Rule r1,
List<GraphObject> changedObjs) {
for (int i = 0; i < changedObjs.size(); i++) {
GraphObject obj = changedObjs.get(i);
if (critObj == obj)
return r1.getImage(obj);
}
return null;
}
private boolean checkConstantAttrOfNAC(
final Rule r1,
// final Rule r2,
// final OrdinaryMorphism nac2,
final OrdinaryMorphism nacStar2,
// final OrdinaryMorphism m2,
final OrdinaryMorphism overlap1
// final OrdinaryMorphism overlap2
) {
List<GraphObject> changedObjs = this.getChangedObjs(r1);
if (changedObjs == null || changedObjs.isEmpty())
return true;
Enumeration<GraphObject> objs = nacStar2.getDomain();
while (objs.hasMoreElements()) {
GraphObject obj_n = objs.nextElement();
GraphObject obj = nacStar2.getImage(obj_n);
if (obj != null && obj.isCritical() && obj.getAttribute() != null) {
if (overlap1.getInverseImage(obj).hasMoreElements()) {
GraphObject obj_r1 = overlap1.getInverseImage(obj).nextElement();
GraphObject img_r1 = this.getChangedObjOfCriticalObj(obj_r1, r1, changedObjs);
if (img_r1 != null) {
for (int i=0; i<obj.getAttribute().getNumberOfEntries(); i++) {
ValueMember obj_mem = (ValueMember) obj.getAttribute().getMemberAt(i);
ValueMember img_r1_mem = (ValueMember) obj.getAttribute().getMemberAt(obj_mem.getName());
if (obj_mem.isSet() && obj_mem.getExpr().isConstant()) {
if (img_r1_mem != null && img_r1_mem.isSet()
&& img_r1_mem.getExpr().isConstant()
&& !obj_mem.getExprAsText().equals(img_r1_mem.getExprAsText())) {
return false;
}
}
}
}
}
}
}
return true;
}
private boolean tryValidateAttrCond(final Match m) {
boolean result = true;
if (m.getAttrContext().getConditions().getNumberOfEntries() > 0) {
final List<VarMember> list = new Vector<VarMember>(1);
// ((VarTuple) m.getAttrContext().getVariables()).showVariables();
// ((CondTuple) m.getAttrContext().getConditions()).showConditions();
// check attr condition which is marking by CondMember.LHS
result = checkAttrCondOfLHS(m);
// additionally, check attr condition which is NOT marking by CondMember.LHS
result = result && this.checkAttrCondOfMorph(m);
for (int i=0; i<list.size(); i++) {
list.get(i).undoUnification();
list.get(i).setExpr(null);
}
}
return result;
}
/*
* Returns 1 (TRUE) if the nac has not any attr. conditions and variables;
* returns 1 (TRUE) if for all attr. conditions of the nac:
* - all variables are set and attr. conditions are satisfied;
* returns -1 (FALSE) if for all attr. conditions of the nac:
* - all variables are set and at least one attr. conditions is not satisfied;
* otherwise - 0 (UNDEFINED).
*/
private int tryValidateNACAttrCond(
final OrdinaryMorphism nac,
final OrdinaryMorphism nacStar,
final OrdinaryMorphism m) {
if (m.getAttrContext().getVariables().getNumberOfEntries() == 0)
return 1;
int allConds = m.getAttrContext().getConditions().getNumberOfEntries();
if (allConds > 0) {
final List<VarMember> list = new Vector<VarMember>(1);
Enumeration<GraphObject> objs = nacStar.getDomain();
while (objs.hasMoreElements()) {
GraphObject obj_om = objs.nextElement();
if (obj_om.getAttribute() == null)
continue;
GraphObject obj = nacStar.getImage(obj_om);
if (obj != null && obj.getAttribute() != null) {
for (int i=0; i<obj_om.getAttribute().getNumberOfEntries(); i++) {
ValueMember obj_om_mem = (ValueMember) obj_om.getAttribute().getMemberAt(i);
ValueMember obj_mem = (ValueMember) obj.getAttribute().getMemberAt(obj_om_mem.getName());
if (obj_om_mem.isSet() && obj_om_mem.getExpr().isVariable()) {
if (obj_mem != null && obj_mem.isSet() && obj_mem.getExpr().isConstant()) {
VarMember var = m.getAttrContext().getVariables().getVarMemberAt(obj_om_mem.getExprAsText());
if (var != null) {
var.setExprAsText(obj_mem.getExprAsText());
list.add(var);
}
}
}
}
}
}
// ((VarTuple) m.getAttrContext().getVariables()).showVariables();
// ((CondTuple) m.getAttrContext().getConditions()).showConditions();
int evalRes = 0;
int nacConds = 0;
CondTuple conds = (CondTuple) m.getAttrContext().getConditions();
for (int i = 0; i < conds.getSize(); i++) {
CondMember cond = conds.getCondMemberAt(i);
if (cond.isEnabled() && cond.getMark() != CondMember.LHS) {
nacConds++;
evalRes = 1;
if (!cond.isDefinite() || !cond.areVariablesSet()) {
evalRes = 0;
break;
}
if (!cond.isTrue()) {
evalRes = -1;
break;
}
}
}
for (int i=0; i<list.size(); i++) {
list.get(i).undoUnification();
list.get(i).setExpr(null);
}
if (nacConds == 0) {
if (allConds == 0)
return 1;
else return 0;
}
else
return evalRes;
}
return 0;
}
private boolean tryValidateAttrCond(
final OrdinaryMorphism om,
final OrdinaryMorphism isoNAC2ext,
final OrdinaryMorphism m,
final OrdinaryMorphism overlap1,
final OrdinaryMorphism overlap2) {
boolean result = true;
if (om.getAttrContext().getConditions().getNumberOfEntries() > 0) {
final List<VarMember> list = new Vector<VarMember>(1);
if (overlap2 != null) {
Enumeration<GraphObject> objs = om.getTarget().getElements();
while (objs.hasMoreElements()) {
GraphObject obj_om = objs.nextElement();
if (obj_om.getAttribute() == null)
continue;
GraphObject obj = null;
if (om.getInverseImage(obj_om).hasMoreElements()) {
GraphObject obj_m = om.getInverseImage(obj_om).nextElement();
obj = m.getImage(obj_m);
}
else {
GraphObject obj_e = isoNAC2ext.getImage(obj_om);
if (obj_e != null) {
obj = overlap2.getImage(obj_e);
}
}
if (obj != null && obj.getAttribute() != null) {
for (int i=0; i<obj_om.getAttribute().getNumberOfEntries(); i++) {
ValueMember obj_om_mem = (ValueMember) obj_om.getAttribute().getMemberAt(i);
ValueMember obj_mem = (ValueMember) obj.getAttribute().getMemberAt(obj_om_mem.getName());
if (obj_om_mem.isSet() && obj_om_mem.getExpr().isVariable()) {
if (obj_mem != null && obj_mem.isSet() && obj_mem.getExpr().isConstant()) {
VarMember var = om.getAttrContext().getVariables().getVarMemberAt(obj_om_mem.getExprAsText());
if (var != null) {
var.setExprAsText(obj_mem.getExprAsText());
list.add(var);
}
}
}
}
}
}
}
// ((VarTuple) m.getAttrContext().getVariables()).showVariables();
// ((CondTuple) m.getAttrContext().getConditions()).showConditions();
// check attr condition which is marking by CondMember.LHS
result = result && this.checkAttrCondOfMorph(om);
for (int i=0; i<list.size(); i++) {
list.get(i).undoUnification();
list.get(i).setExpr(null);
}
}
return result;
}
private boolean tryValidateAttrCond(
final boolean firstRule,
final Match m,
final OrdinaryMorphism overlap1,
final OrdinaryMorphism overlap2) {
boolean result = true;
if (m.getAttrContext().getConditions().getNumberOfEntries() > 0) {
final List<VarMember> list = new Vector<VarMember>(1);
if (overlap1 != null && overlap2 != null) {
if (firstRule) {
final Enumeration<GraphObject> dom1 = overlap1.getDomain();
while (dom1.hasMoreElements()) {
final GraphObject obj1 = dom1.nextElement();
final GraphObject obj = overlap1.getImage(obj1);
if (overlap2.getInverseImage(obj).hasMoreElements()) {
final GraphObject obj2 = overlap2.getInverseImage(obj).nextElement();
if (obj1.getAttribute() != null && obj2.getAttribute() != null && obj.getAttribute() != null) {
for (int i=0; i<obj1.getAttribute().getNumberOfEntries(); i++) {
ValueMember obj1mem = (ValueMember) obj1.getAttribute().getMemberAt(i);
ValueMember obj2mem = (ValueMember) obj2.getAttribute().getMemberAt(obj1mem.getName());
ValueMember objmem = (ValueMember) obj.getAttribute().getMemberAt(obj1mem.getName());
if (objmem != null && objmem.isSet() && !objmem.getExpr().isConstant()) {
if (obj1mem.isSet() && obj1mem.getExpr().isVariable()
&& obj2mem != null && obj2mem.isSet() && obj2mem.getExpr().isConstant()) {
VarMember var = m.getAttrContext().getVariables().getVarMemberAt(obj1mem.getExprAsText());
if (var != null) {
var.setExprAsText(obj2mem.getExprAsText());
list.add(var);
}
}
}
}
}
}
}
} else {
final Enumeration<GraphObject> dom2 = overlap2.getDomain();
while (dom2.hasMoreElements()) {
final GraphObject obj2 = dom2.nextElement();
final GraphObject obj = overlap2.getImage(obj2);
if (overlap1.getInverseImage(obj).hasMoreElements()) {
final GraphObject obj1 = overlap1.getInverseImage(obj).nextElement();
if (obj1.getAttribute() != null && obj2.getAttribute() != null && obj.getAttribute() != null) {
for (int i=0; i<obj2.getAttribute().getNumberOfEntries(); i++) {
ValueMember obj2mem = (ValueMember) obj2.getAttribute().getMemberAt(i);
ValueMember obj1mem = (ValueMember) obj1.getAttribute().getMemberAt(obj2mem.getName());
ValueMember objmem = (ValueMember) obj.getAttribute().getMemberAt(obj2mem.getName());
if (objmem != null && objmem.isSet() && !objmem.getExpr().isConstant()) {
if (obj2mem.isSet() && obj2mem.getExpr().isVariable()
&& obj1mem != null && obj1mem.isSet() && obj1mem.getExpr().isConstant()) {
VarMember var = m.getAttrContext().getVariables().getVarMemberAt(obj2mem.getExprAsText());
if (var != null) {
var.setExprAsText(obj1mem.getExprAsText());
list.add(var);
}
}
}
}
}
}
}
}
}
// ((VarTuple) m.getAttrContext().getVariables()).showVariables();
// ((CondTuple) m.getAttrContext().getConditions()).showConditions();
// check attr condition which is marking by CondMember.LHS
result = checkAttrCondOfLHS(m);
// additionally, check attr condition which is NOT marking by CondMember.LHS
result = result && this.checkAttrCondOfMorph(m);
for (int i=0; i<list.size(); i++) {
list.get(i).undoUnification();
list.get(i).setExpr(null);
}
}
return result;
}
/*
* Checks attribute condition of type <code>CondMember</code> which is enabled,<br>
* and is only for LHS of a rule (its marking is <code>CondMember.LHS</code>),<br>
* and all used variables are definite and set<br>
* then returns the value of condition evaluation.<br>
* Otherwise, returns true.
*/
private boolean checkAttrCondOfLHS(OrdinaryMorphism m) {
CondTuple conds = (CondTuple) m.getAttrContext().getConditions();
for (int i = 0; i < conds.getSize(); i++) {
CondMember cond = conds.getCondMemberAt(i);
if (cond.isEnabled() && cond.getMark() == CondMember.LHS
&& cond.isDefinite() && cond.areVariablesSet()
&& !cond.isTrue()) {
System.out.println("Attr cond: " + cond.getExprAsText()+ " failed.");
// ((VarTuple) m.getAttrContext().getVariables()).unsetVariables();
return false;
}
}
return true;
}
/*
* Checks all attribute conditions of type <code>CondMember</code> which are enabled,<br>
* and are not for LHS of a rule (its mark is not <code>CondMember.LHS</code>),<br>
* and all variables are definite and set,<br>
* then returns the value of condition evaluation.<br>
* Otherwise returns TRUE.
*/
private boolean checkAttrCondOfApplCond(OrdinaryMorphism m) {
CondTuple conds = (CondTuple) m.getAttrContext().getConditions();
for (int i = 0; i < conds.getSize(); i++) {
CondMember cond = conds.getCondMemberAt(i);
if (cond.isEnabled() && cond.getMark() != CondMember.LHS
&& cond.isDefinite() && cond.areVariablesSet()
&& !cond.isTrue()) {
return false;
}
}
return true;
}
/*
* Checks attribute condition of type <code>CondMember</code>
* of the attribute context of the given morphism <code>m</code>.
* The given morphism <code>m</code> is a NAC or PAC morphism.
* This attribute condition is enabled,
* and not marking by <code>CondMember.LHS</code>,
* and all used variables are definite and set.
* If at least one of these points failed, returns true.
*
* In case of NAC it returns true if at least one attribute condition
* is evaluated to false, otherwise returns false.
* In case of PAC it returns false if at least one attribute condition
* is evaluated to false, otherwise returns true.
*
*/
private boolean checkAttrCondOfMorph(OrdinaryMorphism m) {
boolean defaultResult = true;
CondTuple conds = (CondTuple) m.getAttrContext().getConditions();
for (int i = 0; i < conds.getSize(); i++) {
CondMember cond = conds.getCondMemberAt(i);
if (!cond.isEnabled() || cond.getMark() == CondMember.LHS) {
continue;
}
if (cond.isDefinite() && cond.areVariablesSet()) {
if (cond.getMark() >= CondMember.NAC
|| cond.getMark() <= CondMember.NAC_PAC_LHS) {
defaultResult = false;
if (!cond.isTrue())
return true;
}
else if (cond.getMark() >= CondMember.PAC
|| cond.getMark() <= CondMember.PAC_LHS) {
if (!cond.isTrue())
return false;
}
}
}
return defaultResult;
}
private boolean isDeleteUseMatchValid(
final Rule r,
final Match m,
final OrdinaryMorphism nac,
boolean firstRule,
final OrdinaryMorphism overlap1,
final OrdinaryMorphism overlap2) {
m.getTarget().setCompleteGraph(false);
if (m.isTotal()
&& m.isValid(true)
&& tryValidateAttrCond(firstRule, m, overlap1, overlap2)
&& checkNACs(r, m, nac, firstRule)) {
return true;
}
return false;
}
private boolean checkNACs(final Rule r, final Match m) {
boolean result = true;
if (this.withNACs) {
final List<OrdinaryMorphism> nacs = r.getNACsList();
for (int l=0; l<nacs.size(); l++) {
final OrdinaryMorphism nac = nacs.get(l);
if (nac.isEnabled()) {
OrdinaryMorphism nacStar = (OrdinaryMorphism) m.checkNAC(nac, true);
if (nacStar != null) {
if (!hasVariableInContext(nac, r.getAttrContext())
&& !hasConstantToVariableInContext(nacStar)
&& !hasNewConstantToVariableInContext(nac, nacStar)
) {
nacStar.dispose(); nacStar = null;
result = false;
break;
}
nacStar.dispose(); nacStar = null;
}
}
}
}
return result;
}
/*
* Returns TRUE if all checked NACs are valid:
* - NAC graph structure is not found in m.getTarget()
* - or the NAC structure is found, but the attribut context is not valid
* ( NAC attr. conditions are TRUE, no any NAC Star mappings with (constant -> variable) ).
* Otherwise returns FALSE.
*/
private boolean checkNACs(final Rule r, final Match m,
final OrdinaryMorphism nac_NotToCheck, boolean firstRule) {
boolean result = true;
if (this.withNACs) {
final List<OrdinaryMorphism> nacs = r.getNACsList();
for (int l=0; l<nacs.size(); l++) {
final OrdinaryMorphism nac = nacs.get(l);
if (nac.isEnabled() && (nac_NotToCheck == null || nac_NotToCheck != nac)) {
OrdinaryMorphism nacStar = (OrdinaryMorphism) m.checkNAC(nac, true);
if (nacStar != null) {
if (firstRule) {
if (!hasVariableInContext(nac, r.getAttrContext())
&& !hasConstantToVariableInContext(nacStar)
&& !hasNewConstantToVariableInContext(nac, nacStar)
) {
nacStar.dispose(); nacStar = null;
result = false;
break;
}
nacStar.dispose(); nacStar = null;
} else if (!hasVariableInContext(nac, r.getAttrContext())
&& !hasConstantToVariableInContext(nacStar)
&& !hasNewConstantToVariableInContext(nac, nacStar)
) {
nacStar.dispose(); nacStar = null;
result = false;
break;
} else {
nacStar.dispose(); nacStar = null;
}
}
}
}
}
return result;
}
private boolean check2NACs(final Rule r, final Match m,
final OrdinaryMorphism nac_NotToCheck, boolean firstRule) {
boolean result = true;
if (this.withNACs) {
final List<OrdinaryMorphism> nacs = r.getNACsList();
for (int l=0; l<nacs.size(); l++) {
final OrdinaryMorphism nac = nacs.get(l);
if (nac.isEnabled() && ((nac_NotToCheck == null) || (nac_NotToCheck != nac))) {
OrdinaryMorphism nacStar = (OrdinaryMorphism) m.checkNAC(nac, true);
if (nacStar != null) {
if (firstRule) {
if (!hasVariableInContext(nac, r.getAttrContext())
&& !hasConstantToVariableInContext(nacStar)
&& !hasNewConstantToVariableInContext(nac, nacStar)
) {
nacStar.dispose(); nacStar = null;
result = false;
break;
}
nacStar.dispose(); nacStar = null;
} else if (!hasVariableInContext(nac, r.getAttrContext())
&& !hasConstantToVariableInContext(nacStar)
&& !hasNewConstantToVariableInContext(nac, nacStar)
) {
nacStar.dispose(); nacStar = null;
result = false;
break;
} else {
nacStar.dispose(); nacStar = null;
}
}
}
}
}
return result;
}
private boolean isProduceForbidMatchValid(
final Rule r,
final Match m,
OrdinaryMorphism nac,
boolean firstRule,
final Pair<OrdinaryMorphism, OrdinaryMorphism> overlapping) {
boolean result = true;
m.getTarget().setCompleteGraph(false);
if (!m.isTotal()) {
result = false;
}
else if (!m.isValid(true)) {
result = false;
}
else if (!tryValidateAttrCond(firstRule, m, overlapping.first, overlapping.second)) {
result = false;
}
else {
if (this.withNACs) {
final List<OrdinaryMorphism> nacs = r.getNACsList();
for (int l=0; l<nacs.size(); l++) {
final OrdinaryMorphism n = nacs.get(l);
if (n.isEnabled() /*&& (n != nac)*/) {
OrdinaryMorphism nacStar = (OrdinaryMorphism) m.checkNAC(n, true);
if (nacStar != null) {
if (firstRule) {
if (!hasVariableInContext(n, r.getAttrContext())
&& !hasConstantToVariableInContext(nacStar)
&& !hasNewConstantToVariableInContext(n, nacStar)) {
nacStar.dispose(); nacStar = null;
result = false;
break;
}
else {
nacStar.dispose(); nacStar = null;
}
}
else if (!hasVariableInContext(n, r.getAttrContext())
&& !hasConstantToVariableInContext(nacStar)
&& !hasNewConstantToVariableInContext(n, nacStar)) {
nacStar.dispose(); nacStar = null;
result = false;
break;
}
else {
nacStar.dispose(); nacStar = null;
}
}
}
}
}
}
return result;
}
private boolean isChangeAttrMatchValid(
final Rule r1,
final Rule r2,
final Match m,
final OrdinaryMorphism nac,
final OrdinaryMorphism isoNAC2ext,
boolean firstRule,
final OrdinaryMorphism overlap1,
final OrdinaryMorphism overlap2) {
Rule r = firstRule? r1: r2;
boolean result = true;
m.getTarget().setCompleteGraph(false);
if (!m.isTotal()) {
result = false;
}
else if (!m.isValid(true)) {
result = false;
}
else if (!tryValidateAttrCond(firstRule, m, overlap1, overlap2)) {
result = false;
}
else {
if (this.withNACs) {
final List<OrdinaryMorphism> nacs = r.getNACsList();
for (int l=0; l<nacs.size(); l++) {
final OrdinaryMorphism n = nacs.get(l);
if (n.isEnabled()) {
OrdinaryMorphism nacStar = (OrdinaryMorphism) m.checkNAC(n, true);
if (nacStar != null) {
int nacCondEval = tryValidateNACAttrCond(n, nacStar, m);
if (nacCondEval == 1) {
nacStar.dispose(); nacStar = null;
result = false;
break;
}
else if (nacCondEval == -1) {
nacStar.dispose(); nacStar = null;
result = true;
}
else if (nacCondEval == 0) { //UNDEFINED
// TODO TEST MORE
if (nac == null || n != nac) {
if (firstRule) {
if (!hasVariableInContext(n, r.getAttrContext())
&& !hasConstantToVariableInContext(nacStar)
&& !hasNewConstantToVariableInContext(n, nacStar)) {
nacStar.dispose(); nacStar = null;
result = false;
break;
}
nacStar.dispose(); nacStar = null;
}
// second rule
else if (!hasVariableInContext(n, r.getAttrContext())
&& !hasConstantToVariableInContext(nacStar)
&& !hasNewConstantToVariableInContext(n, nacStar)) {
nacStar.dispose(); nacStar = null;
result = false;
break;
} else {
nacStar.dispose(); nacStar = null;
}
}
}
}
}
}
}
}
return result;
}
private boolean isInverseMatchValid(final boolean firstRule, final Match m) {
m.getTarget().setCompleteGraph(false);
if (!m.isTotal()) {
return false;
} else if (!m.isValid(true)) {
return false;
} else if (!tryValidateAttrCond(m)) {
return false;
}
return true;
}
private boolean hasVariableInContext(final Rule r) {
final VarTuple vars = (VarTuple) r.getAttrContext().getVariables();
final CondTuple conds = (CondTuple) r.getAttrContext().getConditions();
final int s = vars.getSize();
for (int i=0; i<s; i++) {
VarMember var = vars.getVarMemberAt(i);
if (!var.isTransient()) {
// if (this.strongAttrCheck)
{
if (var.isInputParameter()) {
return true;
}
for (int j = 0; j < conds.getSize(); j++) {
CondMember cm = (CondMember) conds
.getValueMemberAt(i);
if (cm.getAllVariableNamesOfExpression()
.contains(var.getName())) {
return true;
}
}
}
}
}
return false;
}
/*
* Checks variables of the morph context (if relatedAttrContext is null) or of the relatedAttrContext.
* Returns TRUE if a variable is an input parameter or is in an attr. condition which is not valid or false.
* Otherwise returns FALSE.
*/
private boolean hasVariableInContext(final OrdinaryMorphism morph, final AttrContext relatedAttrContext) {
final VarTuple vars = (VarTuple) morph.getAttrContext().getVariables();
final CondTuple conds = (CondTuple) morph.getAttrContext().getConditions();
boolean result = hasVarInContext(morph, vars, conds, relatedAttrContext,
morph.getTarget().getNodesSet().iterator())
|| hasVarInContext(morph, vars, conds, relatedAttrContext,
morph.getTarget().getArcsSet().iterator());
return result;
}
/*
* Checks variables of the vars (if relatedAttrContext is null) or of the relatedAttrContext.
* Returns TRUE if a variable is an input parameter or is in an attr. condition which is not valid or false.
* Otherwise returns FALSE.
*/
private boolean hasVarInContext(
final OrdinaryMorphism morph,
final VarTuple vars,
final CondTuple conds,
final AttrContext relatedAttrContext,
final Iterator<?> e) {
while (e.hasNext()) {
GraphObject o = (GraphObject) e.next();
if (o.getAttribute() == null) {
continue;
}
ValueTuple vt = (ValueTuple) o.getAttribute();
for (int k = 0; k < vt.getSize(); k++) {
ValueMember vm = vt.getValueMemberAt(k);
if (vm.isSet()) {
if (vm.getExpr().isVariable()) {
VarMember varm = (relatedAttrContext == null)?
vars.getVarMemberAt(vm.getExprAsText()):
((VarTuple)relatedAttrContext.getVariables()).getVarMemberAt(vm.getExprAsText());
if (varm != null) {
if (varm.isInputParameter()) {
return true;
}
if (!morph.getInverseImage(o).hasMoreElements()) {
// object o is in morph.target only
if (conds.isEmpty())
return true;
else {
boolean condOK = true;
boolean varInCond = false;
for (int i = 0; i < conds.getSize(); i++) {
CondMember cm = (CondMember) conds.getValueMemberAt(i);
if (cm.getAllVariableNamesOfExpression().contains(varm.getName())) {
varInCond = true;
if (cm.isDefinite() && cm.areVariablesSet() && cm.isTrue()) {
// take next condition
}
else {
condOK = false;
break;
}
}
}
if (varInCond)
return !condOK;
else
return true;
}
}
else { // object o is also in morph.source
for (int i = 0; i < conds.getSize(); i++) {
CondMember cm = (CondMember) conds.getValueMemberAt(i);
if (cm.getAllVariableNamesOfExpression().contains(varm.getName())) {
return true;
}
}
}
}
}
}
}
}
return false;
}
/*
* Here motph.target == co_motph.source
* Returns TRUE if at least one object of the morph.target graph without any pre-image
* has an attr. mapping with constant -> !constant into its image of the co_morph.
* Otherwise returns FALSE.
*/
private boolean hasNewConstantToVariableInContext(
final OrdinaryMorphism morph,
final OrdinaryMorphism co_morph) {
boolean result = hasNewConstToVarInContext(morph, co_morph, morph.getTarget().getNodesSet().iterator())
|| hasNewConstToVarInContext(morph, co_morph, morph.getTarget().getArcsSet().iterator());
return result;
}
/*
* Here objs == motph.target graph objects == co_motph.source graph objects.
* Returns TRUE if at least one object of objs without any pre-image of the morph
* has an attr. mapping with constant -> variable into its image of the co_morph.
* Otherwise returns FALSE.
*/
private boolean hasNewConstToVarInContext(
final OrdinaryMorphism morph,
final OrdinaryMorphism co_morph,
final Iterator<?> objs) {
while (objs.hasNext()) {
GraphObject o = (GraphObject) objs.next();
if (o.getAttribute() == null)
continue;
GraphObject co_obj = co_morph.getImage(o);
if (!morph.getInverseImage(o).hasMoreElements()
&& co_obj != null) {
ValueTuple vt = (ValueTuple) o.getAttribute();
ValueTuple co_vt = (ValueTuple) co_obj.getAttribute();
for (int k = 0; k < vt.getSize(); k++) {
ValueMember vm = vt.getValueMemberAt(k);
ValueMember co_vm = co_vt.getValueMemberAt(vm.getName());
if ((vm.getExpr() != null && vm.getExpr().isConstant())
&& (co_vm.getExpr() != null && !co_vm.getExpr().isConstant())) {
return true;
}
}
}
}
return false;
}
private boolean hasConstantToVariableInContext(final OrdinaryMorphism morph) {
final Enumeration<GraphObject> e = morph.getDomain();
while (e.hasMoreElements()) {
final GraphObject o = e.nextElement();
final GraphObject img = morph.getImage(o);
if (o.getAttribute() == null || img.getAttribute() == null)
continue;
final ValueTuple vt = (ValueTuple) o.getAttribute();
final ValueTuple vtimg = (ValueTuple) img.getAttribute();
for (int k = 0; k < vt.getSize(); k++) {
final ValueMember vm = vt.getValueMemberAt(k);
final ValueMember vmimg = vtimg.getValueMemberAt(vm.getName());
if ((vm.getExpr() != null && vm.getExpr().isConstant())
&& (vmimg.getExpr() != null && vmimg.getExpr().isVariable())) {
return true;
}
}
}
return false;
}
protected boolean reduceCriticalPairs(
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> v) {
boolean reduced = false;
int size = v.size();
boolean found = true;
while ((size > 0) && found) {
found = false;
for (int i = 0; i<size && !found; i++) {
Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>> p1i = v.elementAt(i);
Pair<OrdinaryMorphism, OrdinaryMorphism> p1 = p1i.first;
for (int j = i + 1; j<size && !found; j++) {
Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
p2i = v.elementAt(j);
Pair<OrdinaryMorphism, OrdinaryMorphism> p2 = p2i.first;
Pair<OrdinaryMorphism, OrdinaryMorphism> p = checkIfSimilar(p1, p2);
if (p != null) {
found = true;
v.remove(p2i);
Graph g = p2i.first.first.getTarget();
p2i.first.first.dispose();
p2i.first.second.dispose();
if (p2i.second != null) {
p2i.second.first.dispose();
if (p2i.second.second != null)
p2i.second.second.dispose();
}
g.dispose();
reduced = true;
}
}
}
size = v.size();
}
return reduced;
}
private Pair<OrdinaryMorphism, OrdinaryMorphism> checkIfSimilar(
Pair<OrdinaryMorphism, OrdinaryMorphism> p1,
Pair<OrdinaryMorphism, OrdinaryMorphism> p2) {
OrdinaryMorphism first1 = null;
OrdinaryMorphism second1 = null;
OrdinaryMorphism first2 = null;
OrdinaryMorphism second2 = null;
OrdinaryMorphism morph1 = null;
OrdinaryMorphism morph2 = null;
Graph overlap1 = p1.first.getImage();
Graph overlap2 = p2.first.getImage();
int n1 = overlap1.getSize();
int n2 = overlap2.getSize();
if (n1 != n2)
return null;
morph1 = (BaseFactory.theFactory()).createMorphism(overlap1,
overlap2);
morph2 = (BaseFactory.theFactory()).createMorphism(overlap1,
overlap2);
first1 = p1.first;
first2 = p2.first;
second1 = p1.second;
second2 = p2.second;
if (morph1.makeDiagram(first1, first2)) {
if (morph2.makeDiagram(second1, second2)) {
if (morph1.isPartialIsomorphicTo(morph2)) {
return p2;
}
}
}
return null;
}
@SuppressWarnings("unused")
private void inspectCritPair(
final Rule r1,
final Rule r2,
final List<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlappings) {
CriticalPairData data = new CriticalPairData(r1, r2, overlappings);
while (data.hasCriticals()) {
if (data.next()) {
System.out.println(r1.getName());
System.out.println(r2.getName());
System.out.println(data.getRule1().getName());
System.out.println(data.getRule2().getName());
OrdinaryMorphism mo1 = data.getMorph1();
OrdinaryMorphism mo2 = data.getMorph2();
System.out.println(data.getMorph1().getName());
System.out.println(data.getMorph2().getName());
OrdinaryMorphism m1 = data.getMorph1DueToLHS();
OrdinaryMorphism m2 = data.getMorph2DueToLHS();
OrdinaryMorphism m3 = data.getMorph2DueToNAC();
}
}
}
}
/*
* $Log: ExcludePair.java,v $
* Revision 1.147 2010/12/16 17:32:14 olga
* tuning
*
* Revision 1.146 2010/12/15 16:57:56 olga
* restriction added - CPA for rules with GACs not implemented
*
* Revision 1.145 2010/11/28 22:15:26 olga
* tuning
*
* Revision 1.144 2010/11/17 14:06:38 olga
* improved
*
* Revision 1.143 2010/11/16 23:33:09 olga
* tuning
*
* Revision 1.142 2010/11/11 17:18:20 olga
* tuning
*
* Revision 1.141 2010/11/07 20:48:11 olga
* tuning
*
* Revision 1.140 2010/11/06 20:18:45 olga
* tuning
*
* Revision 1.139 2010/11/06 18:33:50 olga
* extended and improved
*
* Revision 1.138 2010/11/04 11:01:32 olga
* tuning
*
* Revision 1.137 2010/10/07 20:07:09 olga
* GraTra option GACs added
*
* Revision 1.136 2010/09/20 14:30:11 olga
* tuning
*
* Revision 1.135 2010/08/12 14:53:28 olga
* tuning
*
* Revision 1.134 2010/07/29 10:03:45 olga
* tuning
*
* Revision 1.133 2010/06/28 07:53:06 olga
* tuning
*
* Revision 1.132 2010/06/09 10:56:06 olga
* tuning
*
* Revision 1.131 2010/05/03 08:00:56 olga
* tuning
*
* Revision 1.130 2010/04/29 15:15:13 olga
* tuning and tests
*
* Revision 1.129 2010/04/28 15:16:42 olga
* tuning
*
* Revision 1.128 2010/04/27 10:38:34 olga
* computing tuning
*
* Revision 1.127 2010/04/21 23:38:00 olga
* CPA optimization
*
* Revision 1.126 2010/04/19 11:35:08 olga
* CPA: bug fixed in attr check with NAC
*
* Revision 1.125 2010/04/08 09:22:48 olga
* essential CPs : change attribute conflict - bug fixed
*
* Revision 1.124 2010/03/20 19:27:21 olga
* docu
*
* Revision 1.123 2010/03/08 15:46:42 olga
* code optimizing
*
* Revision 1.122 2010/03/04 14:11:14 olga
* code optimizing
*
* Revision 1.121 2010/02/22 15:01:57 olga
* code optimizing
*
* Revision 1.120 2009/10/12 08:26:39 olga
* ApplOfRS-improved and bug fixed
*
* Revision 1.119 2009/10/05 14:00:04 olga
* ARS check, attr. condition check - improved
*
* Revision 1.118 2009/10/05 08:52:34 olga
* RSA check - bug fixed
*
* Revision 1.117 2009/09/03 15:53:25 olga
* checking attr condition during CPA - improved
*
* Revision 1.116 2009/09/02 12:37:11 olga
* Checking attribute condition - bug fixed
*
* Revision 1.115 2009/08/03 16:54:22 olga
* CPA , essential pairs - bug fixed
*
* Revision 1.114 2009/07/30 10:44:53 olga
* Code tuning
*
* Revision 1.113 2009/07/30 07:51:30 olga
* Code tuning
*
* Revision 1.112 2009/07/30 07:35:44 olga
* Extension of CPA process
*
* Revision 1.111 2009/07/29 16:32:32 olga
* Match bug fixed
*
* Revision 1.110 2009/07/20 07:54:11 olga
* Appl. RuleSequence - tuning
*
* Revision 1.109 2009/07/16 17:21:02 olga
* GUI bugs fixed
*
* Revision 1.108 2009/07/14 12:16:31 olga
* Multiplicity bug fixed
*
* Revision 1.107 2009/07/08 16:22:01 olga
* Multiplicity bug fixed;
* ARS development
*
* Revision 1.106 2009/06/30 09:50:19 olga
* agg.xt_basis.GraphObject: added: setObjectName(String), getObjectName()
* agg.xt_basis.Node, Arc: changed: save, load the object name
* agg.editor.impl.EdGraphObject: changed: String getTypeString() - contains object name if set
*
* workaround of Applicability of Rule Sequences and Object Flow
*
* Revision 1.105 2009/06/02 12:39:25 olga
* Min Multiplicity check - bug fixed
*
* Revision 1.104 2009/05/28 13:18:23 olga
* Amalgamated graph transformation - development stage
*
* Revision 1.103 2009/05/12 10:54:25 olga
* CPA : bug fixed
*
* Revision 1.102 2009/05/12 10:36:58 olga
* CPA: bug fixed
* Applicability of Rule Seq. : bug fixed
*
* Revision 1.101 2009/04/27 07:37:15 olga
* Copy and Paste TypeGraph- bug fixed
* CPA - dangling edge conflict when first produce second delete - extended
*
* Revision 1.100 2009/04/23 06:29:13 olga
* CSP: bug fixed
*
* Revision 1.99 2009/04/21 13:21:49 olga
* CPA: bug fixed
*
* Revision 1.98 2009/04/20 08:50:45 olga
* CPA: bug fixed
*
* Revision 1.97 2009/03/19 09:31:06 olga
* CPE: attr check improved
*
* Revision 1.96 2009/03/12 10:57:45 olga
* some changes in CPA of managing names of the attribute variables.
*
* Revision 1.95 2009/03/04 13:06:10 olga
* New extension: Export/Import to/from ColorGraph
*
* Revision 1.94 2009/02/26 16:31:42 olga
* Code tuning
*
* Revision 1.93 2009/01/29 14:30:35 olga
* CPA - bug fixed
*
* Revision 1.92 2008/11/13 08:26:21 olga
* some tests
*
* Revision 1.91 2008/10/22 14:07:55 olga
* GUI, ARS and CPA tuning
*
* Revision 1.90 2008/10/15 14:58:39 olga
* - Bug fixed: import type graph with inheritance
* - Bug fixed: edge type Multiplicity check in CPA
*
* Revision 1.89 2008/10/07 07:44:46 olga
* Bug fixed: usage static methods of user own classes in attribute condition
*
* Revision 1.88 2008/09/22 10:02:38 olga
* tests only
*
* Revision 1.87 2008/09/11 09:22:26 olga
* Some changes in CPA: new computing of conflicts after an option changed,
* Graph layout of overlapping graphs
*
* Revision 1.86 2008/07/30 06:27:14 olga
* Applicability of RS , concurrent rule - handling of attributes improved
*
* Revision 1.85 2008/07/28 17:13:10 olga
* NACStarMorphism - bug fixed
*
* Revision 1.84 2008/07/21 10:03:28 olga
* Code tuning
*
* Revision 1.83 2008/07/17 15:51:50 olga
* GraphEditor - graph scaling tuning
*
* Revision 1.82 2008/07/10 07:42:34 olga
* Applicability of RS - tuning
*
* Revision 1.81 2008/07/09 13:34:26 olga
* Applicability of RS - bug fixed
* Delete not used node/edge type - bug fixed
* AGG help - extended
*
* Revision 1.80 2008/07/07 07:52:28 olga
* Applicability of Rule Sequences - bug fixed
*
* Revision 1.79 2008/06/30 10:47:39 olga
* Applicability of Rule Sequence - tuning
* Node animation - first steps
*
* Revision 1.78 2008/06/18 15:35:29 olga
* Applicability of Rule Sequences - Tuning
*
* Revision 1.77 2008/05/22 15:21:06 olga
* ARS - implementing further details
*
* Revision 1.76 2008/05/07 08:40:33 olga
* ...
*
* Revision 1.75 2008/05/07 08:37:55 olga
* Applicability of Rule Sequences with NACs
*
* Revision 1.74 2008/05/05 09:11:51 olga
* Graph parser - bug fixed.
* New AGG feature - Applicability of Rule Sequences - in working.
*
* Revision 1.73 2008/04/10 10:53:14 olga
* Draw graphics tuning
*
* Revision 1.72 2008/04/09 13:05:25 olga
* strong attribute check at constant value fixed
*
* Revision 1.71 2008/04/09 07:38:53 olga
* Bug fixed during loading of grammar
*
* Revision 1.70 2008/04/07 09:36:51 olga
* Code tuning: refactoring + profiling
* Extension: CPA - two new options added
*
* Revision 1.69 2008/02/25 08:44:48 olga
* Extending of CPA: new class CriticalRulePairAtGraph to get critical
* matches of two rules at a concret graph.
*
* Revision 1.68 2008/02/18 13:43:04 olga
* Code tuning
*
* Revision 1.67 2008/02/18 09:37:10 olga
* - an extention of rule dependency check is implemented;
* - some bugs fixed;
* - editing of graphs improved
*
* Revision 1.66 2008/01/07 09:08:40 olga
* - Applying an injective / non-injective rule at non-injective match - bug fixed;
* - Moving nodes/edges in edit mode "Select" - .;
* - CPA: Title of the overlapping graph frame for "delete-use" conflict - bug fixed
*
* Revision 1.65 2007/12/20 12:52:16 olga
* code tuning
*
* Revision 1.64 2007/12/19 11:04:59 olga
* Code tuning
*
* Revision 1.63 2007/12/17 08:33:30 olga
* Editing inheritance relations - bug fixed;
* CPA: dependency of rules - bug fixed
*
* Revision 1.62 2007/12/13 13:48:18 olga
* code tuning
*
* Revision 1.61 2007/12/12 09:21:55 olga
* code tuning
*
* Revision 1.60 2007/12/10 08:42:58 olga
* CPA of grammar with node type inheritance for attributed graphs - bug fixed
*
* Revision 1.59 2007/12/05 08:57:01 olga
* Delete a conclusion of an Atomic graph constraint : bug fixed
* Graph visualization update after the marking "Abstract" of a type node in the type graph : bug fixed
* CPA : some bug fixed; code tuning
*
* Revision 1.58 2007/12/03 08:35:12 olga
* - Some bugs fixed in visualization of morphism mappings after deleting and creating
* nodes, edges
* - implemented: matching with non-injective NAC and Match morphism
*
* Revision 1.57 2007/11/21 09:59:45 olga
* Update V1.6.2.1:
* new features: - default attr value can be set in a type graph and used during transformation (experimental phase)
* - currently selected node and edge type are shown in the bottom right corner of the AGG GUI
* - Critical pair analysis for grammar with node type inheritance (experimental phase)
*
* Revision 1.56 2007/11/19 08:48:39 olga
* Some GUI usability mistakes fixed.
* Default values in node/edge of a type graph implemented.
* Code tuning.
*
* Revision 1.55 2007/11/14 14:27:23 olga
* code tuning
*
* Revision 1.54 2007/11/14 08:53:43 olga
* code tuning
*
* Revision 1.53 2007/11/12 08:48:56 olga
* Code tuning
*
* Revision 1.52 2007/11/08 12:57:00 olga
* working on CPA inconsistency for rules with pacs and inheritance
* bugs are possible
*
* Revision 1.51 2007/11/05 09:18:22 olga
* code tuning
*
* Revision 1.50 2007/11/01 09:58:18 olga
* Code refactoring: generic types- done
*
* Revision 1.49 2007/10/24 08:21:30 olga
* CPA with inheritance: implementierung and test
*
* Revision 1.47 2007/10/22 09:46:50 olga
* Inheritance: bug fixed
*
* Revision 1.46 2007/10/22 09:03:16 olga
* First implementation of CPA for grammars with node type inheritance.
* Only for internal tests.
*
* Revision 1.45 2007/10/18 15:30:06 olga
* CPA bug fixed
*
* Revision 1.44 2007/10/17 14:48:02 olga
* EdRule: bug fixed
* Code tuning
*
* Revision 1.43 2007/10/10 14:30:34 olga
* Enumeration typing
*
* Revision 1.42 2007/10/10 07:44:27 olga
* CPA: bug fixed
* GUI, AtomConstraint: bug fixed
*
* Revision 1.41 2007/10/04 07:44:28 olga
* Code tuning
*
* Revision 1.40 2007/09/27 15:53:18 olga
* CPA tuning
*
* Revision 1.39 2007/09/27 08:42:46 olga
* CPA: new option -ignore pairs with same rules and same matches-
*
* Revision 1.38 2007/09/24 09:42:38 olga
* AGG transformation engine tuning
* Revision 1.37 2007/09/10 13:05:40 olga In this
* update: - package xerces2.5.0 is not used anymore; - class
* com.objectspace.jgl.Pair is replaced by the agg own generic class
* agg.util.Pair; - bugs fixed in: usage of PACs in rules; match completion;
* usage of static method calls in attr. conditions - graph editing: added some
* new features Revision 1.36 2007/07/09 08:00:27 olga GUI tuning
*
* Revision 1.35 2007/07/05 14:10:33 olga CSP test and tuning
*
* Revision 1.34 2007/07/04 14:45:53 olga test only
*
* Revision 1.33 2007/06/18 08:16:00 olga New extentions by drawing edge.
*
* Revision 1.32 2007/06/14 07:37:58 olga Bug fixed in the added check for
* constant attr value
*
* Revision 1.31 2007/06/13 13:31:55 olga tuning
*
* Revision 1.30 2007/06/13 12:30:33 olga new attribute check for critical pairs
* added: it checks the constant attribute value of an object in the LHS of the
* first rule against the constant attribute value of an compatible object in
* the LHS of the second rule. Here the LHS of the second rule is a value domain
* of the constant attribute. If any equal constant is not found and there is no
* other possibility to overlap the LHS1 and LHS2 then only over objects with
* constant attribute value, then these two rules are non-conflicting rules.
* Similar for NAC: the target graph af a NAC of the second rule agains the RHS
* of the first rule. Here only objects of a NAC without mapping from the LHS
* and produced objects of the RHS are considered.
*
* Revision 1.29 2007/06/13 08:32:57 olga Update: V161
*
* Revision 1.28 2007/03/28 10:00:54 olga - extensive changes of Node/Edge Type
* Editor, - first Undo implementation for graphs and Node/edge Type editing and
* transformation, - new / reimplemented options for layered transformation, for
* graph layouter - enable / disable for NACs, attr conditions, formula - GUI
* tuning
*
* Revision 1.27 2007/02/07 08:38:45 olga CPA bug fixed
*
* Revision 1.26 2007/02/05 12:33:39 olga CPA: chengeAttribute
* conflict/dependency : attributes with constants bug fixed, but the critical
* pairs computation has still a gap.
*
* Revision 1.25 2007/01/31 09:19:29 olga Bug fixed in case of transformating
* attributed grammar with inheritance and non-injective match
*
* Revision 1.24 2007/01/11 10:21:14 olga Optimized Version 1.5.1beta , free for
* tests
*
* Revision 1.23 2006/12/13 13:32:59 enrico reimplemented code
*
* Revision 1.22 2006/11/01 11:17:30 olga Optimized agg sources of CSP
* algorithm, match usability, graph isomorphic copy, node/edge type
* multiplicity check for injective rule and match
*
* Revision 1.21 2006/05/18 15:41:30 olga CPA: Bug fixed Import graph tuning
*
* Revision 1.20 2006/04/10 09:19:30 olga Import Type Graph, Import Graph -
* tuning. Attr. member type check: if class does not exist. Graph constraints
* for a layer of layered grammar.
*
* Revision 1.19 2006/03/13 10:04:42 olga CPA tuning
*
* Revision 1.18 2006/03/09 11:07:29 olga CPs tuning
*
* Revision 1.17 2006/03/08 14:08:13 olga test
*
* Revision 1.16 2006/03/08 13:48:20 olga test
*
* Revision 1.15 2006/03/08 09:14:59 olga CPs mistake fixed
*
* Revision 1.14 2006/03/06 10:04:06 olga CPs ...
*
* Revision 1.13 2006/03/06 09:36:39 olga CPs tuning
*
* Revision 1.12 2006/03/02 12:03:23 olga CPA: check host graph - done
*
* Revision 1.11 2006/03/01 15:49:33 olga tests
*
* Revision 1.10 2006/03/01 15:28:11 olga tests
*
* Revision 1.8 2006/03/01 09:55:46 olga - new CPA algorithm, new CPA GUI
*
* Revision 1.5 2005/09/26 08:35:15 olga CPA graph frames; bugs
*
* Revision 1.4 2005/09/19 09:12:14 olga CPA GUI tuning
*
* Revision 1.3 2005/09/12 10:34:02 olga Bug fixed in produce-forbid check.
*
* Revision 1.2 2005/08/25 15:28:13 olga Null pointer in hasConstantContext
* fixed.
*
* Revision 1.1 2005/08/25 11:56:58 enrico *** empty log message ***
*
* Revision 1.4 2005/07/13 08:13:37 olga Some code optimization only
*
* Revision 1.3 2005/07/11 09:30:20 olga This is test version AGG V1.2.8alfa .
* What is new: - saving rule option <disabled> - setting trigger rule for layer -
* display attr. conditions in gragra tree view - CPA algorithm <dependencies> -
* creating and display CPA graph with conflicts and/or dependencies based on
* (.cpx) file
*
* Revision 1.2 2005/06/20 13:37:03 olga Up to now the version 1.2.8 will be
* prepared.
*
* Revision 1.1 2005/05/30 12:58:03 olga Version with Eclipse
*
* Revision 1.60 2005/05/23 09:54:30 olga CPA improved: Stop of generation
* process or rule pair.
*
* Revision 1.59 2005/05/09 11:42:04 olga -CPs: error of dangling condition
* check fixed. -Transformation: attr. exception handling. -Omondo XMI to XSL:
* importing
*
* Revision 1.58 2005/04/14 12:30:28 olga Tests
*
* Revision 1.57 2005/04/11 13:43:05 olga Dangling by CPs fixed.
*
* Revision 1.56 2005/04/11 13:06:13 olga Errors during CPA are corrected.
*
* Revision 1.55 2005/03/24 11:15:17 olga ...
*
* Revision 1.54 2005/03/21 12:19:28 olga ...
*
* Revision 1.53 2005/03/21 09:22:57 olga ...
*
* Revision 1.52 2005/03/16 12:02:10 olga
*
* only little changes
*
* Revision 1.51 2005/03/03 13:48:42 olga - Match with NACs and attr. conditions
* with mixed variables - error corrected - save/load class packages written by
* user - PACs : creating T-equivalents - improved - save/load matches of the
* rules (only one match of a rule) - more friendly graph/rule editor GUI - more
* syntactical checks in attr. editor
*
* Revision 1.50 2005/02/14 09:27:01 olga -PAC; -GUI, layered graph
* transformation anzeigen; -CPs.
*
* Revision 1.49 2005/02/09 11:10:32 olga Fehler bei Post Application
* Constraints behoben. Import/Export Fehler mit aggXXX.jar behoben. CPs
* berechnung : Variablenumbenennung in Overlapgraphen
*
* Revision 1.48 2005/01/31 13:00:49 olga Das Laden mit TypeGraph check
* ENABLED_MAX_MIN - OK CP Berechnung angeppasst.
*
* Revision 1.47 2005/01/28 14:02:32 olga -Fehlerbehandlung beim Typgraph check
* -Erweiterung CP GUI / CP Menu -Fehlerbehandlung mit identification option
* -Fehlerbehandlung bei Rule PAC
*
* Revision 1.46 2005/01/03 13:14:43 olga Errors handling
*
* Revision 1.45 2004/12/20 14:53:48 olga Changes because of matching
* optimisation.
*
* Revision 1.44 2004/10/25 14:24:38 olga Fehlerbehandlung bei CPs und
* Aenderungen im zusammenhang mit termination-Modul in AGG
*
* Revision 1.43 2004/09/27 09:15:54 olga ...
*
* Revision 1.42 2004/09/23 08:26:43 olga Fehler bei CPs weg, Debug output in
* file
*
* Revision 1.41 2004/09/13 10:21:14 olga Einige Erweiterungen und
* Fehlerbeseitigung bei CPs und Graph Grammar Transformation
*
* Revision 1.40 2004/07/15 11:13:10 olga CPs letzter Schliff
*
* Revision 1.39 2004/07/12 07:31:41 olga ...
*
* Revision 1.38 2004/06/24 07:06:38 olga ..
*
* Revision 1.37 2004/06/23 08:26:57 olga CPs sind endlich OK.
*
* Revision 1.36 2004/06/21 08:35:33 olga immer noch CPs
*
* Revision 1.35 2004/06/17 10:21:50 olga Start-Transformation mit Anhalten nach
* einer Ableitung; CPs Korrektur und Optimierung
*
* Revision 1.34 2004/06/14 12:34:19 olga CP Analyse and Transformation
*
* Revision 1.33 2004/06/09 11:32:54 olga Attribute-Eingebe/Bedingungen : NAC
* kann jetzt eigene Variablen und Bedingungen haben. CP Berechnung korregiert.
*
* Revision 1.32 2004/04/19 11:39:30 olga Graphname als String ohne Blanks
*
* Revision 1.31 2004/03/29 12:15:25 olga Tests
*
* Revision 1.30 2004/03/26 12:44:12 olga ...
*
* Revision 1.29 2004/03/25 12:34:04 olga ....
*
* Revision 1.28 2004/03/18 17:41:53 olga
*
* rrektur an CPs und XML converter
*
* Revision 1.27 2004/03/08 10:19:20 olga tests
*
* Revision 1.26 2004/03/04 16:18:09 olga CP test
*
* Revision 1.25 2003/06/18 15:17:29 olga Tests
*
* Revision 1.24 2003/03/17 15:36:01 olga Xread, Xwrite erweitert
*
* Revision 1.23 2003/03/06 14:45:35 olga Tests
*
* Revision 1.22 2003/03/05 18:24:09 komm sorted/optimized import statements
*
* Revision 1.21 2003/03/05 14:53:35 olga CP optimierung
*
* Revision 1.20 2003/03/03 17:46:16 olga Optimierung
*
* Revision 1.19 2003/02/27 08:51:54 olga r1DeletesR2Uses geaendert
*
* Revision 1.18 2003/02/26 17:20:40 olga r1ProducesR2Forbids jetzt ohne Step
* mit r2
*
* Revision 1.17 2003/02/26 10:08:26 olga r1DeletesR2Used geaendert
*
* Revision 1.16 2003/02/24 17:51:22 olga Berechnung getestet
*
* Revision 1.15 2003/02/24 13:28:38 olga NACs
*
* Revision 1.14 2003/02/20 17:38:53 olga NAC tests
*
* Revision 1.13 2003/02/13 15:08:21 olga NACs bei CPs
*
* Revision 1.12 2003/02/03 17:49:31 olga Tests
*
* Revision 1.11 2003/01/20 12:11:46 olga Tests raus
*
* Revision 1.10 2003/01/15 16:31:03 olga Match.isValid(boolean allowVariables)
* wird benutzt
*
* Revision 1.9 2003/01/15 11:37:06 olga Kleine Aenderung
*
* Revision 1.8 2002/12/20 11:26:33 olga Tests
*
* Revision 1.7 2002/12/09 17:53:56 olga Graph name - Verbesserung
*
* Revision 1.6 2002/11/11 10:43:25 komm added support for multiplicity check
*
* Revision 1.5 2002/11/07 16:04:17 olga Tests
*
* Revision 1.4 2002/10/02 18:30:57 olga XXX
*
* Revision 1.3 2002/09/30 10:32:19 komm added TypeException handling
*
* Revision 1.2 2002/09/26 13:59:16 olga Folgeaenderung
*
* Revision 1.1.1.1 2002/07/11 12:17:23 olga Imported sources
*
* Revision 1.13 2001/08/16 14:14:08 olga LayerFunction erweitert:
* ExtendedLayerFunction erbt LayerFunction (checkLayer ueberschrieben)
* WeakLayerFunction erbt LayerFunction ( checkLayer ueberschrieben)
* WeakExtendedLayerFunction erbt WeakLayerFunction ( checkLayer ueberschrieben)
*
* Revision 1.12 2001/08/02 15:22:15 olga Error-Meldungen eingebaut in
* LayerFunction und die Anzeige dieser Meldungen in GUI.
*
* Revision 1.11 2001/07/04 10:45:33 olga Mehr Testarbeit.
*
* Revision 1.10 2001/06/26 17:28:03 olga Parser test
*
* Revision 1.9 2001/06/18 13:37:46 olga Bei Critical Pair ein neuer Menuitem:
* Debug, wo man einzelne Regelpaare testen kann. System.gc() eingefuegt.
*
* Revision 1.8 2001/06/13 16:49:34 olga Parser Classen Optimierung.
*
* Revision 1.7 2001/05/14 12:02:59 olga Zusaetzliche Parser Events Aufrufe
* eingebaut, um bessere Kommunikation mit GUI Status Anzeige zu ermoeglichen.
*
* Revision 1.6 2001/04/11 14:59:18 olga Stop Method eingefuegt.
*
* Revision 1.5 2001/03/29 12:01:33 olga MorphCompletionStrategy: dangling
* condition wieder ON
*
* Revision 1.4 2001/03/22 15:53:25 olga Zusaetzliche Events Meldungen
* eingebaut.
*
* Revision 1.3 2001/03/08 10:42:50 olga Die Parser Version aus parser branch
* wurde in Head uebernommen.
*
* Revision 1.1.2.16 2001/01/28 13:14:51 shultzke API fertig
*
* Revision 1.1.2.15 2001/01/03 09:44:59 shultzke TODO's bis auf laden und
* speichern erledigt. Wann meldet sich endlich Michael?
*
* Revision 1.1.2.14 2001/01/01 21:24:32 shultzke alle Parser fertig inklusive
* Layout
*
* Revision 1.1.2.13 2000/12/10 20:26:08 shultzke Parser kann XML
*
* Revision 1.1.2.12 2000/12/10 14:55:48 shultzke um Layer erweitert
*
* Revision 1.1.2.11 2000/10/25 13:43:37 shultzke parser start dialog
*
* Revision 1.1.2.10 2000/09/28 12:32:21 shultzke Attribute verbessert
*
* Revision 1.1.2.9 2000/09/27 13:21:09 shultzke bis auf die Attribute scheint
* die Excludebeziehung zu stehen
*
* Revision 1.1.2.8 2000/09/26 13:01:49 shultzke OverlapSetBerechnung erweitert
*
* Revision 1.1.2.7 2000/09/25 13:52:52 shultzke Report.trace veraendert
* ExcludePair: Attribute in exclude aufgenommen. Fast vollstaendig
* implementiert
*
* Revision 1.1.2.6 2000/09/21 14:02:19 shultzke ExcludePair bei nacs erweitert
*
* Revision 1.1.2.5 2000/07/19 08:24:14 shultzke jetzt wieder uebersetzbar
*
* Revision 1.1.2.4 2000/07/18 20:03:53 shultzke Exclude ohne Nac sollten
* funktionieren
*
* Revision 1.1.2.3 2000/07/17 16:12:43 shultzke exlude berechnung verschluckt
* stdout und rechnet nicht richtig
*
* Revision 1.1.2.2 2000/07/16 18:52:26 shultzke *** empty log message ***
*
* Revision 1.1.2.1 2000/07/12 07:58:36 shultzke merged
*
* Revision 1.2 2000/07/10 15:09:37 shultzke additional representtion
* hinzugefuegt
*
*/