package agg.xt_basis;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import agg.attribute.AttrContext;
import agg.attribute.AttrInstance;
import agg.attribute.AttrMapping;
import agg.attribute.handler.AttrHandler;
import agg.attribute.handler.impl.javaExpr.JexExpr;
import agg.attribute.parser.javaExpr.ASTId;
import agg.attribute.parser.javaExpr.SimpleNode;
import agg.attribute.parser.javaExpr.ASTPrimaryExpression;
import agg.attribute.handler.SymbolTable;
import agg.attribute.handler.HandlerType;
import agg.attribute.handler.HandlerExpr;
import agg.attribute.handler.AttrHandlerException;
import agg.attribute.impl.CondTuple;
import agg.attribute.impl.CondMember;
import agg.attribute.impl.ValueTuple;
import agg.attribute.impl.ValueMember;
import agg.attribute.impl.VarTuple;
import agg.attribute.impl.VarMember;
import agg.attribute.impl.DeclMember;
import agg.attribute.impl.ContextView;
import agg.attribute.facade.impl.DefaultInformationFacade;
import agg.cons.AtomConstraint;
import agg.cons.Evaluable;
import agg.cons.Formula;
import agg.ruleappl.ApplicabilityChecker;
import agg.ruleappl.ObjectFlow;
import agg.ruleappl.RuleSequence;
import agg.util.Pair;
import agg.util.Triple;
import agg.xt_basis.agt.KernelRule;
import agg.xt_basis.agt.MultiRule;
import agg.xt_basis.agt.RuleScheme;
import agg.xt_basis.csp.Completion_InheritCSP;
/**
* A factory class for Graphs, Morphisms, Rules, Matches.
*/
public class BaseFactory {
/** The factory models GraGras. */
private final List<GraGra> itsGraGras = new Vector<GraGra>();
protected static BaseFactory theBaseFactory;
public static BaseFactory theFactory() {
if (theBaseFactory != null)
return (theBaseFactory);
theBaseFactory = new BaseFactory();
return (theBaseFactory);
}
/** Create a new gragra with its own type set and a host graph inclusive. */
public GraGra createGraGra() {
GraGra gg = new GraGra(new TypeSet());
this.itsGraGras.add(gg);
return (gg);
}
/** Create a new gragra with its own type set and a host graph optionally. */
public GraGra createGraGra(boolean withGraph) {
GraGra gg = new GraGra(withGraph);
this.itsGraGras.add(gg);
return (gg);
}
/** Create a new gragra with its own type set and a host graph optionally.
* The second parameter defines whether the graphs are directed or not.
*/
public GraGra createGraGra(boolean withGraph, boolean directedArcs, boolean parallelArcs) {
GraGra gg = new GraGra(new TypeSet(directedArcs, parallelArcs), withGraph);
this.itsGraGras.add(gg);
return (gg);
}
/**
* Dispose the specified gragra and remove from the gragra list.
*/
public void destroyGraGra(GraGra gg) {
if (this.itsGraGras.contains(gg)) {
this.itsGraGras.remove(gg);
gg.dispose();
}
}
/**
* Remove the specified gragra from the gragra list.
*/
public void removeGraGra(GraGra gg) {
if (this.itsGraGras.contains(gg)) {
this.itsGraGras.remove(gg);
}
}
public Enumeration<GraGra> getGraGras() {
return ((Vector<GraGra>) this.itsGraGras).elements();
}
public int getCountOfGraGras() {
return this.itsGraGras.size();
}
public void notify(GraGra gg) {
if (!this.isElement(gg))
(this.itsGraGras).add(gg);
}
private boolean isElement(GraGra gg) {
if (this.itsGraGras.contains(gg))
return true;
return false;
}
/** Create a new graph transformation unit GraTra */
public GraTra createGraTra() {
return (new DefaultGraTraImpl());
}
/** Create a new graph */
public final Graph createGraph() {
return new Graph();
}
/**
* Create a new graph
*/
public final Graph createGraph(TypeSet types) {
// return new Graph(types);
return types.isArcDirected()? new Graph(types): new UndirectedGraph(types);
}
/**
* Create a new graph
*/
public final Graph createGraph(TypeSet types, boolean complete) {
return types.isArcDirected()? new Graph(types, complete):
new UndirectedGraph(types, complete);
}
/** Create a new type manager and container for the type graph */
public final TypeSet createTypeSet() {
return new TypeSet();
}
/** Dispose the specified graph. */
public final void destroyGraph(Graph graph) {
graph.dispose();
}
/**
* There are graphs L, R, G and given morphisms
* r: L --> R and m: L --> G.<br>
* Computes PO as the colimit graph H with morphisms
* f: G --> H and g: R --> H.<br>
*
* The attributes of nodes and edges of the graph L are still unset.
*
* @return a pair (f,g) or NULL
*/
public final Pair<OrdinaryMorphism,OrdinaryMorphism> makePO(
final OrdinaryMorphism r,
final OrdinaryMorphism m,
boolean allowAttrVarsInGraph,
boolean wrtEqualAttrVarName) {
try {
Pair<OrdinaryMorphism,OrdinaryMorphism>
PO = StaticStep.executeColim(r, m, allowAttrVarsInGraph, wrtEqualAttrVarName);
return PO;
} catch (TypeException ex) {}
return null;
}
/**
* There are graphs K, L, G and given morphisms
* l: K --> L and g: L --> G.<br>
* Computes PO-complement: the graph C with morphisms
* k: K --> C and c: C --> G.<br>
*
* @return a pair (c,k) or NULL
*/
public final Pair<OrdinaryMorphism,OrdinaryMorphism> makePOComplement(
final OrdinaryMorphism l,
final OrdinaryMorphism g) {
final Graph K = l.getSource();
final Graph L = l.getTarget();
final Graph G = g.getTarget();
final OrdinaryMorphism c = G.inverseIsoCopy();
if (c == null)
return null;
final Graph C = c.getSource();
final OrdinaryMorphism k = new OrdinaryMorphism(K, C,
g.getAttrManager().newContext(AttrMapping.PLAIN_MAP));
List<Node> del = new Vector<Node>();
Iterator<Node> nodes = L.getNodesCollection().iterator();
while (nodes.hasNext()) {
Node nL = nodes.next();
Node nC = (Node)c.getInverseImage(g.getImage(nL)).nextElement();
if (l.getInverseImage(nL).hasMoreElements()) {
Node nK = (Node)l.getInverseImage(nL).nextElement();
try {
k.addMapping(nK, nC);
} catch (BadMappingException ex) {
System.out.println("BF.makePOComplement: "+ex.getMessage());
return null;
}
} else {
del.add(nC);
}
}
Iterator<Arc> arcs = L.getArcsCollection().iterator();
while (arcs.hasNext()) {
Arc aL = arcs.next();
Arc aC = (Arc)c.getInverseImage(g.getImage(aL)).nextElement();
if (l.getInverseImage(aL).hasMoreElements()) {
Arc aK = (Arc)l.getInverseImage(aL).nextElement();
try {
k.addMapping(aK, aC);
} catch (BadMappingException ex) {
System.out.println("BF.makePOComplement: "+ex.getMessage());
return null;
}
} else {
try {
c.removeMapping(aC);
} catch (BadMappingException ex) {
System.out.println("BF.makePOComplement: "+ex.getMessage());
return null;
}
try {
C.destroyArc(aC, false, true);
} catch (TypeException ex) {
System.out.println("BF.makePOComplement: "+ex.getMessage());
return null;
}
}
}
for (int i=0; i<del.size(); i++) {
try {
c.removeMapping(del.get(i));
} catch (BadMappingException ex) {
System.out.println("BF.makePOComplement: "+ex.getMessage());
return null;
}
try {
C.destroyNode(del.get(i), false, true);
} catch (TypeException ex) {
System.out.println("BF.makePOComplement: "+ex.getMessage());
return null;
}
}
// arcs = G.getArcsCollection().iterator();
// while (arcs.hasNext()) {
// Arc aG = arcs.next();
// GraphObject sG = aG.getSource();
// GraphObject tG = aG.getTarget();
// if (g.getInverseImage(sG).hasMoreElements()) {
// GraphObject sL = g.getInverseImage(sG).nextElement();
// if (!l.getInverseImage(sL).hasMoreElements()) {
// System.out.println("BF.makePOComplement: edge source conflict!!");
// return null;
// }
// } else if (g.getInverseImage(tG).hasMoreElements()) {
// GraphObject sL = g.getInverseImage(tG).nextElement();
// if (!l.getInverseImage(sL).hasMoreElements()) {
// System.out.println("BF.makePOComplement: edge source conflict!!");
// return null;
// }
// }
// }
return new Pair<OrdinaryMorphism,OrdinaryMorphism>(c, k);
}
private boolean checkDelDueToMerge(final OrdinaryMorphism t,
final OrdinaryMorphism l,
final OrdinaryMorphism g) {
final Graph G = g.getTarget();
Iterator<Arc> arcs = G.getArcsCollection().iterator();
while (arcs.hasNext()) {
Arc aG = arcs.next();
GraphObject sG = aG.getSource();
GraphObject tG = aG.getTarget();
if (g.getInverseImage(sG).hasMoreElements()
&& !t.getInverseImage(g.getInverseImage(sG).nextElement()).hasMoreElements()) {
// aG is a new edge
GraphObject sL = g.getInverseImage(sG).nextElement();
if (!l.getInverseImage(sL).hasMoreElements()) {
// System.out.println("BF.makePOComplement: edge source conflict!!");
return false;
}
} else if (g.getInverseImage(tG).hasMoreElements()) {
GraphObject sL = g.getInverseImage(tG).nextElement();
if (!l.getInverseImage(sL).hasMoreElements()) {
// System.out.println("BF.makePOComplement: edge source conflict!!");
return false;
}
}
}
return true;
}
/*
* There are graphs K, L, G and given morphisms
* l: K --> L and g: L --> G.<br>
* Computes PO-complement: the graph C with morphisms
* k: K --> C and c: C --> G.<br>
*
* @return a pair (c,k) or NULL
*
private final Pair<OrdinaryMorphism,OrdinaryMorphism> makePOComplement2(
final OrdinaryMorphism l,
final OrdinaryMorphism g) {
final Graph K = l.getSource();
final OrdinaryMorphism k = K.isoGraph();
final Graph C = k.getTarget();
final Graph G = g.getTarget();
final OrdinaryMorphism c = new OrdinaryMorphism(C, G,
g.getAttrManager().newContext(AttrMapping.PLAIN_MAP));
final Hashtable<Object,Object> o2o = new Hashtable<Object,Object>();
Enumeration<GraphObject> dom = l.getDomain();
while (dom.hasMoreElements()) {
GraphObject goK = dom.nextElement();
try {
GraphObject goC = k.getImage(goK);
GraphObject goG = g.getImage(l.getImage(goK));
goC.getAttribute().copyEntries(goG.getAttribute());
c.addMapping(goC, goG);
if (goK.isNode()) {
o2o.put(goG, goC);
}
} catch (BadMappingException ex) {
System.out.println("BF.makePOComplement: "+ex.getMessage());
return null;
}
}
Iterator<Node> nodes = G.getNodesCollection().iterator();
while (nodes.hasNext()) {
Node nG = nodes.next();
if (!g.getInverseImage(nG).hasMoreElements()) {
try {
Node nC = C.createNode(nG.getType());
nC.getAttribute().copyEntries(nG.getAttribute());
o2o.put(nG, nC);
try {
c.addMapping(nC, nG);
} catch (BadMappingException ex) {
System.out.println("BF.makePOComplement2: "+ex.getMessage());
return null;
}
} catch (TypeException ex) {
System.out.println("BF.makePOComplement2: "+ex.getMessage());
return null;
}
}
}
Iterator<Arc> arcs = G.getArcsCollection().iterator();
while (arcs.hasNext()) {
Arc aG = arcs.next();
if (!g.getInverseImage(aG).hasMoreElements()) {
try {
Node sC = (Node)o2o.get(aG.getSource());
Node tC = (Node)o2o.get(aG.getTarget());
Arc aC = C.createArc(aG.getType(), sC, tC);
aC.getAttribute().copyEntries(aG.getAttribute());
try {
c.addMapping(aC, aG);
} catch (BadMappingException ex) {
System.out.println("BF.makePOComplement2: "+ex.getMessage());
return null;
}
} catch (TypeException ex) {
System.out.println("BF.makePOComplement2: "+ex.getMessage());
return null;
}
}
}
return new Pair<OrdinaryMorphism,OrdinaryMorphism>(c, k);
}
*/
/*
* There are graphs R, G, H with given morphisms
* g: R --> H and f: G --> H.<br>
* Computes the PB as the limit graph L with morphisms
* r: L --> R and m: L --> G.<br>
*
* The attributes of nodes and edges of the graph L are still unset.
*
* @return a pair (r,m) or NULL
*/
public final Pair<OrdinaryMorphism,OrdinaryMorphism> makePB(
final OrdinaryMorphism f,
final OrdinaryMorphism g) {
final Graph L = BaseFactory.theFactory().createGraph(f.getTarget().getTypeSet());
final Graph R = g.getSource();
final Graph G = f.getSource();
final Graph H = f.getTarget();
final OrdinaryMorphism r = new OrdinaryMorphism(L, R,
g.getAttrManager().newContext(
AttrMapping.PLAIN_MAP));
final OrdinaryMorphism m = new OrdinaryMorphism(L, G,
f.getAttrManager().newContext(
AttrMapping.PLAIN_MAP));
Hashtable<Object,Object> n2n = new Hashtable<Object,Object>();
Iterator<Node> nodes = H.getNodesCollection().iterator();
while (nodes.hasNext()) {
Node n = nodes.next();
if (g.getInverseImage(n).hasMoreElements()
&& f.getInverseImage(n).hasMoreElements()) {
Node n_f = (Node) f.getInverseImage(n).nextElement();
Node n_g = (Node) g.getInverseImage(n).nextElement();
try {
Node nn = L.createNode(n.getType());
try {
r.addMapping(nn, n_g);
m.addMapping(nn, n_f);
n2n.put(n_g, nn);
} catch (BadMappingException ex1) {}
} catch (TypeException ex) {}
}
}
Iterator<Arc> arcs = H.getArcsCollection().iterator();
while (arcs.hasNext()) {
Arc a = arcs.next();
if (g.getInverseImage(a).hasMoreElements()
&& f.getInverseImage(a).hasMoreElements()) {
Arc a_f = (Arc) f.getInverseImage(a).nextElement();
Arc a_g = (Arc) g.getInverseImage(a).nextElement();
Node src = (Node)n2n.get(a_g.getSource());
Node tar = (Node)n2n.get(a_g.getTarget());
try {
Arc na = L.createArc(a.getType(), src, tar);
try {
r.addMapping(na, a_g);
m.addMapping(na, a_f);
} catch (BadMappingException ex1) {}
} catch (TypeException ex) {}
}
}
return new Pair<OrdinaryMorphism,OrdinaryMorphism>(r, m);
}
/*
* Given morphism g: D --> G.<br>
* Computes Initial Pushout (IPO) as a triple of morphisms:
* b1: B --> D, b2: B --> L, b3: L --> G.
*
* The attributes of nodes and edges of the graphs B and L are still unset.
*
* @return a triple of morphisms or NULL
*/
public final Triple<OrdinaryMorphism,OrdinaryMorphism,OrdinaryMorphism> makeIPO(final OrdinaryMorphism g) {
final Graph B = BaseFactory.theFactory().createGraph(g.getTarget().getTypeSet());
final Graph D = g.getSource();
final Graph L = BaseFactory.theFactory().createGraph(g.getTarget().getTypeSet());
final Graph G = g.getTarget();
final OrdinaryMorphism b1 = new OrdinaryMorphism(B, D,
g.getAttrManager().newContext(
AttrMapping.PLAIN_MAP));
final OrdinaryMorphism b2 = new OrdinaryMorphism(B, L,
g.getAttrManager().newContext(
AttrMapping.PLAIN_MAP));
final OrdinaryMorphism b3 = new OrdinaryMorphism(L, G,
g.getAttrManager().newContext(
AttrMapping.PLAIN_MAP));
Hashtable<Object,Object> n2n_L = new Hashtable<Object,Object>();
Hashtable<Object,Object> n2n_B = new Hashtable<Object,Object>();
// an edge in G but not in D add with source and target to L, add mappings to b3
// source/target in G and in D add to B, add mappings to b1 and b2
Iterator<Arc> arcs = G.getArcsCollection().iterator();
while (arcs.hasNext()) {
Arc a = arcs.next();
if (!g.getInverseImage(a).hasMoreElements()) {
// edge is in G but not in D
try {
// add edge to L
Node s_L = (n2n_L.get(a.getSource()) == null
|| !(n2n_L.get(a.getSource()) instanceof Node))?
L.createNode(a.getSourceType()):
(Node)n2n_L.get(a.getSource());
Node t_L = (n2n_L.get(a.getTarget()) == null
|| !(n2n_L.get(a.getTarget()) instanceof Node))?
L.createNode(a.getTargetType()):
(Node)n2n_L.get(a.getTarget());
Arc a_L = L.createArc(a.getType(), s_L, t_L);
n2n_L.put(a.getSource(), s_L);
n2n_L.put(a.getTarget(), t_L);
try {
b3.addMapping(s_L, a.getSource());
b3.addMapping(t_L, a.getTarget());
b3.addMapping(a_L, a);
} catch (BadMappingException ex1) {}
if (g.getInverseImage(a.getSource()).hasMoreElements()) {
// edge's source is in D, so add it to B
if (n2n_B.get(a.getSource()) == null) {
Node s_B = B.createNode(a.getSourceType());
n2n_B.put(a.getSource(), s_B);
try {
b1.addMapping(s_B, g.getInverseImage(a.getSource()).nextElement());
b2.addMapping(s_B, s_L);
} catch (BadMappingException ex1) {}
}
}
if (g.getInverseImage(a.getTarget()).hasMoreElements()) {
// edge's target is in D, so add it to B
if (n2n_B.get(a.getTarget()) == null) {
Node t_B = B.createNode(a.getTargetType());
n2n_B.put(a.getTarget(), t_B);
try {
b1.addMapping(t_B, g.getInverseImage(a.getTarget()).nextElement());
b2.addMapping(t_B, t_L);
} catch (BadMappingException ex1) {}
}
}
} catch (TypeException ex) {}
} else {
if (n2n_L.get(a.getSource()) == null)
n2n_L.put(a.getSource(), a);
if (n2n_L.get(a.getTarget()) == null)
n2n_L.put(a.getTarget(), a);
}
}
Iterator<Node> nodes = G.getNodesCollection().iterator();
// single node in G but not in D add to L, add mappings to b3
while (nodes.hasNext()) {
Node n = nodes.next();
if (n2n_L.get(n) == null
&& !g.getInverseImage(n).hasMoreElements()) {
try {
Node n_L = L.createNode(n.getType());
try {
b3.addMapping(n_L, n);
} catch (BadMappingException ex1) {}
} catch (TypeException ex) {}
}
}
return new Triple<OrdinaryMorphism,OrdinaryMorphism,OrdinaryMorphism>(b1, b2, b3);
}
/*
* Given morphism t: G --> H.<br>
* Computes the span G <-- D --> H with g: D --> G and f: D --> H.
*
* The attributes of nodes and edges of the graph D are still unset.
*
* @return a pair (g,f) or NULL
*/
public final Pair<OrdinaryMorphism,OrdinaryMorphism> makeSpan(final OrdinaryMorphism t) {
final Graph D = BaseFactory.theFactory().createGraph(t.getTarget().getTypeSet());
final Graph G = t.getSource();
final Graph H = t.getTarget();
final OrdinaryMorphism g = new OrdinaryMorphism(D, G,
t.getAttrManager().newContext(
AttrMapping.PLAIN_MAP));
final OrdinaryMorphism f = new OrdinaryMorphism(D, H,
t.getAttrManager().newContext(
AttrMapping.PLAIN_MAP));
Hashtable<Object,Object> n2n = new Hashtable<Object,Object>();
Iterator<Node> nodes = G.getNodesCollection().iterator();
while (nodes.hasNext()) {
Node n = nodes.next();
if (t.getImage(n) != null) {
try {
Node nn = D.createNode(n.getType());
try {
f.addMapping(nn, t.getImage(n));
g.addMapping(nn, n);
n2n.put(n, nn);
} catch (BadMappingException ex1) {}
} catch (TypeException ex) {}
}
}
Iterator<Arc> arcs = G.getArcsCollection().iterator();
while (arcs.hasNext()) {
Arc a = arcs.next();
if (t.getImage(a) != null) {
Node src = (Node)n2n.get(a.getSource());
Node tar = (Node)n2n.get(a.getTarget());
try {
Arc na = D.createArc(a.getType(), src, tar);
try {
f.addMapping(na, t.getImage(a));
g.addMapping(na, a);
} catch (BadMappingException ex1) {}
} catch (TypeException ex) {}
}
}
return new Pair<OrdinaryMorphism,OrdinaryMorphism>(g, f);
}
/*
* Given transformation G --t-> H.<br>
* Computes the graph modification G <-g-- D --h-> H and then
* the minimal rule L --r->R with induced match L --m-> G.
*
* @return the minimal rule or NULL
*/
public final Rule makeMinimalRule(final OrdinaryMorphism t) {
Pair<OrdinaryMorphism,OrdinaryMorphism> span = this.makeSpan(t);
Triple<OrdinaryMorphism,OrdinaryMorphism,OrdinaryMorphism> IPO1 = this.makeIPO(span.first);
Triple<OrdinaryMorphism,OrdinaryMorphism,OrdinaryMorphism> IPO2 = this.makeIPO(span.second);
Pair<OrdinaryMorphism,OrdinaryMorphism> PB = this.makePB(IPO1.first, IPO2.first);
Pair<OrdinaryMorphism,OrdinaryMorphism> PO4 = this.makePO(PB.first, PB.second, true, false);
Pair<OrdinaryMorphism,OrdinaryMorphism> PO3 = null;
Pair<OrdinaryMorphism,OrdinaryMorphism> PO5 = null;
if (IPO1.second.getSource() == PO4.first.getSource()) {
// this is the case!
PO3 = this.makePO(IPO1.second, PO4.first, true, false);
PO5 = this.makePO(IPO2.second, PO4.second, true, false);
} else if (IPO1.second.getSource() == PO4.second.getSource()) {
PO3 = this.makePO(IPO1.second, PO4.second, true, false);
PO5 = this.makePO(IPO2.second, PO4.first, true, false);
}
if (PO3 != null && PO5 != null) {
final OrdinaryMorphism mKD = new OrdinaryMorphism(
PO4.first.getTarget(), IPO1.first.getTarget(),
t.getAttrManager().newContext(
AttrMapping.PLAIN_MAP));
if (mKD.makeDiagram(PO4.first, IPO1.first)
&& mKD.makeDiagram(PO4.second, IPO2.first)) {
final Rule r = new Rule(PO3.first.getTarget(), PO5.first.getTarget());
if (r.makeDiagram(PO3.first, PO5.first)) {
final OrdinaryMorphism mL = new OrdinaryMorphism(
r.getLeft(), t.getSource(),
t.getAttrManager().newContext(AttrMapping.PLAIN_MAP));
final OrdinaryMorphism mR = new OrdinaryMorphism(
r.getRight(), t.getTarget(),
t.getAttrManager().newContext(AttrMapping.PLAIN_MAP));
if (mL.makeDiagram(PO3.first, mKD, span.first)
&& mR.makeDiagram(PO5.first, mKD, span.second)) {
changedAttr2Var(r, t, mL, mR);
Match m = this.createMatch(r, t.getSource());
if (m.makeDiagram(PO3.first, mKD, span.first)
&& m.makeDiagram(PO3.second, IPO1.third)) {
r.setMatch(m);
return r;
}
}
}
}
}
return null;
}
/*
* Given two transformations G --t1-> H1 and G --t2-> H2. <br>
* Computes two graph modifications G <-g1-- D1 --h1-> H1 and G <-g2-- D2 --h2-> H2 and then <br>
* the merge graph X and the merge graph modification G <-d-- D --x-> X.
*
* @return a pair (d,x) or NULL
*/
public final Pair<OrdinaryMorphism,OrdinaryMorphism> makeMerge(
final OrdinaryMorphism t1,
final OrdinaryMorphism t2) {
if (t1.getSource() != t2.getSource())
return null;
Pair<OrdinaryMorphism,OrdinaryMorphism> span1 = this.makeSpan(t1);
Pair<OrdinaryMorphism,OrdinaryMorphism> span2 = this.makeSpan(t2);
Pair<OrdinaryMorphism,OrdinaryMorphism> pb = this.makePB(span1.first, span2.first);
if (pb != null) {
if (this.checkDelDueToMerge(t1, pb.second, span1.second)
&& this.checkDelDueToMerge(t2, pb.first, span2.second))
{
Pair<OrdinaryMorphism,OrdinaryMorphism> poc1 = this.makePOComplement(pb.second, span1.second);
Pair<OrdinaryMorphism,OrdinaryMorphism> poc2 = this.makePOComplement(pb.first, span2.second);
if (poc1 != null && poc2 != null) {
Pair<OrdinaryMorphism,OrdinaryMorphism> po3 = this.makePO(poc2.second, poc1.second, false, false);
if (po3 != null) {
OrdinaryMorphism d = pb.second.compose(span1.first);
OrdinaryMorphism x = poc1.second.compose(po3.second);
if (d != null && x != null) {
return new Pair<OrdinaryMorphism,OrdinaryMorphism>(d, x);
}
}
}
}
}
return null;
}
private void changedAttr2Var(final Rule r, final OrdinaryMorphism t,
final OrdinaryMorphism mL, final OrdinaryMorphism mR) {
int indx = 1;
Enumeration<GraphObject> dom = r.getDomain();
while (dom.hasMoreElements()) {
GraphObject goL = dom.nextElement();
GraphObject goR = r.getImage(goL);
GraphObject goG = mL.getImage(goL);
GraphObject goH = mR.getImage(goR);
if (goG == null || goH == null)
continue;
ValueTuple vtL = (ValueTuple)goL.getAttribute();
ValueTuple vtR = (ValueTuple)goR.getAttribute();
ValueTuple vtH = (ValueTuple)goH.getAttribute();
ValueTuple vtG = (ValueTuple)goG.getAttribute();
for (int i=0; i<vtG.getSize(); i++) {
ValueMember vmG = vtG.getValueMemberAt(i);
ValueMember vmH = vtH.getValueMemberAt(vmG.getName());
if (vmG.isSet() && vmH.isSet()
&& !vmG.getExprAsText().equals(vmH.getExprAsText())) {
ValueMember vmL = vtL.getValueMemberAt(vmG.getName());
vmL.setExprAsText("x".concat(String.valueOf(indx)));
ValueMember vmR = vtR.getValueMemberAt(vmG.getName());
vmR.setExprAsText("x".concat(String.valueOf(indx)));
indx++;
}
}
}
}
/**
* Construct a new rule from the given morphism h. The left graph of the
* rule is the source graph and the right
* graph of the rule is the target graph of the morphism h,
* the object mappings are similar to the mappings of the morphism h.
*/
public Rule constructRuleFromMorph(OrdinaryMorphism h) {
return constructRuleFromMorph(h, null);
}
/**
* Construct a new rule from the given morphism h. The left graph of the
* rule is the source and the right graph is the target of the morphism h,
* the object mappings are similar to the mappings of the morphism h.
* The attribute context of the new rule is set to the given attribute context.
*/
public Rule constructRuleFromMorph(OrdinaryMorphism h, AttrContext attrCntx) {
Rule rule = (attrCntx==null)?
new Rule(h.getOriginal(), h.getImage()):
new Rule(h.getOriginal(), h.getImage(), attrCntx);
Enumeration<GraphObject> dom = h.getDomain();
while (dom.hasMoreElements()) {
GraphObject obj = dom.nextElement();
try {
rule.addMapping(obj, h.getImage(obj));
} catch (BadMappingException ex) {}
}
// set variables and conditions
VarTuple vars = (VarTuple) rule.getAttrContext().getVariables();
this.declareVar(rule.getLeft(), vars, (ContextView) rule.getAttrContext());
this.declareVar(rule.getRight(), vars, (ContextView) rule.getAttrContext());
// this.declareVariable(rule.getLeft(), vars);
// this.declareVariable(rule.getRight(), vars);
VarTuple varsMorph = (VarTuple) h.getAttrContext().getVariables();
for (int j = 0; j < varsMorph.getSize(); j++) {
VarMember vm = varsMorph.getVarMemberAt(j);
DeclMember dm = (DeclMember) vm.getDeclaration();
if (dm.getTypeName() != null && dm.getName() != null) {
if (!vars.isDeclared(dm.getTypeName(), dm.getName())) {
vars.declare(dm.getHandler(), dm.getTypeName(), dm.getName());
vars.getVarMemberAt(dm.getName()).setInputParameter(vm.isInputParameter());
}
}
}
CondTuple condsMorph = (CondTuple) h.getAttrContext().getConditions();
CondTuple conds = (CondTuple) rule.getAttrContext().getConditions();
for (int j = 0; j < condsMorph.getSize(); j++) {
CondMember cm = condsMorph.getCondMemberAt(j);
if (!cm.getExprAsText().equals("")) {
conds.addCondition(cm.getExprAsText());
}
}
// check attr. setting in RHS and evntl. fill with variable
String exprMsg = "";
vars = (VarTuple) rule.getAttrContext().getVariables();
String mark = "r";
setEmptyRHSAttrs(rule, mark, vars, rule.getRight().getNodesSet().iterator());
setEmptyRHSAttrs(rule, mark, vars, rule.getRight().getArcsSet().iterator());
String warning = rule.getErrorMsg();
if (!exprMsg.equals(""))
warning = warning.concat(exprMsg).concat(" ; ");
rule.setErrorMsg(warning);
return rule;
}
private void setEmptyRHSAttrs(Rule rule, String mark, VarTuple vars, Iterator<?> objs) {
String exprMsg = "";
int count = vars.getSize();
while (objs.hasNext()) {
GraphObject o = (GraphObject) objs.next();
if (o.getAttribute() == null)
continue;
Enumeration<GraphObject> inverseImg = rule.getInverseImage(o);
if (!inverseImg.hasMoreElements()) {
ValueTuple value = (ValueTuple) o.getAttribute();
for (int i = 0; i < value.getSize(); i++) {
ValueMember vm = value.getValueMemberAt(i);
if (!vm.isSet()) {
exprMsg = "attribute member: ".concat(vm.getName());
String t = vm.getName() + String.valueOf(count) + mark;
// declareVariable(vm.getDeclaration().getHandler(),
// vm.getDeclaration().getTypeName(), t, vars);
count++;
vm.setExprAsText(t);
vm.setTransient(true);
exprMsg = exprMsg.concat(" set by a new variable: ").concat(t).concat(" ; ");
}
}
}
}
}
/**
* Construct a rule r out of the given morphism h. The left graph of the
* rule r is a graph isomorphic to the source graph of the morphism h, the
* right graph of the rule r is a graph isomorphic to the target graph of
* the morphism h, the object mappings are identical to the mappings of the
* morphism h. Returns a Pair with : the first element is the new rule, the
* second element is a Pair with two elements of OrdinaryMorphism: an
* isomorphic copy of the source graph of the morphism h and an isomorphic
* copy of the target graph of the morphism h.
*/
public Pair<Rule, Pair<OrdinaryMorphism, OrdinaryMorphism>> constructIsomorphicRule(
final OrdinaryMorphism h) {
return constructIsomorphicRule(h, true, false);
}
/**
* Construct a rule based of the given morphism <code>h</code>. The left graph of the
* rule is isomorphic to the source graph of <code>h</code>, the
* right graph of the rule is isomorphic to the target graph of <code>h</code>,
* the object mappings are identical to the mappings of <code>h</code>,
* Returns a Pair with the first element is the new rule, the
* second element is a Pair with two isomorphic morphism.
*/
public Pair<Rule, Pair<OrdinaryMorphism, OrdinaryMorphism>> constructIsomorphicRule(
final OrdinaryMorphism h,
boolean replaceExpressionByVar,
boolean replaceConstantByVar) {
final OrdinaryMorphism isoL = h.getSource().isomorphicCopy();
if (isoL == null) {
return null;
}
final OrdinaryMorphism isoR = h.getTarget().isomorphicCopy();
if (isoR == null) {
isoL.dispose(false, true);
return null;
}
final Rule rule = new Rule(isoL.getTarget(), isoR.getTarget());
final Enumeration<GraphObject> dom = h.getDomain();
while (dom.hasMoreElements()) {
GraphObject obj = dom.nextElement();
GraphObject img = h.getImage(obj);
try {
rule.addMapping(isoL.getImage(obj), isoR.getImage(img));
} catch (BadMappingException ex) {}
}
final Pair<Rule, Pair<OrdinaryMorphism, OrdinaryMorphism>>
p = new Pair<Rule, Pair<OrdinaryMorphism, OrdinaryMorphism>>(
rule,
new Pair<OrdinaryMorphism, OrdinaryMorphism>(isoL, isoR));
rule.putVarToAttrContext();
// set variables and conditions
final VarTuple vars = (VarTuple) rule.getAttrContext().getVariables();
final VarTuple varsMorph = (VarTuple) h.getAttrContext().getVariables();
for (int j = 0; j < varsMorph.getSize(); j++) {
VarMember vm = varsMorph.getVarMemberAt(j);
DeclMember dm = (DeclMember) vm.getDeclaration();
if (!vars.isDeclared(dm.getTypeName(), dm.getName())) {
vars.declare(dm.getHandler(), dm.getTypeName(), dm.getName());
}
}
final CondTuple condsMorph = (CondTuple) h.getAttrContext().getConditions();
final CondTuple conds = (CondTuple) rule.getAttrContext().getConditions();
for (int j = 0; j < condsMorph.getSize(); j++) {
CondMember cm = condsMorph.getCondMemberAt(j);
if (!cm.getExprAsText().equals("")) {
conds.addCondition(cm.getExprAsText());
}
}
// check attr. setting in RHS and evntl. fill with variable
int count = 1;
count = doCheckAndFillUnsetAttrs(rule, vars, count,
replaceExpressionByVar,
rule.getRight().getNodesSet().iterator());
count = doCheckAndFillUnsetAttrs(rule, vars, count,
replaceExpressionByVar,
rule.getRight().getArcsSet().iterator());
return p;
}
/*
* Check attributes of the specified elements:<br>
* - replace expression value by a variable<br>
* - set unset attribute by a variable<br>
*/
private int doCheckAndFillUnsetAttrs(
final Rule rule,
final VarTuple vars,
int startCount,
boolean replaceExpressionByVar,
final Iterator<?> elems) {
// check attr. setting in RHS and evntl. fill with variable
int count = startCount;
while (elems.hasNext()) {
GraphObject o =(GraphObject) elems.next();
boolean inverseImageExists = rule.getInverseImage(o).hasMoreElements();
if (o.getAttribute() == null) {
continue;
}
ValueTuple value = (ValueTuple) o.getAttribute();
for (int i = 0; i < value.getSize(); i++) {
ValueMember vm = value.getValueMemberAt(i);
if (!vm.isSet()) {
if (!inverseImageExists) {
String t = vm.getName() + count;
// declareVariable(vm.getDeclaration().getHandler(),
// vm.getDeclaration().getTypeName(), t, vars);
vm.setExprAsText(t);
vm.setTransient(true);
count++;
}
} else if (vm.getExpr().isComplex() && replaceExpressionByVar) {
String t = "expr" + count;
// declareVariable(vm.getDeclaration().getHandler(),
// vm.getDeclaration().getTypeName(), t, vars);
vm.setExprAsText(t);
vm.setTransient(true);
count++;
}
// else if (vm.getExpr().isConstant() && replaceConstantByVar) {
// declareVariable(vm.getDeclaration().getHandler(),
// vm.getDeclaration().getTypeName(), t, vars);
// vm.setExprAsText(t);
// vm.setTransient(true);
// count++;
// }
}
}
return count;
}
/**
* Construct a new rule from the given morphism h. The left graph of the
* rule is a copy of the source graph and the
* right graph of the rule r is a copy of the target graph of
* the morphism h, the object mappings are similar to the
* mappings of the morphism h.
*/
public Rule constructRule(OrdinaryMorphism h) {
// System.out.println("BaseFactory.constructRule");
Rule rule = new Rule(h.getOriginal().getTypeSet());
Graph lgraph = h.getOriginal();
Graph rgraph = h.getImage();
Graph left = rule.getLeft();
Graph right = rule.getRight();
Hashtable<GraphObject, GraphObject> ltable = new Hashtable<GraphObject, GraphObject>();
Hashtable<GraphObject, GraphObject> rtable = new Hashtable<GraphObject, GraphObject>();
Iterator<Node> rnodes = rgraph.getNodesSet().iterator();
while (rnodes.hasNext()) {
Node rNode = rnodes.next();
Node itsRNode = null;
try {
itsRNode = right.copyNode(rNode);
itsRNode.setContextUsage(rNode.getContextUsage());
rtable.put(rNode, itsRNode);
} catch (TypeException e) {
// If the given morphism is well typed,
// the resulting rule graphs should be also well typed
e.printStackTrace();
}
}
Iterator<Node> lnodes = lgraph.getNodesSet().iterator();
while (lnodes.hasNext()) {
Node lNode = lnodes.next();
Node itsLNode = null;
try {
itsLNode = left.copyNode(lNode);
itsLNode.setContextUsage(lNode.getContextUsage());
ltable.put(lNode, itsLNode);
} catch (TypeException e) {
// If the given morphism is well typed,
// the resulting rule graphs should be also well typed
e.printStackTrace();
}
GraphObject rn = h.getImage(lNode);
if (rn != null) {
try {
rule.addMapping(itsLNode, rtable.get(rn));
} catch (BadMappingException ex) {}
}
}
Iterator<Arc> rarcs = rgraph.getArcsSet().iterator();
while (rarcs.hasNext()) {
Arc rArc = rarcs.next();
Node itsRSource = (Node) rtable.get(rArc.getSource());
Node itsRTarget = (Node) rtable.get(rArc.getTarget());
Arc itsRArc = null;
try {
itsRArc = right.copyArc(rArc, itsRSource, itsRTarget);
itsRArc.setContextUsage(rArc.getContextUsage());
rtable.put(rArc, itsRArc);
} catch (TypeException ex) {
}
}
Iterator<Arc> larcs = lgraph.getArcsSet().iterator();
while (larcs.hasNext()) {
Arc lArc = larcs.next();
Node itsLSource = (Node) ltable.get(lArc.getSource());
Node itsLTarget = (Node) ltable.get(lArc.getTarget());
Arc itsLArc = null;
try {
itsLArc = left.copyArc(lArc, itsLSource, itsLTarget);
itsLArc.setContextUsage(lArc.getContextUsage());
ltable.put(lArc, itsLArc);
} catch (TypeException ex) {
}
GraphObject ra = h.getImage(lArc);
if (ra != null) {
try {
rule.addMapping(itsLArc, rtable.get(ra));
} catch (BadMappingException ex) {}
}
}
// check attr. setting in RHS and evntl. fill with variable
VarTuple vars = (VarTuple) rule.getAttrContext().getVariables();
int count = vars.getSize();
String mark = "r";
Iterator<?> objs = right.getNodesSet().iterator();
while (objs.hasNext()) {
GraphObject o = (GraphObject) objs.next();
Enumeration<GraphObject> inverseImg = rule.getInverseImage(o);
if (!inverseImg.hasMoreElements()) {
if (o.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) o.getAttribute();
for (int i = 0; i < value.getSize(); i++) {
ValueMember vm = value.getValueMemberAt(i);
if (!vm.isSet()) {
String t = vm.getName() + String.valueOf(count) + mark;
// declareVariable(vm.getDeclaration().getHandler(),
// vm.getDeclaration().getTypeName(), t, vars);
count++;
vm.setExprAsText(t);
vm.setTransient(true);
}
}
}
}
objs = right.getArcsSet().iterator();
while (objs.hasNext()) {
GraphObject o = (GraphObject) objs.next();
Enumeration<GraphObject> inverseImg = rule.getInverseImage(o);
if (!inverseImg.hasMoreElements()) {
if (o.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) o.getAttribute();
for (int i = 0; i < value.getSize(); i++) {
ValueMember vm = value.getValueMemberAt(i);
if (!vm.isSet()) {
String t = vm.getName() + String.valueOf(count) + mark;
// declareVariable(vm.getDeclaration().getHandler(),
// vm.getDeclaration().getTypeName(), t, vars);
count++;
vm.setExprAsText(t);
vm.setTransient(true);
}
}
}
}
ltable.clear();
ltable = null;
rtable.clear();
rtable = null;
return (rule);
}
public Pair<OrdinaryMorphism, Pair<OrdinaryMorphism, OrdinaryMorphism>> reverseMorphism(
final OrdinaryMorphism morph) {
// System.out.println("BF.reverseMorphism: of "+morph.getSource().getName()+" --> "+morph.getTarget().getName());
// check if morph is injective
if (!morph.isInjective()) {
return null;
}
String warning = "";
// make LHS
OrdinaryMorphism isoRight = morph.getTarget().isomorphicCopy();
// make RHS
OrdinaryMorphism isoLeft = morph.getSource().isomorphicCopy();
if (isoRight == null || isoLeft == null) {
return null;
}
Graph left = isoRight.getTarget();
Graph right = isoLeft.getTarget();
// make inverse morphism
OrdinaryMorphism inverseMorph = createMorphism(left, right);
VarTuple vars = (VarTuple) inverseMorph.getAttrContext().getVariables();
// new LHS: replace attr. expression by variable
String warning1 = replaceAttrExpressionByVariable(vars, left.getNodesSet().iterator(), true, null); //false, null);
if (!warning1.equals(""))
warning = warning.concat(warning1);
warning1 = replaceAttrExpressionByVariable(vars, left.getArcsSet().iterator(), true, null); //false, null);
if (!warning1.equals(""))
warning = warning.concat(warning1);
// set mappings
final Enumeration<GraphObject> dom = morph.getDomain();
while (dom.hasMoreElements()) {
GraphObject obj = dom.nextElement();
GraphObject img = morph.getImage(obj);
GraphObject img1 = isoLeft.getImage(obj);
GraphObject obj1 = isoRight.getImage(img);
try {
inverseMorph.addMapping(obj1, img1);
replaceExprOf3ByVarOf1(obj, img, obj1); // TEST!!
} catch (BadMappingException ex) {
warning = warning.concat(ex.getMessage()).concat(" ; ");
}
// set left attr. members by values of the right attr. members
if (obj1.getAttribute() != null && img1.getAttribute() != null) {
ValueTuple valueLeft = (ValueTuple) obj1.getAttribute();
ValueTuple valueRight = (ValueTuple) img1.getAttribute();
for (int i = 0; i < valueLeft.getSize(); i++) {
ValueMember mLeft = valueLeft.getValueMemberAt(i);
ValueMember mRight = valueRight.getValueMemberAt(mLeft.getName());
if (!mLeft.isSet() && mRight.isSet()) {
mLeft.setExprAsText(mRight.getExprAsText());
mLeft.setTransient(mRight.isTransient()); //(true);
}
}
}
}
// new RHS: replace empty attr of nodes by variable
warning1 = replaceEmptyAttrByVariable(vars, right.getNodesSet().iterator(), inverseMorph);
if (!warning1.equals(""))
warning = warning.concat(warning1);
// new RHS: replace empty attr of arcs by variable
warning1 = replaceEmptyAttrByVariable(vars, right.getArcsSet().iterator(), inverseMorph);
if (!warning1.equals(""))
warning = warning.concat(warning1);
inverseMorph.setErrorMsg(warning);
return new Pair<OrdinaryMorphism, Pair<OrdinaryMorphism, OrdinaryMorphism>>(
inverseMorph, new Pair<OrdinaryMorphism, OrdinaryMorphism>(
isoLeft, isoRight));
}
private void replaceExprOf3ByVarOf1(GraphObject obj, GraphObject img, GraphObject obj1) {
if (obj.getAttribute() != null && img.getAttribute() != null && obj1.getAttribute() != null) {
ValueTuple vObj = (ValueTuple) obj.getAttribute();
ValueTuple vImg = (ValueTuple) img.getAttribute();
ValueTuple vObj1 = (ValueTuple) obj1.getAttribute();
for (int i = 0; i < vImg.getSize(); i++) {
ValueMember mImg = vImg.getValueMemberAt(i);
ValueMember mObj = vObj.getValueMemberAt(i);
ValueMember mObj1 = vObj1.getValueMemberAt(i);
if (mImg.isSet() && mImg.getExpr().isComplex()
&& mObj.isSet() && mObj.getExpr().isVariable()) {
// mObj1.setExprAsText(mObj.getExprAsText()); // TEST!!!
mObj1.setTransient(false);
}
}
}
}
private boolean reverseMorphismInto(
final OrdinaryMorphism srcMorph,
OrdinaryMorphism tarMorph,
final Hashtable<GraphObject, GraphObject> table) {
if (!srcMorph.isInjective()) {
return false;
}
String warning = "";
Graph left = null;
Graph right = null;
// make LHS
if (tarMorph == null) {
left = srcMorph.getTarget().copy(table);
}
else {
this.copyGraph(srcMorph.getTarget(), tarMorph.getSource(), table);
left = tarMorph.getSource();
}
// make RHS
if (tarMorph == null) {
right = srcMorph.getSource().copy(table);
}
else {
this.copyGraph(srcMorph.getSource(), tarMorph.getTarget(), table);
right = tarMorph.getTarget();
}
if (left == null || right == null) {
return false;
}
// make inverse morphism
if (tarMorph == null)
tarMorph = createMorphism(left, right);
VarTuple vars = (VarTuple) tarMorph.getAttrContext().getVariables();
// new LHS: replace attr. expression by variable
String warning1 = replaceAttrExpressionByVariable(vars, left.getNodesSet().iterator(), true, null); //false, null);
if (!warning1.equals(""))
warning = warning.concat(warning1);
warning1 = replaceAttrExpressionByVariable(vars, left.getArcsSet().iterator(), true, null); //false, null);
if (!warning1.equals(""))
warning = warning.concat(warning1);
// set mappings
final Enumeration<GraphObject> dom = srcMorph.getDomain();
while (dom.hasMoreElements()) {
GraphObject obj = dom.nextElement();
GraphObject img = srcMorph.getImage(obj);
GraphObject img1 = table.get(obj);
GraphObject obj1 = table.get(img);
try {
tarMorph.addMapping(obj1, img1);
} catch (BadMappingException ex) {
warning = warning.concat(ex.getMessage()).concat(" ; ");
}
// set left attr. members by values of the right attr. members
if (obj1.getAttribute() != null && img1.getAttribute() != null) {
ValueTuple valueLeft = (ValueTuple) obj1.getAttribute();
ValueTuple valueRight = (ValueTuple) img1.getAttribute();
for (int i = 0; i < valueLeft.getSize(); i++) {
ValueMember mLeft = valueLeft.getValueMemberAt(i);
ValueMember mRight = valueRight.getValueMemberAt(mLeft.getName());
if (!mLeft.isSet() && mRight.isSet()) {
mLeft.setExprAsText(mRight.getExprAsText());
mLeft.setTransient(mRight.isTransient()); //(true);
}
}
}
}
// new RHS: replace empty attr of nodes by variable
warning1 = replaceEmptyAttrByVariable(vars, right.getNodesSet().iterator(), tarMorph);
if (!warning1.equals(""))
warning = warning.concat(warning1);
// new RHS: replace empty attr of arcs by variable
warning1 = replaceEmptyAttrByVariable(vars, right.getArcsSet().iterator(), tarMorph);
if (!warning1.equals("")) {
warning = warning.concat(warning1);
}
tarMorph.setErrorMsg(warning);
return true;
}
/**
* Returns an inverse rule construction of the given rule by success, otherwise null.<br>
* The rule of the result is the inverse rule r_1 with:<br>
* - r_1.LHS is a copy of this.RHS,<br>
* - r_1.RHS is a copy of this.LHS, <br>
* - r_1 morphism is the converted rule morphism. <br>
*
* The Boolean value is true, when no application conditions (NACs, PACs, GACs, attribute conditions)
* of the original rule exist, otherwise false<br>
*
* Note: the specified Rule r has to be injective, otherwise returns null.<br>
* The first morphism of the second pair is r.LHS -> r_1.RHS,<br>
* The second morphism of the second pair is r.RHS -> r_1.LHS. <br>
*/
public Pair<Pair<Rule,Boolean>, Pair<OrdinaryMorphism, OrdinaryMorphism>> makeAbstractInverseRule(
final Rule r) {
final Pair<OrdinaryMorphism, Pair<OrdinaryMorphism, OrdinaryMorphism>>
pair = this.reverseMorphism(r);
if (pair != null) {
final Rule absInverseRule = BaseFactory.theFactory().constructRuleFromMorph(pair.first);
absInverseRule.setName(r.getName() + "_INV");
reflectInputParameter(r, absInverseRule);
String warning = pair.first.getErrorMsg().concat(absInverseRule.getErrorMsg());
if (!warning.isEmpty())
absInverseRule.setErrorMsg(warning);
if (!r.getNACs().hasMoreElements()
&& !r.getPACs().hasMoreElements()
&& !r.getNestedACs().hasMoreElements()
&& r.getAttrContext().getConditions().getNumberOfEntries() == 0) {
return new Pair<Pair<Rule,Boolean>, Pair<OrdinaryMorphism, OrdinaryMorphism>>(
new Pair<Rule,Boolean>(absInverseRule, Boolean.TRUE), pair.second);
}
else {
return new Pair<Pair<Rule,Boolean>, Pair<OrdinaryMorphism, OrdinaryMorphism>>(
new Pair<Rule,Boolean>(absInverseRule, Boolean.FALSE), pair.second);
}
}
return null;
}
/**
* Returns an inverse rule construction of the given rule by success, otherwise null.<br>
* The rule of the result is the inverse rule r_1 with:<br>
* - r_1.LHS is a copy of this.RHS,<br>
* - r_1.RHS is a copy of this.LHS, <br>
* - r_1 morphism is the converted rule morphism. <br>
*
* The Boolean value is true, when no application conditions (NACs, PACs, GACs, attribute conditions)
* of the original rule exist,
* or they are exist and converted to the inverse rule, otherwise false<br>
*
* Note: the specified Rule r has to be injective, otherwise returns null.<br>
* The first morphism of the second pair is r.LHS -> r_1.RHS,<br>
* The second morphism of the second pair is r.RHS -> r_1.LHS. <br>
*/
public Pair<Pair<Rule,Boolean>, Pair<OrdinaryMorphism, OrdinaryMorphism>> reverseRule(final Rule r) {
boolean failed = false;
Pair<Pair<Rule,Boolean>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
result = makeAbstractInverseRule(r);
if (result != null) {
final Rule inverseRule = result.first.first;
boolean needExtend = !result.first.second.booleanValue();
if (needExtend) {
OrdinaryMorphism isoRight = result.second.second;
// first converting PACs from LHS to RHS
if (this.convertPACsLeft2Right(r, inverseRule, isoRight)) {
// converting GACs from LHS to RHS
if (this.convertRuleGACsLeft2Right(r, inverseRule, isoRight)) {
// converting NACs from LHS to RHS
this.convertNACsLeft2Right(r, inverseRule, isoRight);
// convert attr conditions
this.convertAttrConditionLeft2Right(r, inverseRule);
result.first.second = Boolean.TRUE;
}
}
else
failed = true;
}
if (failed) {
result.first.first.dispose();
result.second.first.dispose();
result.second.second.dispose();
result.first = null;
result.second = null;
result = null;
}
else {
inverseRule.removeUnusedVariableOfAttrContext();
inverseRule.isReadyToTransform();
}
}
return result;
}
public void replaceExprByVarInApplConds(
final Rule r,
final Hashtable<ValueMember, Pair<String, String>> storeMap) {
Enumeration<OrdinaryMorphism> applConds = r.getNACs();
while (applConds.hasMoreElements()) {
OrdinaryMorphism morph = applConds.nextElement();
VarTuple vars = (VarTuple) morph.getAttrContext().getVariables();
replaceAttrExpressionByVariable(
vars,
morph.getTarget().getNodesSet().iterator(),
true,
storeMap);
replaceAttrExpressionByVariable(
vars,
morph.getTarget().getArcsSet().iterator(),
true,
storeMap);
// ((VarTuple) morph.getAttrContext().getVariables()).showVariables();
}
applConds = r.getPACs();
while (applConds.hasMoreElements()) {
OrdinaryMorphism morph = applConds.nextElement();
VarTuple vars = (VarTuple) morph.getAttrContext().getVariables();
replaceAttrExpressionByVariable(
vars,
morph.getTarget().getNodesSet().iterator(),
true,
storeMap);
replaceAttrExpressionByVariable(
vars,
morph.getTarget().getArcsSet().iterator(),
true,
storeMap);
// ((VarTuple) morph.getAttrContext().getVariables()).showVariables();
}
}
public void replaceExprByVarInApplConds(
final List<Rule> rules,
final Hashtable<ValueMember, Pair<String, String>> storeMap) {
for (int i=0; i<rules.size(); i++) {
Rule r = rules.get(i);
replaceExprByVarInApplConds(r, storeMap);
}
}
/**
* Replace expressions in the attributes of the specified elements by a new variable
* which is added to the specified variable tuple.
*
* @param vars
* @param elems
* @return a warning message (not an error!) about replacement
*/
public String replaceAttrExpressionByVariable(
final VarTuple vars,
final Iterator<?> elems,
boolean setTransient,
final Hashtable<ValueMember, Pair<String, String>> storeMap) {
int nn = -1;
String exprMsg = "";
while (elems.hasNext()) {
GraphObject grob = (GraphObject) elems.next();
nn++;
if (grob.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) grob.getAttribute();
for (int i = 0; i < value.getSize(); i++) {
String nm = (i == 0) ? "" : ("" + i);
ValueMember val = value.getValueMemberAt(i);
if (val.isSet()) {
if (val.getExpr().isComplex()) {
exprMsg = "Attr. expression ".concat(val.getExprAsText());
String varname = "expr" + nn + nm;
if (storeMap != null) {
storeMap.put(val, new Pair<String,String>(varname, val.getExprAsText()));
}
val.setExpr(null);
vars.declare(DefaultInformationFacade.self()
.getJavaHandler(), val.getDeclaration()
.getTypeName(), varname);
vars.getEntryAt(varname).setTransient(setTransient);
val.setExprAsText(varname);
val.setTransient(setTransient);
exprMsg = exprMsg.concat(" replaced by a new variable ").concat(varname).concat(" ; ");
// System.out.println(exprMsg);
}
// additionally check undeclared variable
else if (val.getExpr().isVariable()) {
if (vars.getVarMemberAt(val.getExprAsText()) == null) {
String varname = val.getExprAsText();
vars.declare(DefaultInformationFacade.self()
.getJavaHandler(), val.getDeclaration()
.getTypeName(), varname);
vars.getEntryAt(varname).setTransient(true);
val.setTransient(setTransient);
}
}
}
}
}
return exprMsg;
}
public void restoreExprByVarInApplConds(
final Rule r,
final Hashtable<ValueMember, Pair<String, String>> storeMap) {
Enumeration<OrdinaryMorphism> applConds = r.getNACs();
while (applConds.hasMoreElements()) {
OrdinaryMorphism morph = applConds.nextElement();
VarTuple vars = (VarTuple) morph.getAttrContext().getVariables();
this.restoreAttrExpressionReplacedByVariable(
vars,
morph.getTarget().getNodesSet().iterator(),
storeMap);
this.restoreAttrExpressionReplacedByVariable(
vars,
morph.getTarget().getArcsSet().iterator(),
storeMap);
// ((VarTuple) morph.getAttrContext().getVariables()).showVariables();
}
applConds = r.getPACs();
while (applConds.hasMoreElements()) {
OrdinaryMorphism morph = applConds.nextElement();
VarTuple vars = (VarTuple) morph.getAttrContext().getVariables();
this.restoreAttrExpressionReplacedByVariable(
vars,
morph.getTarget().getNodesSet().iterator(),
storeMap);
this.restoreAttrExpressionReplacedByVariable(
vars,
morph.getTarget().getArcsSet().iterator(),
storeMap);
// ((VarTuple) morph.getAttrContext().getVariables()).showVariables();
}
}
public void restoreExprByVarInApplConds(
final List<Rule> rules,
final Hashtable<ValueMember, Pair<String, String>> storeMap) {
if (storeMap == null || storeMap.isEmpty()) {
return;
}
for (int i=0; i<rules.size(); i++) {
Rule r = rules.get(i);
restoreExprByVarInApplConds(r, storeMap);
}
}
private void restoreAttrExpressionReplacedByVariable(
final VarTuple vars,
final Iterator<?> elems,
final Hashtable<ValueMember, Pair<String, String>> storeMap) {
while (elems.hasNext()) {
GraphObject grob = (GraphObject) elems.next();
// System.out.println("BF.replaceAttrExpressionByVariable: inside of "+grob.getContext().getName());
if (grob.getAttribute() == null)
continue;
ValueTuple value = (ValueTuple) grob.getAttribute();
for (int i = 0; i < value.getSize(); i++) {
ValueMember val = value.getValueMemberAt(i);
Pair<String,String> p = storeMap.get(val);
if (p != null) {
String var = p.first;
String expr = p.second;
val.setExprAsText(expr);
val.setTransient(false);
vars.getTupleType().deleteMemberAt(var);
}
}
}
}
public Rule checkApplCondsOfRules(final List<Rule> rules) {
for (int i=0; i<rules.size(); i++) {
if (!rules.get(i).areApplCondsValid())
return rules.get(i);
}
return null;
}
/*
* Returns true if the Match m1 does not delete or changed objects of the Match m2,
* or vice versa. Otherwise returns false.<br>
* The given matches must be complete and valid.<br>
* Potential produce-forbid conflicts would not be checked.
*/
public boolean checkWeakParallelMatches(final Match m1, final Match m2) {
if (m1 != null && m1.isValid()
&& m2 != null && m2.isValid()) {
Enumeration<GraphObject> dom1 = m1.getDomain();
while (dom1.hasMoreElements()) {
GraphObject go1 = dom1.nextElement();
GraphObject go = m1.getImage(go1);
if (m2.hasInverseImage(go)) {
GraphObject go2 = m2.getInverseImage(go).nextElement();
// check r2 delete
if (m2.getRule().getImage(go2) == null) {
return false;
}
// check r1 delete
else if (m1.getRule().getImage(go1) == null) {
return false;
}
else {
GraphObject img1 = m1.getRule().getImage(go1);
GraphObject img2 = m2.getRule().getImage(go2);
// check change attribute
if (img1.getAttribute() != null && img2.getAttribute() != null) {
ValueTuple vt1l = (ValueTuple) go1.getAttribute();
ValueTuple vt2l = (ValueTuple) go2.getAttribute();
ValueTuple vt1r = (ValueTuple) img1.getAttribute();
ValueTuple vt2r = (ValueTuple) img2.getAttribute();
for (int i=0; i<vt1r.getNumberOfEntries(); i++) {
ValueMember vm1r = vt1r.getEntryAt(i);
ValueMember vm1l = vt1l.getEntryAt(vm1r.getName());
// check r1 change attribute
if (vm1r.isSet()
&& (!vm1l.isSet()
|| !vm1r.getExprAsText().equals(vm1l.getExprAsText()))) {
return false;
}
else {
ValueMember vm2r = vt2r.getEntryAt(vm1r.getName());
ValueMember vm2l = vt2l.getEntryAt(vm1r.getName());
// check r2 change attribute
if (vm2r.isSet()
&& (!vm2l.isSet()
|| !vm2r.getExprAsText().equals(vm2l.getExprAsText()))) {
return false;
}
}
}
}
}
}
}
return true;
}
return false;
}
public ParallelRule makeParallelRule(final TypeSet types, final List<Rule> rules) {
if (rules.size() == 2)
return new ParallelRule(types, rules.get(0), rules.get(1));
else
return null;
}
/**
* Creates a new concurrent rule which is constructed as
* a disjoint union of LHS1 and LHS2 (resp. RHS1 and RHS2)
* of the given two rules.<br>
* The application conditions (NACs, PACs, attr. condition) of the input rules
* will be shifted to the new concurrent rule.<br>
* @param r1 first rule
* @param r2 second rule
* @return ConcurrentRule
*/
private ConcurrentRule makeConcurrentRuleByDisjointUnion(final Rule r1, final Rule r2) {
final Hashtable<String, String> storeNewName2OldName = new Hashtable<String, String>();
if (r1 != r2) {
BaseFactory.theFactory().renameSimilarVariable(r2, r1, "r1_", storeNewName2OldName);
// ((VarTuple) r1.getAttrContext().getVariables()).showVariables();
// ((CondTuple) r1.getAttrContext().getConditions()).showConditions();
}
final ConcurrentRule cr = new ConcurrentRule(r1, r2);
if (!storeNewName2OldName.isEmpty()) {
BaseFactory.theFactory().restoreVariableNameOfRule(r1, storeNewName2OldName);
}
return cr;
}
/**
* Creates a new jointly concurrent rule. The given object flow
* (r1.RHS.object -> r2.LHS2.object) defines the jointly usable
* objects of the RHS of the first rule
* and the LHS of the second rule.<br>
* The application conditions (NACs, attr. condition) of the input rules
* will be shifted to the new concurrent rule.<br>
* The PACs of rules r1 and r2 are integrated in the r1.LHS
* resp. r2.LHS at the begin of the creating process.<br>
* The application conditions (NACs, attr. condition) of the input rules
* will be shifted to the new concurrent rule.<br>
* @param r1 first rule
* @param r2 second rule
* @param objFlow a map with (r1.RHS.object -> r2.LHS.object)
* @return ConcurrentRule
*/
private ConcurrentRule makeConcurrentRuleByObjectFlow(
final Rule r1,
final Rule r2,
final Hashtable<Object, Object> objFlow) {
if (objFlow.isEmpty()) {
return this.makeConcurrentRuleByDisjointUnion(r1, r2);
}
ConcurrentRule cr = null;
// rename similar variables of rule1
final Hashtable<String, String> storeNewName2OldName = new Hashtable<String, String>();
if (r1 != r2) {
BaseFactory.theFactory().renameSimilarVariable(r2, r1, "r1_", storeNewName2OldName);
// ((VarTuple) r1.getAttrContext().getVariables()).showVariables();
// ((CondTuple) r1.getAttrContext().getConditions()).showConditions();
}
Pair<Pair<Rule,Boolean>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
inverseRulePair = BaseFactory.theFactory().reverseRule(r1);
Rule inverseRule1 = inverseRulePair.first.first;
int maxsize = r2.getLeft().getSize();
if (!objFlow.isEmpty())
maxsize = objFlow.size();
if (maxsize > 0) {
long freeM = Runtime.getRuntime().freeMemory();
// boolean disjoint_union = false;
// boolean withIsomorphic = true; //false;
// matchmap inverse:: keys to values, values to keys, because of inverse r1
final Hashtable<Object, Object> inversematchmap = new Hashtable<Object, Object>();
Enumeration<?> keys = objFlow.keys();
while (keys.hasMoreElements()) {
Object key = keys.nextElement();
// r2.lhs.object -> r1inverse.rhs.object
inversematchmap.put(objFlow.get(key),
inverseRulePair.second.second.getImage((GraphObject)key));
}
Enumeration<Pair<OrdinaryMorphism, OrdinaryMorphism>>
enums = BaseFactory.theFactory().getOverlappingByPredefinedIntersection(
r2.getLeft(), inverseRule1.getLeft(), inversematchmap);
if (enums != null
&& enums.hasMoreElements()) {
final Pair<OrdinaryMorphism, OrdinaryMorphism> overlapping = enums.nextElement();
// if (this.checkIntersectionDuetoObjectFlow(overlapping, objFlow))
{
cr = new ConcurrentRule(r1, inverseRulePair.first.first, r2,
inverseRulePair.second.first,
inverseRulePair.second.second,
overlapping.second,
overlapping.first);
if (cr.getRule() != null) {
System.out.println("=== >>> Concurrent rule: "
+cr.getRule().getName()
+" has NACs: "+cr.getRule().getNACs().hasMoreElements()
+", has PACs: "+cr.getRule().getPACs().hasMoreElements());
// ((VarTuple) cr.getRule().getAttrContext().getVariables()).showVariables();
cr.usedM = freeM - Runtime.getRuntime().freeMemory();
}
}
}
}
if (!storeNewName2OldName.isEmpty()) {
BaseFactory.theFactory().restoreVariableNameOfRule(r1, storeNewName2OldName);
}
return cr;
}
/**
* Creates a concurrent rule based on the given RuleSequence.<br>
* If the second parameter is <code>false</code>, the left and right graphs
* of the returned concurrent rule are constructed as disjoint unions of the left
* and right graphs of the rules of the sequence.<br>
* If the second parameter is <code>true</code> and an ObjectFlow of the given rule sequence
* is defined, the left and right graphs of the concurrent rule are overlapping graphs above
* the ObjectFlow,<br>
* otherwise it returns null.<br>
* The backward construction starts with the two last rules of the RuleSequence.
* The next previous rule will be used at the next building step.
*
* @param sequence is a RuleSequence
* @param byObjectFlow
* @return a ConcurrentRule based on the disjoint union or the ObjectFlow of the RuleSequence
*/
public ConcurrentRule makeConcurrentRuleOfRuleSeqBackwards(
final RuleSequence sequence,
boolean byObjectFlow) {
long freeM = 0;
ConcurrentRule cr = null;
boolean ok = true;
if (byObjectFlow) {
sequence.makeFlatSequence();
sequence.tryCompleteObjFlowTransClosure();
}
RuleSequence rs = sequence.getCopy();
// RuleSequence.printObjFlow(rs);
int size = rs.getSize();
int i2 = -1;
int i1 = -1;
while (size>1 && ok) {
i2 = size-1;
i1 = i2-1;
Rule r1 = rs.getRule(i1);
Rule r2 = rs.getRule(i2);
if (byObjectFlow) {
ObjectFlow objFlow_r1r2 = rs.getObjFlowForRules(r1, i1, r2, i2);
// System.out.println(objFlow_r1r2.getKey());
if (objFlow_r1r2 != null
&& !objFlow_r1r2.isEmpty()) {
cr = this.makeConcurrentRuleByObjectFlow(r1, r2, objFlow_r1r2.getMapping());
} else {
cr = this.makeConcurrentRuleByDisjointUnion(r1, r2);
}
}
else {
cr = this.makeConcurrentRuleByDisjointUnion(r1, r2);
}
if (cr == null || cr.getRule() == null) {
ok = false;
}
else {
freeM = Runtime.getRuntime().freeMemory();
cr.setIndexOfFirstSourceRule(i1);
cr.setIndexOfSecondSourceRule(i2);
List<ObjectFlow> newObjFlows = new Vector<ObjectFlow>();
if (byObjectFlow) {
List<ObjectFlow> r1ObjFlow = rs.getObjFlowForRule(r1, i1);
List<ObjectFlow> r2ObjFlow = rs.getObjFlowForRule(r2, i2);
cr.reflectObjectFlow(r1ObjFlow);
cr.reflectObjectFlow(r2ObjFlow);
for (int j=0; j<i1; j++) {
Rule rj = rs.getRule(j);
List<ObjectFlow> rjObjFlow = rs.getObjFlowFromRule(rj, j);
if (!rjObjFlow.isEmpty()) {
Hashtable<Object, Object>
rjOutIn = new Hashtable<Object, Object>(cr.getReflectedInputObjectFlowFromRule(rj, rjObjFlow));
if (!rjOutIn.isEmpty()) {
int indx1 = j;
int indx2 = i1;
if (rs.getGraph() != null) {
indx1++;
indx2++;
}
ObjectFlow objFlow = new ObjectFlow(rj, cr.getRule(),
indx1, indx2, rjOutIn);
newObjFlows.add(objFlow);
}
}
}
List<ObjectFlow> gObjFlow = rs.getObjFlowFromGraph();
if (!gObjFlow.isEmpty()) {
Hashtable<Object, Object>
gOutIn = new Hashtable<Object, Object>(cr.getReflectedInputObjectFlowFromGraph(rs.getGraph(), gObjFlow));
if (!gOutIn.isEmpty()) {
int indx2 = i1;
if (rs.getGraph() != null) {
indx2++;
}
ObjectFlow objFlow = new ObjectFlow(rs.getGraph(), cr.getRule(),
0, indx2, gOutIn);
newObjFlows.add(objFlow);
}
}
}
rs.removeRule(i2);
rs.removeRule(i1);
rs.addRule(cr.getRule());
for (int l=0; l<newObjFlows.size(); l++) {
rs.addObjFlow(newObjFlows.get(l));
}
rs.tryCompleteObjFlowTransClosure();
// RuleSequence.printObjFlow(rs);
size = rs.getSize();
}
}
if (cr != null && rs.getSize() == 1 && cr.getRule() == rs.getRule(0)) {
List<ObjectFlow> gOF = rs.getObjFlowFromGraph();
if (gOF != null) {
Match m = this.createMatch(cr.getRule(), rs.getGraph());
cr.getRule().setMatch(m);
for (int i=0; i<gOF.size(); i++) {
ObjectFlow of = gOF.get(i);
List<Object> inpts = of.getInputs();
for (int j=0; j<inpts.size(); j++) {
GraphObject go = (GraphObject) inpts.get(j);
if (go.isNode() && go.getContext() == cr.getRule().getLeft()) {
try {
m.addMapping(go, (GraphObject)of.getOutput(go));
} catch (BadMappingException ex) {}
}
}
inpts = of.getInputs();
for (int j=0; j<inpts.size(); j++) {
GraphObject go = (GraphObject) inpts.get(j);
if (go.isArc() && go.getContext() == cr.getRule().getLeft()) {
try {
m.addMapping(go, (GraphObject)of.getOutput(go));
} catch (BadMappingException ex) {}
}
}
}
}
cr.usedM = cr.usedM + freeM - Runtime.getRuntime().freeMemory();
}
return cr;
}
public List<ConcurrentRule> makeConcurrentRuleOfRuleSeqForward(
final RuleSequence sequence,
final GraGra gra,
boolean completeConcurrency) {
RuleSequence rs = sequence.getCopy();
ApplicabilityChecker applChecker = new ApplicabilityChecker(rs, gra);
applChecker.setCompleteConcurrency(completeConcurrency);
List<ConcurrentRule> crs = applChecker.buildPlainConcurrentRule(rs.getRules(), null);
for (int i=0; i < crs.size(); i++) {
ConcurrentRule concurrentRule = crs.get(i);
Rule r = concurrentRule.getRule();
checkAttrContext(r);
}
return crs;
}
private void checkAttrContext(Rule r) {
VarTuple vars = (VarTuple) r.getAttrContext().getVariables();
Iterator<Node> nodes = r.getRight().getNodesSet().iterator();
while (nodes.hasNext()) {
Node n = nodes.next();
if (n.getAttribute() != null) {
ValueTuple vt = (ValueTuple) n.getAttribute();
for (int i=0; i<vt.getNumberOfEntries(); i++) {
ValueMember vm = (ValueMember) vt.getMemberAt(i);
if (vm.isSet() && vm.getExpr().isVariable()) {
VarMember v = (VarMember) vars.getMemberAt(vm.getExprAsText());
if (v != null) {
String errm = vm.getErrorMsg();
if (!errm.isEmpty()) {
vm.removeErrorMsg();
vm.setExprAsText(v.getName());
}
}
}
}
}
}
}
private String replaceEmptyAttrByVariable(final VarTuple vars,
final Iterator<?> e,
final OrdinaryMorphism morph) {
String exprMsg = "";
while (e.hasNext()) {
GraphObject grob = (GraphObject) e.next();
if (grob.getAttribute() == null)
continue;
if (!morph.getInverseImage(grob).hasMoreElements()) {
ValueTuple value = (ValueTuple) grob.getAttribute();
for (int i = 0; i < value.getSize(); i++) {
ValueMember val = value.getValueMemberAt(i);
if (!val.isSet()) {
exprMsg = "attribute member: ".concat(val.getName());
String varname = "r" + i;
vars.declare(DefaultInformationFacade.self()
.getJavaHandler(), val.getDeclaration()
.getTypeName(), varname);
val.setExprAsText(varname);
val.setTransient(true);
vars.getEntryAt(varname).setTransient(true);
exprMsg = exprMsg.concat(" set by a new variable: ").concat(varname).concat(" ; ");
} else if (val.getExpr().isVariable()) {
if (vars.getVarMemberAt(val.getExprAsText()) == null) {
String varname = val.getExprAsText();
vars.declare(DefaultInformationFacade.self()
.getJavaHandler(), val.getDeclaration()
.getTypeName(), varname);
vars.getEntryAt(varname).setTransient(true);
}
}
}
}
}
return exprMsg;
}
public void replaceTransientTarVarBySrcVar(final OrdinaryMorphism morph) {
replaceTransTarVarBySrcVar(morph.getTarget().getNodesCollection().iterator(),
morph,
(VarTuple)morph.getAttrContext().getVariables());
replaceTransTarVarBySrcVar(morph.getTarget().getArcsCollection().iterator(),
morph,
(VarTuple)morph.getAttrContext().getVariables());
}
private void replaceTransTarVarBySrcVar(
final Iterator<?> e,
final OrdinaryMorphism morph,
final VarTuple vars) {
while (e.hasNext()) {
GraphObject tar = (GraphObject) e.next();
if (!tar.attrExists())
continue;
if (morph.getInverseImage(tar).hasMoreElements()) {
GraphObject src = morph.getInverseImage(tar).nextElement();
if (!src.attrExists())
continue;
ValueTuple srcVal = (ValueTuple) src.getAttribute();
ValueTuple tarVal = (ValueTuple) tar.getAttribute();
for (int i = 0; i < tarVal.getSize(); i++) {
ValueMember tarM = tarVal.getValueMemberAt(i);
if (tarM.isSet() && tarM.isTransient()) {
ValueMember srcM = srcVal.getValueMemberAt(tarM.getName());
if (srcM != null && srcM.isSet()
&& srcM.getExpr().isVariable()) {
VarMember v = vars.getVarMemberAt(srcM.getExprAsText());
if (v != null && !v.isTransient()) {
tarM.setExprAsText(v.getName());
tarM.setTransient(false);
}
}
}
}
}
}
}
public void reflectInputParameter(Rule r, Rule absInvertRule) {
VarTuple varsOfInvertRule = (VarTuple) absInvertRule.getAttrContext().getVariables();
VarTuple vars = (VarTuple) r.getAttrContext().getVariables();
for (int i=0; i<vars.getNumberOfEntries(); i++) {
VarMember vm = vars.getVarMemberAt(i);
if (vm.isInputParameter()) {
VarMember vmOfInvertRule = varsOfInvertRule.getVarMemberAt(vm.getName());
if (vmOfInvertRule != null)
vmOfInvertRule.setInputParameter(true);
}
}
}
private void convertAttrConditionLeft2Right(Rule r, Rule inverseR) {
CondTuple conds = (CondTuple) r.getAttrContext().getConditions();
if (conds.isEmpty())
return;
CondTuple condsOfInverseR = (CondTuple) inverseR.getAttrContext().getConditions();
for (int i=0; i<conds.getNumberOfEntries(); i++) {
CondMember cond = conds.getCondMemberAt(i);
// Vector<String> condVars = cond.getAllVariables();
condsOfInverseR.addCondition(cond.getExprAsText());
}
}
/*
private void convertAttrConditionFromLeft2Right(Rule r, Rule inverseR) {
CondTuple conds = (CondTuple) r.getAttrContext().getConditions();
if (conds.isEmpty())
return;
VarTuple vars = (VarTuple) r.getAttrContext().getVariables();
CondTuple condsOfInverseR = (CondTuple) inverseR.getAttrContext().getConditions();
VarTuple varsOfInverseR = (VarTuple) inverseR.getAttrContext().getVariables();
Hashtable<VarMember, Boolean>
varLeftRight = new Hashtable<VarMember, Boolean>();
for (int i=0; i<vars.getNumberOfEntries(); i++) {
VarMember var = vars.getVarMemberAt(i);
if (var.getMark() == VarMember.LHS) {
if (variableUsed(var, r.getLeft()) ){
VarMember varInverse = varsOfInverseR.getVarMemberAt(var.getName());
if (variableUsed(var, r.getRight())) {
varLeftRight.put(var, Boolean.valueOf(true));
varInverse.setMark(VarMember.LHS);
}
else {
varLeftRight.put(var, Boolean.valueOf(false));
varInverse.setMark(VarMember.RHS);
}
}
}
}
for (int i=0; i<conds.getNumberOfEntries(); i++) {
CondMember cond = conds.getCondMemberAt(i);
Vector<String> condVars = cond.getAllVariables();
boolean varsOK = true;
for (int j=0; j<condVars.size(); j++) {
String varN = condVars.get(j);
VarMember var = vars.getVarMemberAt(varN);
if (var.getMark() == VarMember.LHS) {
if (!varLeftRight.get(var).booleanValue())
varsOK = false;
}
}
if (varsOK) {
condsOfInverseR.addCondition(cond.getExprAsText());
}
}
}
private boolean variableUsed(VarMember var, Graph g) {
return varUsed(var, g.getNodesSet().iterator())
|| varUsed(var, g.getArcsSet().iterator());
}
private boolean varUsed(VarMember var, Iterator<?> elems) {
while (elems.hasNext()) {
GraphObject obj = (GraphObject)elems.next();
if (obj.getAttribute() == null)
continue;
ValueTuple val = (ValueTuple) obj.getAttribute();
for (int i = 0; i < val.getSize(); i++) {
ValueMember vm = val.getValueMemberAt(i);
if (vm.isSet() && vm.getExpr().isVariable()) {
if (vm.getExprAsText().equals(var.getName()))
return true;
}
}
}
return false;
}
*/
public Pair<OrdinaryMorphism, OrdinaryMorphism> extendRightGraphByNAC(
final Rule r,
final OrdinaryMorphism nacL) {
OrdinaryMorphism isoLHS = r.getLeft().isomorphicCopy();
if (isoLHS == null) {
return null;
}
// extLeft: L -> Lcopy
OrdinaryMorphism extLeft = extendTargetGraph1ByTargetGraph2(isoLHS, nacL);
if (extLeft == null)
return null;
Graph extLeftGraph = extLeft.getTarget();
Match m = (BaseFactory.theFactory()).createMatch(r, extLeftGraph, true, "1");
// extLeftGraph is the graph m.getTarget()
m.getTarget().setCompleteGraph(false);
// m.setCompletionStrategy(new Completion_InjCSP(), true);
// set match mapping
Iterator<Node> lhsNodes = r.getLeft().getNodesSet().iterator();
while (lhsNodes.hasNext()) {
Node n = lhsNodes.next();
Node img = (Node) isoLHS.getImage(n);
if (img != null) {
try {
m.addMapping(n, img);
} catch (BadMappingException ex) {
System.out.println("BaseFactory.extendRightGraphByNAC: "+n+" "+ex);
return null;
}
}
}
Iterator<Arc> lhsArcs = r.getLeft().getArcsSet().iterator();
while (lhsArcs.hasNext()) {
Arc a = lhsArcs.next();
Arc img = (Arc) isoLHS.getImage(a);
if (img != null) {
try {
m.addMapping(a, img);
} catch (BadMappingException ex) {
System.out.println("extendRightGraphByNAC: "+a+" "+ex);
return null;
}
}
}
if (m.isTotal()) {
if (!m.isDanglingSatisfied()) {
System.out.println("extendRightGraphByNAC: isDanglingConditionSatisfied FAILED!");
return null;
}
// final TestStep s = new TestStep();
try {
OrdinaryMorphism R2R_NAC = (OrdinaryMorphism) TestStep.execute(m, true);
R2R_NAC.setName("RHS_"+nacL.getName());
// System.out.println("extendRightGraphByNAC: right NAC: "+nacR.getTarget());
return new Pair<OrdinaryMorphism, OrdinaryMorphism>(R2R_NAC, extLeft);
} catch (TypeException tex) {
System.out.println("extendRightGraphByNAC: s.execute: "+tex);
return null;
}
}
System.out.println("extendRightGraphByNAC: m is NOT TOTAL! FAILED!");
return null;
}
private void convertNACsLeft2Right(
final Rule r,
final Rule inverseRule,
final OrdinaryMorphism isoRHS) {
final List<OrdinaryMorphism> nacs = r.getNACsList();
for(int i=0; i<nacs.size(); i++) {
OrdinaryMorphism acL = nacs.get(i);OrdinaryMorphism acR = null;
if (r.isACShiftPossible(acL)) {
int tglevelcheck = r.getTypeSet().getLevelOfTypeGraphCheck();
r.getTypeSet().setLevelOfTypeGraph(TypeSet.ENABLED);
acR = convertACLeft2Right(r, acL);
if (acR != null) {
r.getTypeSet().setLevelOfTypeGraph(tglevelcheck);
Collection<TypeError> error = r.getTypeSet().checkType(acR.getTarget());
if (error != null && !error.isEmpty()) {
acR.dispose(false, true);
acR = null;
}
}
}
boolean ok = false;
if (acR != null) {
OrdinaryMorphism ac = BaseFactory.theFactory().createMorphism(
inverseRule.getLeft(),
acR.getTarget());
ok = acR.completeDiagram(isoRHS, ac);
if (ok) {
if (!ac.isRightTotal()
|| !ac.doesIgnoreAttrs()) {
this.unsetAllTransientAttrValues(ac);
// set and adjust attr context
ac.setAttrContext(inverseRule.getLeft().getAttrContext());
this.declareVariable(ac.getTarget(), (VarTuple)inverseRule.getAttrContext().getVariables());
adjustAttributeValueAlongMorphismMapping(ac);
ac.setName(acR.getName());
ac.setEnabled(acL.isEnabled());
inverseRule.addNAC(ac);
}
}
}
if (!ok) {
String warning = inverseRule.getErrorMsg();
String warning1 = "NAC: ".concat(acL.getName()).concat(" could not be converted");
warning = warning.concat(warning1).concat(" ; ");
inverseRule.setErrorMsg(warning);
}
}
}
private boolean convertNACsLeft2Right(
final Rule r,
final Rule inverseRule,
final Hashtable<GraphObject,GraphObject> isoRight) {
final List<OrdinaryMorphism> acs = r.getNACsList();
for(int i=0; i<acs.size(); i++) {
OrdinaryMorphism acL = acs.get(i);
OrdinaryMorphism acR = null;
if (r.isACShiftPossible(acL)) {
int tglevelcheck = r.getTypeSet().getLevelOfTypeGraphCheck();
r.getTypeSet().setLevelOfTypeGraph(TypeSet.ENABLED);
acR = convertACLeft2Right(r, acL);
r.getTypeSet().setLevelOfTypeGraph(tglevelcheck);
Collection<TypeError> error = r.getTypeSet().checkType(acR.getTarget());
if (error != null && !error.isEmpty()) {
acR.dispose(false, true);
acR = null;
}
}
boolean ok = false;
if (acR != null) {
OrdinaryMorphism ac = BaseFactory.theFactory().createMorphism(
inverseRule.getLeft(),
acR.getTarget());
ok = ac.completeDiagram(isoRight, acR);
if (ok){
if (!ac.isRightTotal()
|| !ac.doesIgnoreAttrs()) {
this.unsetAllTransientAttrValues(ac);
// set and adjust attr context
ac.setAttrContext(inverseRule.getLeft().getAttrContext());
this.declareVariable(ac.getTarget(), (VarTuple)inverseRule.getAttrContext().getVariables());
adjustAttributeValueAlongMorphismMapping(ac);
ac.setEnabled(acL.isEnabled());
ac.setName(acR.getName());
inverseRule.addNAC(ac);
}
}
}
if (!ok) {
String warning = inverseRule.getErrorMsg();
String warning1 = "NAC: ".concat(acL.getName()).concat(" could not be shifted from left to right");
warning = warning.concat(warning1).concat(" ; ");
inverseRule.setErrorMsg(warning);
}
}
return true;
}
private boolean convertRuleGACsLeft2Right(
final Rule r,
final Rule inverseRule,
final OrdinaryMorphism isoRight) {
boolean failed = false;
// Vector<OrdinaryMorphism> racs = new Vector<OrdinaryMorphism>();
final List<OrdinaryMorphism> acs = r.getNestedACsList();
for(int i=0; i<acs.size() && !failed; i++) {
NestedApplCond acL = (NestedApplCond)acs.get(i);
OrdinaryMorphism acR = null;
Pair<OrdinaryMorphism,OrdinaryMorphism> pairPO = null;
if (r.isACShiftPossible(acL)) {
int tglevelcheck = r.getTypeSet().getLevelOfTypeGraphCheck();
r.getTypeSet().setLevelOfTypeGraph(TypeSet.ENABLED);
pairPO = convertNestedACLeft2Right(r, acL);
r.getTypeSet().setLevelOfTypeGraph(tglevelcheck);
if (pairPO != null) {
acR = pairPO.second;
Collection<TypeError> error = r.getTypeSet().checkType(acR.getTarget());
if (error != null && !error.isEmpty()) {
acR.dispose(false, true);
acR = null;
}
}
}
if (acR != null) {
NestedApplCond ac = new NestedApplCond(inverseRule.getLeft(), acR.getTarget(),
inverseRule.getRight().getAttrContext());
ac.completeDiagram2(isoRight, acR);
this.unsetAllTransientAttrValues(ac);
// set and adjust attr context
ac.getTarget().setAttrContext(ac.getAttrContext());
this.declareVariable(ac.getTarget(), (VarTuple)inverseRule.getAttrContext().getVariables());
adjustAttributeValueAlongMorphismMapping(ac);
ac.setName(acL.getName());
// racs.add(ac);
inverseRule.addNestedAC(ac);
if (!acL.getNestedACs().isEmpty()) {
if (!convertNestedACsLeft2Right(pairPO.first, acL, acR, ac, inverseRule)) {
//TODO check formula: replace !ac by TRUE, otherwise formula invalid ???
//
}
}
}
else {
//TODO check formula: replace !ac by TRUE, otherwise formula invalid ???
//
String warning = inverseRule.getErrorMsg();
String warning1 = "General AC: ".concat(acL.getName()).concat(" could not be converted");
warning = warning.concat(warning1).concat(" ; ");
inverseRule.setErrorMsg(warning);
failed = true;
}
}
if (!failed) {
// for (int i=0; i<racs.size(); i++) {
// inverseRule.addNestedAC(racs.get(i));
// }
inverseRule.setFormula(r.getFormulaStr());
}
// else {
// for (int i=0; i<racs.size(); i++) {
// ((NestedApplCond)racs.get(i)).dispose();
// inverseRule.addNestedAC(racs.get(i));
// }
// }
// racs.clear(); racs = null;
return !failed;
}
private boolean convertGACsLeft2Right(
final Rule r,
final Rule inverseRule,
final Hashtable<GraphObject,GraphObject> isoRight) {
boolean failed = false;
// Vector<OrdinaryMorphism> racs = new Vector<OrdinaryMorphism>();
final List<OrdinaryMorphism> acs = r.getNestedACsList();
for(int i=0; i<acs.size() && !failed; i++) {
NestedApplCond acL = (NestedApplCond)acs.get(i);
OrdinaryMorphism acR = null;
Pair<OrdinaryMorphism,OrdinaryMorphism> pairPO = convertNestedACLeft2Right(r, acL);
if (pairPO != null) {
acR = pairPO.second;
NestedApplCond ac = new NestedApplCond(inverseRule.getLeft(), acR.getTarget(),
agg.attribute.impl.AttrTupleManager
.getDefaultManager().newContext(AttrMapping.PLAIN_MAP));
ac.completeDiagram(isoRight, acR);
this.unsetAllTransientAttrValues(ac);
// set and adjust attr context
ac.setAttrContext(inverseRule.getLeft().getAttrContext());
this.declareVariable(ac.getTarget(), (VarTuple)inverseRule.getAttrContext().getVariables());
adjustAttributeValueAlongMorphismMapping(ac);
ac.setName(acL.getName());
// racs.add(ac);
inverseRule.addNestedAC(ac);
if (!acL.getNestedACs().isEmpty()) {
if (!convertNestedACsLeft2Right(pairPO.first, acL, acR, ac, inverseRule)) {
//TODO check formula: replace !ac by TRUE, otherwise formula invalid ???
//
}
}
}
else {
//TODO check formula: replace !ac by TRUE, otherwise formula invalid ???
//
String warning = inverseRule.getErrorMsg();
String warning1 = "General AC: ".concat(acL.getName()).concat(" could not be converted");
warning = warning.concat(warning1).concat(" ; ");
inverseRule.setErrorMsg(warning);
failed = true;
}
}
if (!failed) {
// for (int i=0; i<racs.size(); i++) {
// inverseRule.addNestedAC(racs.get(i));
// }
inverseRule.setFormula(r.getFormulaStr());
}
// else {
// for (int i=0; i<racs.size(); i++) {
//// ((NestedApplCond)racs.get(i)).dispose();
// inverseRule.addNestedAC(racs.get(i));
// }
// }
// racs.clear(); racs = null;
return !failed;
}
private boolean convertNestedACsLeft2Right(
final OrdinaryMorphism rm,
final NestedApplCond acL,
final OrdinaryMorphism acR,
final NestedApplCond ac,
final Rule inverseRule) {
boolean failed = false;
// Vector<OrdinaryMorphism> racs = new Vector<OrdinaryMorphism>();
for (int i=0; i<acL.getNestedACs().size() /*&& !failed*/; i++) {
NestedApplCond ncL = acL.getNestedACs().get(i);
Pair<OrdinaryMorphism,OrdinaryMorphism>
pairPO = convertNestedACLeft2Right(rm, ncL);
if (pairPO != null) {
OrdinaryMorphism ncR = pairPO.second;
NestedApplCond nc = new NestedApplCond(ncR.getSource(), ncR.getTarget(), ncR.getAttrContext());
nc.getDomainObjects().addAll(ncR.getDomainObjects());
nc.getCodomainObjects().addAll(ncR.getCodomainObjects());
this.unsetAllTransientAttrValues(nc);
// set and adjust attr context
nc.getTarget().setAttrContext(nc.getAttrContext());
this.declareVariable(nc.getTarget(), (VarTuple)ncL.getAttrContext().getVariables());
adjustAttributeValueAlongMorphismMapping(nc);
nc.setName(ncL.getName());
// racs.add(nc);
ac.addNestedAC(nc);
if (!ncL.getNestedACs().isEmpty()) {
if (!convertNestedACsLeft2Right(pairPO.first, ncL, ncR, nc, inverseRule)) {
//TODO check formula: replace ac by FALSE ???
}
}
} else {
//TODO check formula: replace ac by FALSE ???
//
String warning = inverseRule.getErrorMsg();
String warning1 = "Nested AC: ".concat(acL.getName()).concat(" could not be converted");
warning = warning.concat(warning1).concat(" ; ");
inverseRule.setErrorMsg(warning);
failed = true;
}
}
if (!failed) {
// for (int i=0; i<racs.size(); i++) {
// ac.addNestedAC((NestedApplCond)racs.get(i));
// }
ac.setFormula(acL.getFormulaStr());
}
// else {
// for (int i=0; i<racs.size(); i++) {
//// ((NestedApplCond)racs.get(i)).dispose();
// ac.addNestedAC((NestedApplCond)racs.get(i));
// }
// }
// racs.clear(); racs = null;
return !failed;
}
public Pair<OrdinaryMorphism,OrdinaryMorphism> convertNestedACLeft2Right(
final OrdinaryMorphism rm,
final NestedApplCond ncL) {
OrdinaryMorphism ncR = null;
OrdinaryMorphism extLeft = null;
OrdinaryMorphism ncL1 = null;
Pair<OrdinaryMorphism,OrdinaryMorphism> pairPO = null;
boolean needHelp = !ncL.isTotal();
if (needHelp) {
ncL1 = rm.getSource().isomorphicCopy();
if (ncL1 == null) {
return null;
}
// extLeft: acL -> (L+acL)
extLeft = extendTargetGraph1ByTargetGraph2(ncL1, ncL);
if (extLeft == null) {
ncL1.dispose();
return null;
}
if (ncL1.isTotal()) {
if (rm instanceof Rule) {
if (this.isDanglingSatisfied(ncL1, rm))
pairPO = this.makePO(rm, ncL1, true, false);
// else
// System.out.println("########## "+this.getClass().getName()+" convert nested AC:: Dangling FAILED");
}
else
pairPO = this.makePO(rm, ncL1, true, false);
}
}
else {
if (rm instanceof Rule) {
if (this.isDanglingSatisfied(ncL, rm))
pairPO = this.makePO(rm, ncL, true, false);
// else
// System.out.println("########## "+this.getClass().getName()+" convert nested AC:: Dangling FAILED");
}
else
pairPO = this.makePO(rm, ncL, true, false);
}
if (pairPO != null) {
OrdinaryMorphism rStar = null;
if (needHelp) {
ncR = pairPO.second;
rStar = extLeft.compose(pairPO.first);
if (rStar != null && filterObjectsOfRightCondition(rm, ncL, ncR)) {
return new Pair<OrdinaryMorphism,OrdinaryMorphism> (rStar, ncR);
}
} else {
return pairPO;
}
}
return null;
}
private boolean convertPACsLeft2Right(
final Rule r,
final Rule inverseRule,
final Hashtable<GraphObject,GraphObject> isoRight) {
final List<OrdinaryMorphism> acs = r.getPACsList();
for(int i=0; i<acs.size(); i++) {
OrdinaryMorphism acL = acs.get(i);
OrdinaryMorphism acR = null;
if (r.isACShiftPossible(acL)) {
int tglevelcheck = r.getTypeSet().getLevelOfTypeGraphCheck();
r.getTypeSet().setLevelOfTypeGraph(TypeSet.ENABLED);
acR = convertACLeft2Right(r, acL);
r.getTypeSet().setLevelOfTypeGraph(tglevelcheck);
Collection<TypeError> error = r.getTypeSet().checkType(acR.getTarget());
if (error != null && !error.isEmpty()) {
acR.dispose(false, true);
acR = null;
}
}
boolean ok = false;
if (acR != null) {
OrdinaryMorphism ac = BaseFactory.theFactory().createMorphism(
inverseRule.getLeft(),
acR.getTarget());
ok = ac.completeDiagram(isoRight, acR);
if (ok) {
if (!ac.isRightTotal()
|| !ac.doesIgnoreAttrs()) {
this.unsetAllTransientAttrValues(ac);
// set and adjust attr context
ac.setAttrContext(inverseRule.getLeft().getAttrContext());
this.declareVariable(ac.getTarget(), (VarTuple)inverseRule.getAttrContext().getVariables());
adjustAttributeValueAlongMorphismMapping(ac);
ac.setEnabled(acL.isEnabled());
ac.setName(acR.getName());
inverseRule.addPAC(ac);
}
}
}
if (!ok) {
String warning = inverseRule.getErrorMsg();
String warning1 = "AC: ".concat(acL.getName()).concat(" could not be converted");
warning = warning.concat(warning1).concat(" ; ");
inverseRule.setErrorMsg(warning);
return false;
}
}
return true;
}
public void adjustAttributeValueAlongMorphismMapping(
final OrdinaryMorphism morph) {
final Enumeration<GraphObject> dom = morph.getDomain();
while (dom.hasMoreElements()) {
GraphObject obj = dom.nextElement();
if (obj.getAttribute() != null) {
GraphObject img = morph.getImage(obj);
if (img.getAttribute() != null) {
ValueTuple vt_obj = (ValueTuple) obj.getAttribute();
ValueTuple vt_img = (ValueTuple) img.getAttribute();
for (int i=0; i<vt_obj.getNumberOfEntries(); i++) {
ValueMember vm_obj = vt_obj.getValueMemberAt(i);
ValueMember vm_img = vt_img.getValueMemberAt(vm_obj.getName());
if (vm_obj.isSet()
&& vm_img != null
&& vm_img.isSet()
&& !vm_img.getExprAsText().equals(vm_obj.getExprAsText())) {
vm_img.setExprAsText(vm_obj.getExprAsText());
}
}
}
}
}
}
private OrdinaryMorphism convertACLeft2Right(
final Rule r,
final OrdinaryMorphism acL) {
// isoLHS: L -> Lcopy
final OrdinaryMorphism isoLHS = r.getLeft().isomorphicCopy();
if (isoLHS == null) {
return null;
}
// extLeft: acL -> (Lcopy+acL)
final OrdinaryMorphism extLeft = extendTargetGraph1ByTargetGraph2(isoLHS, acL);
if (extLeft == null) {
isoLHS.dispose();
return null;
}
boolean ok = false;
OrdinaryMorphism acR = null;
final Match m = (BaseFactory.theFactory()).createMatch(r, extLeft.getTarget(), true, "1");
// extLeftGraph == m.getTarget()
m.getTarget().setCompleteGraph(false);
m.setCompletionStrategy(new Completion_InjCSP(), true);
if (this.setMappingAlongMorphism(m, isoLHS)
&& m.isTotal()
&& this.isDanglingSatisfied(m, r)) {
try {
int levelOfTypeGraphCheck = r.getTypeSet().getLevelOfTypeGraphCheck();
r.getTypeSet().setLevelOfTypeGraph(TypeSet.ENABLED);
// apply rule to extend the graph (LHS+AC) by objects of the RHS
acR = (OrdinaryMorphism) TestStep.execute(m, true);
// now the extended graph (RHS+AC)
r.getTypeSet().setLevelOfTypeGraph(levelOfTypeGraphCheck);
// adjust usage of variables in the attributes of acR
adjustVariablesInAttributeOfRightRuleCondition(r, acL, acR);
// prepare right AC graph :
// delete objects to be created
// or without a mapping from its preimage into the acL
ok = filterObjectsOfRightCondition(r, acL, acR);
if (ok) {
acR.setName(acL.getName());
} else {
acR.dispose();
}
} catch (TypeException tex) {}
}
r.setMatch(null);
extLeft.dispose();
isoLHS.dispose();
return acR;
}
public boolean isDanglingSatisfied(final OrdinaryMorphism m, final OrdinaryMorphism rm) {
final Iterator<Node> objects = rm.getSource().getNodesSet().iterator();
while (objects.hasNext()) {
final Node x = objects.next();
if (rm.getImage(x) == null) {
final Node y = (Node) m.getImage(x);
if (y != null
&& x.getNumberOfArcs() != y.getNumberOfArcs()) {
System.out.println("BF.isDanglingSatisfied:: "+rm.getName()+" x: "+x+" != y: "+y);
return false;
}
}
}
return true;
}
/**
* Given a complete morphism g: A->B with the plain morphism context of object mapping and <br>
* an empty morphism f: A->B with the Match context of object mapping.<br>
* Try to set mappings of f along g.
* @param f
* @param g
*/
private boolean setMappingAlongMorphism(
final OrdinaryMorphism f,
final OrdinaryMorphism g) {
// set match mapping
final Iterator<Node> nodes = g.getSource().getNodesSet().iterator();
while (nodes.hasNext()) {
Node n = nodes.next();
Node img = (Node) g.getImage(n);
if (img != null) {
try {
if (n.getType().isParentOf(img.getType())) {
f.addMapping(n, img);
}
else if (n.getType().isChildOf(img.getType())){
f.addChild2ParentMapping(n, img);
}
} catch (BadMappingException ex) {
return false;
}
}
}
final Iterator<Arc> arcs = g.getSource().getArcsSet().iterator();
while (arcs.hasNext()) {
Arc a = arcs.next();
Arc img = (Arc) g.getImage(a);
if (img != null) {
try {
f.addMapping(a, img);
} catch (BadMappingException ex) {
return false;
}
}
}
return true;
}
private void adjustVariablesInAttributeOfRightRuleCondition(
final Rule r,
final OrdinaryMorphism condL,
final OrdinaryMorphism condR) {
// adjust usage of variables in the attributes of nacR
final Enumeration<GraphObject> nacLCoDom = condL.getCodomain();
while (nacLCoDom.hasMoreElements()) {
GraphObject condObj = nacLCoDom.nextElement();
if (condObj.getAttribute() != null) {
GraphObject lhsObj = condL.getInverseImage(condObj).nextElement();
GraphObject rhsObj = r.getImage(lhsObj);
if (rhsObj != null) {
GraphObject condRObj = condR.getImage(rhsObj);
if (condRObj != null) {
ValueTuple lhsVal = (ValueTuple)lhsObj.getAttribute();
ValueTuple condLVal = (ValueTuple)condObj.getAttribute();
ValueTuple rhsVal = (ValueTuple)rhsObj.getAttribute();
ValueTuple condRVal = (ValueTuple)condRObj.getAttribute();
for (int i=0; i<lhsVal.getNumberOfEntries(); i++) {
ValueMember vm = lhsVal.getEntryAt(i);
if (vm.isSet()) {
ValueMember vmcondL = condLVal.getEntryAt(vm.getName());
ValueMember vmcondR = condRVal.getEntryAt(vm.getName());
if (vmcondL.isSet()) {
if (vm.getExprAsText().equals(vmcondL.getExprAsText())) {
ValueMember vmRHS = rhsVal.getEntryAt(vm.getName());
if (vmRHS.isSet() && vmcondR != null) {
vmcondR.setExprAsText(vmRHS.getExprAsText());
}
}
} else {
if (vmcondR != null && vmcondR.isSet()) {
vmcondR.setExpr(null);
}
}
}
}
}
}
}
}
}
private boolean filterObjectsOfRightCondition(
final OrdinaryMorphism r,
final OrdinaryMorphism condL,
final OrdinaryMorphism condR) {
boolean ok = true;
// delete arc to be created
// or without a mapping from its preimage into the condL
final Iterator<Arc> rhsArcs = r.getTarget().getArcsSet().iterator();
while (rhsArcs.hasNext() && ok) {
Arc a = rhsArcs.next();
Arc aImg = (Arc) condR.getImage(a);
if (!r.getInverseImage(a).hasMoreElements()
|| (condL.getImage(r.getInverseImage(a).nextElement()) == null)) {
try {
condR.getTarget().destroyArc(aImg, false, false);
} catch (TypeException tex) {
ok = false;
}
}
}
// delete node to be created
// or without a mapping from its pre-image into the condL
final Iterator<Node> rhsNodes = r.getTarget().getNodesSet().iterator();
while (rhsNodes.hasNext() && ok) {
Node n = rhsNodes.next();
Node nImg = (Node) condR.getImage(n);
if (!r.getInverseImage(n).hasMoreElements()
|| (condL.getImage(r.getInverseImage(n).nextElement()) == null)) {
try {
condR.getTarget().destroyNode(nImg, false, false);
} catch (TypeException tex) {
ok = false;
}
}
}
return ok;
}
protected boolean convertPACsLeft2Right (
final Rule r,
final Rule inverseRule,
final OrdinaryMorphism isoRHS) {
final List<OrdinaryMorphism> pacs = r.getPACsList();
for(int i=0; i<pacs.size(); i++) {
OrdinaryMorphism acL = pacs.get(i);
OrdinaryMorphism acR = null;
if (r.isACShiftPossible(acL)) {
int tglevelcheck = r.getTypeSet().getLevelOfTypeGraphCheck();
r.getTypeSet().setLevelOfTypeGraph(TypeSet.ENABLED);
acR = convertACLeft2Right(r, acL);
r.getTypeSet().setLevelOfTypeGraph(tglevelcheck);
Collection<TypeError> error = r.getTypeSet().checkType(acR.getTarget());
if (error != null && !error.isEmpty()) {
acR.dispose(false, true);
acR = null;
}
}
boolean ok = false;
if (acR != null) {
OrdinaryMorphism ac = BaseFactory.theFactory().createMorphism(
inverseRule.getLeft(),
acR.getTarget());
ok = acR.completeDiagram(isoRHS, ac);
if (ok) {
if (!ac.isRightTotal()
|| !ac.doesIgnoreAttrs()) {
this.unsetAllTransientAttrValues(ac);
// set attr context
ac.setAttrContext(inverseRule.getLeft().getAttrContext());
this.declareVariable(ac.getTarget(), (VarTuple)inverseRule.getAttrContext().getVariables());
adjustAttributeValueAlongMorphismMapping(ac);
ac.setEnabled(acL.isEnabled());
ac.setName(acR.getName());
inverseRule.addPAC(ac);
}
}
}
if (!ok) {
String warning = inverseRule.getErrorMsg();
String warning1 = "PAC: ".concat(acL.getName()).concat(" could not be converted");
warning = warning.concat(warning1).concat(" ; ");
inverseRule.setErrorMsg(warning);
return false;
}
}
return true;
}
/**
* Copies the value (which is not null) of an attribute of the given GraphObject <code>from</code>
* to the value of the corresponding attribute of the given GraphObject <code>to</code>.
*
* @param from
* @param to
*/
private void adjustAttributesFromTo(
final GraphObject from,
final GraphObject to) {
if (to != null
&& from.getAttribute() != null
&& to.getAttribute() != null) {
ValueTuple vt_from = (ValueTuple) from.getAttribute();
ValueTuple vt_to = (ValueTuple) to.getAttribute();
for (int i=0; i<vt_from.getNumberOfEntries(); i++) {
ValueMember vm = vt_from.getValueMemberAt(i);
ValueMember vm_to = vt_to.getValueMemberAt(vm.getName());
if (vm.isSet()
&& vm_to != null) {
vm_to.setExprAsText(vm.getExprAsText());
vm_to.setTransient(vm.isTransient());
// System.out.println("BF.adjustAttributesFromTo:: "+vm_to);
}
}
}
}
private void setEmptyAttrsByDummyHC(final GraphObject go) {
if (go != null && go.getAttribute() != null) {
ValueTuple vt = (ValueTuple) go.getAttribute();
for (int i=0; i<vt.getNumberOfEntries(); i++) {
ValueMember vm = vt.getValueMemberAt(i);
if (!vm.isSet()) {
vm.setExprAsText(String.valueOf(vm.hashCode()));
vm.setTransient(true);
}
}
}
}
public Pair<OrdinaryMorphism, OrdinaryMorphism> extendLeftGraphByNAC(
final Rule r,
final OrdinaryMorphism nac) {
OrdinaryMorphism L2L_NAC = r.getLeft().isomorphicCopy();
if (L2L_NAC == null) {
return null;
}
OrdinaryMorphism NAC2L_NAC = extendTargetGraph1ByTargetGraph2(L2L_NAC, nac);
return new Pair<OrdinaryMorphism, OrdinaryMorphism>(L2L_NAC, NAC2L_NAC);
}
/**
* Creates a new morphism from the target graph of the given morphism morph2
* to the target graph of the given morphism morph1.
* Extends the target graph of the given morphism morph1 by the objects
* of the given morphism morph2 by respecting existing object mappings.
*
* @param morph1
* @param morph2
* @return a new morphism
*/
public OrdinaryMorphism extendTargetGraph1ByTargetGraph2(
final OrdinaryMorphism morph1,
final OrdinaryMorphism morph2) {
if (morph1 == null || morph2 == null)
return null;
Graph extLeft = morph1.getTarget();
OrdinaryMorphism morph = BaseFactory.theFactory().createMorphism(
morph2.getTarget(), extLeft);
((ContextView) morph.getAttrContext()).changeAllowedMapping(AttrMapping.MATCH_MAP);
Hashtable<Node, Node> tmp = new Hashtable<Node, Node>(5);
Iterator<?> e = morph2.getTarget().getNodesSet().iterator();
while (e.hasNext()) {
GraphObject o = (GraphObject) e.next();
if (!morph2.getInverseImage(o).hasMoreElements()) {
try {
Node n = extLeft.copyNode((Node) o);
this.setEmptyAttrsByDummyHC(n);
n.setContextUsage(o.hashCode());
tmp.put((Node) o, n);
try {
morph.addPlainMapping(o, n);
} catch (BadMappingException exc) {
System.out.println("BF.extendTargetGraph1ByTargetGraph2: copyNode: "+exc.getLocalizedMessage());
}
} catch (TypeException ex) {
System.out.println(ex.getLocalizedMessage());
}
} else if (morph1.getImage(morph2.getInverseImage(o).nextElement()) != null) {
Node n = (Node) morph1.getImage(morph2
.getInverseImage(o).nextElement());
n.setContextUsage(o.hashCode());
n.setObjectName(o.getObjectName());
this.adjustAttributesFromTo(o, n);
this.setEmptyAttrsByDummyHC(n);
try {
if (o.getType().isParentOf(n.getType()))
morph.addMapping(o, n);
else if (o.getType().isChildOf(n.getType()))
morph.addChild2ParentMapping(o, n);
} catch (BadMappingException exc) {
System.out.println("BF.extendTargetGraph1ByTargetGraph2: "+exc.getLocalizedMessage());
}
}
}
e = morph2.getTarget().getArcsSet().iterator();
while (e.hasNext()) {
GraphObject o = (GraphObject) e.next();
if (!morph2.getInverseImage(o).hasMoreElements()) {
Node src = tmp.get(((Arc) o).getSource());
if (src == null) {
src = (Node) morph1.getImage(morph2.getInverseImage(
((Arc) o).getSource()).nextElement());
}
Node tar = tmp.get(((Arc) o).getTarget());
if (tar == null) {
tar = (Node) morph1.getImage(morph2.getInverseImage(
((Arc) o).getTarget()).nextElement());
}
try {
Arc a = extLeft.copyArc((Arc) o, src, tar);
this.setEmptyAttrsByDummyHC(a);
a.setContextUsage(o.hashCode());
try {
morph.addPlainMapping(o, a);
} catch (BadMappingException exc) {
System.out.println("BF.extendTargetGraph1ByTargetGraph2: copyArc: "+exc.getLocalizedMessage());
}
} catch (TypeException ex) {}
} else if (morph1.getImage(morph2.getInverseImage(o).nextElement()) != null) {
Arc a = (Arc) morph1.getImage(morph2
.getInverseImage(o).nextElement());
a.setContextUsage(o.hashCode());
a.setObjectName(o.getObjectName());
this.adjustAttributesFromTo(o, a);
this.setEmptyAttrsByDummyHC(a);
try {
morph.addMapping(o, morph1.getImage( morph2
.getInverseImage(o).nextElement()));
} catch (BadMappingException exc) {
System.out.println("BF.extendTargetGraph1ByTargetGraph2: "+exc.getLocalizedMessage());
}
}
}
// replace parent node by a copy of child node when needed
this.replaceParentByChild(morph, morph1);
return morph;
}
public void unsetTransientAttrValue(
final VarTuple vars,
final Iterator<?> elems) {
while (elems.hasNext()) {
GraphObject obj = (GraphObject) elems.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.isTransient())) {
if (valuem.getExpr().isVariable()) {
String tmpname = valuem.getExprAsText();
if (vars.getMemberAt(tmpname) != null)
vars.getTupleType().deleteMemberAt(tmpname);
}
valuem.setExpr(null);
valuem.setTransient(false);
}
}
}
}
public void unsetAllTransientAttrValues(final OrdinaryMorphism morph) {
final VarTuple vars = (VarTuple)morph.getAttrContext().getVariables();
if (morph.getSource().isAttributed()) {
Iterator<?> elems = morph.getSource().getNodesSet().iterator();
unsetTransientAttrValue(vars, elems);
elems = morph.getSource().getArcsSet().iterator();
unsetTransientAttrValue(vars, elems);
}
if (morph.getTarget().isAttributed()) {
Iterator<?> elems1 = morph.getTarget().getNodesSet().iterator();
unsetTransientAttrValue(vars, elems1);
elems1 = morph.getTarget().getArcsSet().iterator();
unsetTransientAttrValue(vars, elems1);
}
}
public void unsetAllTransientAttrValuesOfRule(final Rule r) {
final VarTuple vars = (VarTuple)r.getAttrContext().getVariables();
// LHS and RHS
this.unsetAllTransientAttrValues(r);
// NACs
final List<OrdinaryMorphism> nacs = r.getNACsList();
for(int j=0; j<nacs.size(); j++) {
OrdinaryMorphism nac = nacs.get(j);
if (nac.getTarget().isAttributed()) {
Iterator<?> e1 = nac.getTarget().getNodesSet().iterator();
this.unsetTransientAttrValue(vars, e1);
e1 = nac.getTarget().getArcsSet().iterator();
this.unsetTransientAttrValue(vars, e1);
}
}
// PACs
final List<OrdinaryMorphism> pacs = r.getPACsList();
for(int j=0; j<pacs.size(); j++) {
OrdinaryMorphism pac = pacs.get(j);
if (pac.getTarget().isAttributed()) {
Iterator<?> e1 = pac.getTarget().getNodesSet().iterator();
this.unsetTransientAttrValue(vars, e1);
e1 = pac.getTarget().getArcsSet().iterator();
this.unsetTransientAttrValue(vars, e1);
}
}
}
/** Returns a clone of the graph. */
public Graph cloneGraph(Graph graph) {
return graph.copy();
}
/** Returns a clone of the rule. */
private KernelRule copyKernelRule(
final Rule rule,
final TypeSet types,
final Hashtable<GraphObject, GraphObject> table) {
KernelRule kr = new KernelRule(types);
copyRule(rule, kr, table, true);
kr.setName(rule.getName());
return kr;
}
/** Returns a clone of the rule scheme. */
public RuleScheme cloneRuleScheme(RuleScheme ruleScheme) {
return this.cloneRuleScheme(ruleScheme, ruleScheme.getKernelRule().getTypeSet());
}
/** Returns a clone of the rule scheme. */
public RuleScheme cloneRuleScheme(RuleScheme ruleScheme, TypeSet types) {
final Hashtable<GraphObject, GraphObject> table = new Hashtable<GraphObject, GraphObject>();
RuleScheme rs = new RuleScheme(ruleScheme.getName(),
copyKernelRule(ruleScheme.getKernelRule(), types, table));
for (int i=0; i<ruleScheme.getMultiRules().size(); i++) {
MultiRule mr = (MultiRule) ruleScheme.getMultiRules().get(i);
MultiRule mrule = rs.createMultiRule(mr.getName());
copyMultiRule(mr, mrule, table);
}
rs.setLayer(ruleScheme.getLayer());
rs.setPriority(ruleScheme.getPriority());
rs.setParallelKernelMatch(ruleScheme.parallelKernelMatch());
rs.setCheckDeleteUseConflictRequired(ruleScheme.checkDeleteUseConflictRequired());
rs.setDisjointMultiMatches(ruleScheme.disjointMultiMatches());
rs.setAtLeastOneMultiMatchRequired(ruleScheme.atLeastOneMultiMatchRequired());
table.clear();
return rs;
}
/**
* Creates a rule scheme with a kernel rule as a copy of the specified rule
* and an empty list of multi rules.
* @return RuleScheme or null if creation failed
*/
public RuleScheme makeRuleScheme(final Rule r) {
KernelRule kr = new KernelRule(r.getTypeSet());
if (this.cloneRule(r, kr)) {
kr.setName(r.getName());
final RuleScheme rs = new RuleScheme(kr.getName()+"_RS", kr);
rs.setLayer(r.getLayer());
rs.setPriority(r.getPriority());
return rs;
}
else {
kr.dispose(true, true);
return null;
}
}
private KernelRule reverseKernelRule(
final KernelRule kern,
final Hashtable<GraphObject, GraphObject> table) {
KernelRule invKern = new KernelRule(kern.getTypeSet());
this.reverseMorphismInto(kern, invKern, table);
this.reflectInputParameter(kern, invKern);
// converting PACs from LHS to RHS
if (this.convertPACsLeft2Right(kern, invKern, table)) {
// converting NACs from LHS to RHS
this.convertNACsLeft2Right(kern, invKern, table);
// converting GACs from LHS to RHS
this.convertGACsLeft2Right(kern, invKern, table);
// convert attr conditions
this.convertAttrConditionLeft2Right(kern, invKern);
invKern.setName(kern.getName());
return invKern;
}
invKern = null;
return null;
}
/** Returns an inverse rule scheme of the specified rule scheme. */
public RuleScheme reverseRuleScheme(RuleScheme ruleScheme) {
Hashtable<GraphObject, GraphObject> kernTable = new Hashtable<GraphObject, GraphObject>();
Hashtable<GraphObject, GraphObject> table = new Hashtable<GraphObject, GraphObject>();
// reverte the kernel rule
KernelRule invKern = this.reverseKernelRule((KernelRule)ruleScheme.getKernelRule(), kernTable);
// new rule scheme
if (invKern != null) {
RuleScheme rs = new RuleScheme(ruleScheme.getName().concat("_INV"), invKern);
if (!"".equals(invKern.getErrorMsg())) {
rs.setErrorMsg(invKern.getErrorMsg());
}
if (!invKern.isReadyToTransform()) {
System.out.println(this.getClass().getName()+" "+invKern.getName()+" :: "+invKern.getErrorMsg());
}
for (int i=0; i<ruleScheme.getMultiRules().size(); i++) {
table.putAll(kernTable);
MultiRule multi = (MultiRule) ruleScheme.getMultiRules().get(i);
MultiRule invMulti = rs.createMultiRule(multi.getName());
if (reverseMultiRule(multi, invMulti, table)) {
invMulti.setName(multi.getName());
if (!"".equals(invMulti.getErrorMsg())) {
rs.setErrorMsg(rs.getErrorMsg().concat(" ; ").concat(invMulti.getErrorMsg()));
}
if (!invMulti.isReadyToTransform()) {
System.out.println(this.getClass().getName()+" "+invMulti.getName()+" :: "+invMulti.getErrorMsg());
}
} else {
ruleScheme.getMultiRules().remove(i);
i--;
invMulti = null;
//TODO was ist in diesem Fall mit inverse RuleScheme??
}
table.clear();
}
rs.setLayer(ruleScheme.getLayer());
rs.setPriority(ruleScheme.getPriority());
rs.setParallelKernelMatch(ruleScheme.parallelKernelMatch());
rs.setCheckDeleteUseConflictRequired(ruleScheme.checkDeleteUseConflictRequired());
rs.setDisjointMultiMatches(ruleScheme.disjointMultiMatches());
rs.setAtLeastOneMultiMatchRequired(ruleScheme.atLeastOneMultiMatchRequired());
kernTable.clear();
kernTable = null;
table = null;
return rs;
}
kernTable.clear();
kernTable = null;
table.clear();
table = null;
return null;
}
/**
* Makes the minimal rule from the given rule.
* A minimal rule comprises the effects of a given rule in a minimal context.
*/
public Rule makeMinimalOfRule(Rule r) {
Rule minRule = new Rule(r.getOriginal().getTypeSet());
final Hashtable<GraphObject, GraphObject> table = new Hashtable<GraphObject, GraphObject>();
copyRule(r, minRule, table, false);
minRule.setLayer(r.getLayer());
minRule.setPriority(r.getPriority());
table.clear();
// remove preserved unchanged objects from LHS and RHS
removePreservedUnchangedObjs(minRule);
return minRule;
}
/**
* Returns true if at least one object ia removed.
*/
public boolean removePreservedUnchangedObjs(final Rule r) {
boolean removed = false;
Vector<GraphObject> del = new Vector<GraphObject>();
// remove preserved unchanged objects from LHS and RHS
Enumeration<GraphObject> dom = r.getDomain();
while (dom.hasMoreElements()) {
GraphObject obj = dom.nextElement();
GraphObject img = r.getImage(obj);
if (obj.isArc()
&& ((obj.getAttribute() == null && img.getAttribute() == null)
|| (obj.getAttribute() != null
&& img.getAttribute() != null
&& obj.getAttribute().compareTo(img.getAttribute())))) {
del.add(obj);
del.add(img);
}
}
for (int i=0; i<del.size()-1; i=i+2) {
GraphObject obj = del.get(i);
GraphObject img = del.get(i+1);
if (obj.isArc()) {
r.removeMapping((Arc)obj, (Arc)img);
try {
r.getLeft().destroyArc((Arc)obj);
r.getRight().destroyArc((Arc)img);
removed = true;
} catch (TypeException ex) {}
}
}
del.clear();
dom = r.getDomain();
while (dom.hasMoreElements()) {
GraphObject obj = dom.nextElement();
GraphObject img = r.getImage(obj);
if (obj.isNode()
&& ((Node)obj).getNumberOfArcs() == 0
&& ((Node)img).getNumberOfArcs() == 0
&& ((obj.getAttribute() == null && img.getAttribute() == null)
|| (obj.getAttribute() != null
&& img.getAttribute() != null
&& obj.getAttribute().compareTo(img.getAttribute())))) {
del.add(obj);
del.add(img);
}
}
for (int i=0; i<del.size()-1; i=i+2) {
GraphObject obj = del.get(i);
GraphObject img = del.get(i+1);
if (obj.isNode()) {
r.removeMapping((Node)obj, (Node)img);
try {
r.getLeft().destroyNode((Node)obj);
r.getRight().destroyNode((Node)img);
removed = true;
} catch (TypeException ex) {}
}
}
return removed;
}
/** Returns a clone of the rule. */
public Rule cloneRule(final Rule rule) {
Rule ruleClone = new Rule(rule.getOriginal().getTypeSet());
final Hashtable<GraphObject, GraphObject> table = new Hashtable<GraphObject, GraphObject>();
copyRule(rule, ruleClone, table, true);
ruleClone.setLayer(rule.getLayer());
ruleClone.setPriority(rule.getPriority());
table.clear();
return ruleClone;
}
/** Returns a clone of the rule. */
public boolean cloneRule(final Rule from, final Rule to) {
final Hashtable<GraphObject, GraphObject> table = new Hashtable<GraphObject, GraphObject>();
copyRule(from, to, table, true);
table.clear();
return true;
}
/** Returns a clone of the given rule using specified types. */
public Rule cloneRule(Rule rule, TypeSet types, boolean withApplConds) {
Rule ruleClone = new Rule(types);
final Hashtable<GraphObject, GraphObject> ltable = new Hashtable<GraphObject, GraphObject>();
final Hashtable<GraphObject, GraphObject> rtable = new Hashtable<GraphObject, GraphObject>();
final Hashtable<GraphObject, GraphObject> table = new Hashtable<GraphObject, GraphObject>();
copyRule(rule, ruleClone, table, withApplConds);
ruleClone.setLayer(rule.getLayer());
ruleClone.setPriority(rule.getPriority());
ltable.clear();
rtable.clear();
return ruleClone;
}
/**
* Copies the given rule into the given ruleClone.
* The TypeSet of the given rules must be the same set.
*/
private Rule copyRule(
final Rule rule,
final Rule ruleClone,
final Hashtable<GraphObject, GraphObject> table,
boolean withApplConds) {
ruleClone.setName(rule.getName());
copyAttrContextFromTo(rule.getAttrContext(), ruleClone.getAttrContext());
// Graph lgraph = rule.getLeft();
// Graph rgraph = rule.getRight();
// Graph left = ruleClone.getLeft();
// Graph right = ruleClone.getRight();
// copy LHS and RHS
this.copyGraph(rule.getLeft(), ruleClone.getLeft(), table);
this.copyGraph(rule.getRight(), ruleClone.getRight(), table);
// copy rule morphism
this.copyMorph(rule, ruleClone, table);
if (withApplConds) {
// copy GAGs
for(int i=0; i<rule.getNestedACsList().size(); i++) {
NestedApplCond ac = (NestedApplCond) rule.getNestedACsList().get(i);
NestedApplCond acClone = ruleClone.createNestedAC();
acClone.getImage().setName(ac.getImage().getName());
acClone.setName(ac.getName());
copyGraph(ac.getImage(), acClone.getImage(), table);
copyMorph(ac, acClone, table);
copyNestedAC(ac, acClone, table);
}
ruleClone.setFormula(rule.getFormulaStr());
// copy NACs
for(int i=0; i<rule.getNACsList().size(); i++) {
OrdinaryMorphism ac = rule.getNACsList().get(i);
OrdinaryMorphism acClone = ruleClone.createNAC();
acClone.getImage().setName(ac.getImage().getName());
acClone.setName(ac.getName());
copyGraph(ac.getImage(), acClone.getImage(), table);
copyMorph(ac, acClone, table);
}
// copy PACs
for(int i=0; i<rule.getPACsList().size(); i++) {
OrdinaryMorphism ac = rule.getPACsList().get(i);
OrdinaryMorphism acClone = ruleClone.createPAC();
acClone.getImage().setName(ac.getImage().getName());
acClone.setName(ac.getName());
copyGraph(ac.getImage(), acClone.getImage(), table);
copyMorph(ac, acClone, table);
}
}
return ruleClone;
}
public void copyGraph(Graph from, Graph to,
Hashtable<GraphObject, GraphObject> table) {
// copy nodes
Iterator<Node> nodes = from.getNodesSet().iterator();
while (nodes.hasNext()) {
Node bn1 = nodes.next();
Node bn2 = null;
try {
bn2 = to.copyNode(bn1);
bn2.setContextUsage(bn1.getContextUsage());
table.put(bn1, bn2);
} catch (TypeException e) {
e.printStackTrace();
}
}
// copy arcs
Iterator<Arc> arcs = from.getArcsSet().iterator();
while (arcs.hasNext()) {
Arc ba1 = arcs.next();
Node src = (Node) table.get(ba1.getSource());
Node tar = (Node) table.get(ba1.getTarget());
Arc ba2 = null;
try {
ba2 = to.copyArc(ba1, src, tar);
ba2.setContextUsage(ba1.getContextUsage());
table.put(ba1, ba2);
// add a new EdArc
} catch (TypeException e) {
e.printStackTrace();
}
}
}
public void copyMorph(OrdinaryMorphism from, OrdinaryMorphism to,
Hashtable<GraphObject, GraphObject> table) {
Iterator<GraphObject> dom = from.getDomainObjects().iterator();
while (dom.hasNext()) {
GraphObject lgo = dom.next();
GraphObject rgo = from.getImage(lgo);
GraphObject lgo1 = table.get(lgo);
GraphObject rgo1 = table.get(rgo);
try {
to.addMapping(lgo1, rgo1);
} catch (agg.xt_basis.BadMappingException e) {
e.printStackTrace();
}
}
}
public AtomConstraint cloneAtomConstraint(
final AtomConstraint ac,
final TypeSet types) {
final Hashtable<GraphObject, GraphObject> commonTable = new Hashtable<GraphObject, GraphObject>();
Graph g1 = BaseFactory.theFactory().createGraph(types);
g1.setKind(GraphKind.PREMISE);
Graph g2 = BaseFactory.theFactory().createGraph(types);
g2.setKind(GraphKind.CONCLUSION);
AtomConstraint atom = new AtomConstraint(g1, g2, agg.attribute.impl.AttrTupleManager
.getDefaultManager().newContext(AttrMapping.PLAIN_MAP), ac.getAtomicName());
copyAttrContextFromTo(ac.getConclusion(0).getAttrContext(),
atom.getConclusion(0).getAttrContext());
copyGraph(ac.getSource(), g1, commonTable);
copyGraph(ac.getConclusion(0).getTarget(), g2, commonTable);
copyMorph(ac.getConclusion(0), atom.getConclusion(0), commonTable);
atom.getConclusion(0).setName(ac.getConclusion(0).getName());
for (int i=1; i<ac.getConclusionsSize(); i++) {
AtomConstraint from = ac.getConclusion(i);
Graph g = BaseFactory.theFactory().createGraph(types);
g.setKind(GraphKind.CONCLUSION);
AtomConstraint to = atom.createNextConclusion(g);
to.setName(from.getName());
copyAttrContextFromTo(from.getAttrContext(), to.getAttrContext());
copyGraph(from.getTarget(), g, commonTable);
copyMorph(from, to, commonTable);
}
return atom;
}
public void copyNestedAC(
final NestedApplCond from,
final NestedApplCond to,
final Hashtable<GraphObject, GraphObject> table) {
for(int i=0; i<from.getNestedACs().size(); i++) {
NestedApplCond ac = from.getNestedACs().get(i);
NestedApplCond acClone = to.createNestedAC();
acClone.getImage().setName(ac.getImage().getName());
acClone.setName(ac.getName());
copyGraph(ac.getImage(), acClone.getImage(), table);
copyMorph(ac, acClone, table);
copyNestedAC(ac, acClone, table);
}
to.setFormula(from.getFormulaStr());
}
/**
* Copies the given rule into the given ruleClone.
* The TypeSet of the given rules must be the same set.
* The kernel part of the given ruleClone is already contained.
*/
private MultiRule copyMultiRule(
final MultiRule rule,
final MultiRule ruleClone,
final Hashtable<GraphObject, GraphObject> table) {
ruleClone.setName(rule.getName());
copyAttrContextFromTo(rule.getAttrContext(), ruleClone.getAttrContext());
Graph lgraph = rule.getLeft();
Graph rgraph = rule.getRight();
Graph left = ruleClone.getLeft();
Graph right = ruleClone.getRight();
// copy RHS nodes
Iterator<Node> rnodes = rgraph.getNodesSet().iterator();
while (rnodes.hasNext()) {
Node rNode = rnodes.next();
Node itsRNode = null;
if (!rule.isTargetOfEmbeddingRight(rNode)) {
try {
itsRNode = right.copyNode(rNode);
table.put(rNode, itsRNode);
} catch (TypeException e) {
e.getLocalizedMessage();
}
} else {
Node n = (Node)table.get(rule.getEmbeddingRight().getInverseImage(rNode).nextElement());
itsRNode = (Node)ruleClone.getEmbeddingRight().getImage(n);
table.put(rNode, itsRNode);
}
}
// copy LHS nodes
Iterator<Node> lnodes = lgraph.getNodesSet().iterator();
while (lnodes.hasNext()) {
Node lNode = lnodes.next();
Node itsLNode = null;
if (!rule.isTargetOfEmbeddingLeft(lNode)) {
try {
itsLNode = left.copyNode(lNode);
table.put(lNode, itsLNode);
} catch (TypeException e) {
e.getLocalizedMessage();
}
GraphObject rn = rule.getImage(lNode);
// set mapping
if (rn != null) {
try {
ruleClone.addMapping(itsLNode, table.get(rn));
} catch (BadMappingException ex) {
System.out.println(ex.getMessage());
}
}
} else {
Node n = (Node)table.get(rule.getEmbeddingLeft().getInverseImage(lNode).nextElement());
itsLNode = (Node)ruleClone.getEmbeddingLeft().getImage(n);
table.put(lNode, itsLNode);
}
}
// copy RHS arcs
Iterator<Arc> rarcs = rgraph.getArcsSet().iterator();
while (rarcs.hasNext()) {
Arc rArc = rarcs.next();
Arc itsRArc = null;
if (!rule.isTargetOfEmbeddingRight(rArc)) {
Node itsRSource = (Node) table.get(rArc.getSource());
Node itsRTarget = (Node) table.get(rArc.getTarget());
try {
itsRArc = right.copyArc(rArc, itsRSource, itsRTarget);
table.put(rArc, itsRArc);
} catch (TypeException e) {
e.getLocalizedMessage();
}
} else {
Arc a = (Arc)table.get(rule.getEmbeddingRight().getInverseImage(rArc).nextElement());
itsRArc = (Arc)ruleClone.getEmbeddingRight().getImage(a);
table.put(rArc, itsRArc);
}
}
// copy LHS arcs
Iterator<Arc> larcs = lgraph.getArcsSet().iterator();
while (larcs.hasNext()) {
Arc lArc = larcs.next();
Arc itsLArc = null;
if (!rule.isTargetOfEmbeddingLeft(lArc)) {
Node itsLSource = (Node) table.get(lArc.getSource());
Node itsLTarget = (Node) table.get(lArc.getTarget());
try {
itsLArc = left.copyArc(lArc, itsLSource, itsLTarget);
table.put(lArc, itsLArc);
} catch (TypeException e) {
e.getLocalizedMessage();
}
GraphObject ra = rule.getImage(lArc);
// set mapping
if (ra != null) {
try {
ruleClone.addMapping(itsLArc, table.get(ra));
} catch (BadMappingException ex) {
System.out.println(ex.getMessage());
}
}
} else {
Arc a = (Arc)table.get(rule.getEmbeddingLeft().getInverseImage(lArc).nextElement());
itsLArc = (Arc)ruleClone.getEmbeddingLeft().getImage(a);
table.put(lArc, itsLArc);
}
}
// copy GAGs
for(int i=0; i<rule.getNestedACsList().size(); i++) {
NestedApplCond ac = (NestedApplCond) rule.getNestedACsList().get(i);
NestedApplCond acClone = ruleClone.createNestedAC();
acClone.getImage().setName(ac.getImage().getName());
acClone.setName(ac.getName());
copyGraph(ac.getImage(), acClone.getImage(), table);
copyMorph(ac, acClone, table);
copyNestedAC(ac, acClone, table);
}
ruleClone.setFormula(rule.getFormulaStr());
// copy NACs
final List<OrdinaryMorphism> nacs = rule.getNACsList();
for(int i=0; i<nacs.size(); i++) {
OrdinaryMorphism ac = nacs.get(i);
OrdinaryMorphism acClone = ruleClone.createNAC();
acClone.getImage().setName(ac.getImage().getName());
acClone.setName(ac.getName());
copyGraph(ac.getImage(), acClone.getImage(), table);
copyMorph(ac, acClone, table);
}
// copy PACs
final List<OrdinaryMorphism> pacs = rule.getPACsList();
for(int i=0; i<pacs.size(); i++) {
OrdinaryMorphism ac = pacs.get(i);
OrdinaryMorphism acClone = ruleClone.createPAC();
acClone.getImage().setName(ac.getImage().getName());
acClone.setName(ac.getName());
copyGraph(ac.getImage(), acClone.getImage(), table);
copyMorph(ac, acClone, table);
}
return ruleClone;
}
/**
* Copies the given rule into the given ruleClone.
* The TypeSet of the given rules must be the same set.
* The kernel part of the given ruleClone is already contained.
*/
private boolean reverseMultiRule(
final MultiRule rule,
final MultiRule invRule,
final Hashtable<GraphObject, GraphObject> table) {
copyAttrContextFromTo(rule.getAttrContext(), invRule.getAttrContext());
Graph left = rule.getLeft();
Graph right = rule.getRight();
Graph invLeft = invRule.getLeft();
Graph invRight = invRule.getRight();
// copy LHS nodes to RHS nodes
Iterator<Node> lnodes = left.getNodesSet().iterator();
while (lnodes.hasNext()) {
Node lNode = lnodes.next();
Node invRNode = null;
if (!rule.isTargetOfEmbeddingLeft(lNode)) {
try {
invRNode = invRight.copyNode(lNode);
table.put(lNode, invRNode);
} catch (TypeException e) {
e.getLocalizedMessage();
}
} else {
Node n = (Node)table.get(rule.getEmbeddingLeft().getInverseImage(lNode).nextElement());
invRNode = (Node)invRule.getEmbeddingRight().getImage(n);
table.put(lNode, invRNode);
}
}
// copy RHS nodes to LHS nodes
Iterator<Node> rnodes = right.getNodesSet().iterator();
while (rnodes.hasNext()) {
Node rNode = rnodes.next();
Node invLNode = null;
if (!rule.isTargetOfEmbeddingRight(rNode)) {
try {
invLNode = invLeft.copyNode(rNode);
table.put(rNode, invLNode);
} catch (TypeException e) {
e.getLocalizedMessage();
}
Enumeration<GraphObject> en = rule.getInverseImage(rNode);
if (en.hasMoreElements()) {
GraphObject ln = en.nextElement();
// set mapping
try {
invRule.addMapping(invLNode, table.get(ln));
} catch (BadMappingException ex) {
System.out.println(ex.getMessage());
}
}
} else {
Node n = (Node)table.get(rule.getEmbeddingRight().getInverseImage(rNode).nextElement());
invLNode = (Node)invRule.getEmbeddingLeft().getImage(n);
table.put(rNode, invLNode);
}
}
// copy LHS arcs to RHS arcs
Iterator<Arc> larcs = left.getArcsSet().iterator();
while (larcs.hasNext()) {
Arc lArc = larcs.next();
Arc invRArc = null;
if (!rule.isTargetOfEmbeddingLeft(lArc)) {
Node itsRSource = (Node) table.get(lArc.getSource());
Node itsRTarget = (Node) table.get(lArc.getTarget());
try {
if (itsRSource != null && itsRTarget != null) {
invRArc = invRight.copyArc(lArc, itsRSource, itsRTarget);
table.put(lArc, invRArc);
}
} catch (TypeException e) {
System.out.println(e.getLocalizedMessage());
}
} else {
Arc a = (Arc)table.get(rule.getEmbeddingLeft().getInverseImage(lArc).nextElement());
invRArc = (Arc)invRule.getEmbeddingRight().getImage(a);
table.put(lArc, invRArc);
}
}
// copy RHS arcs to LHS arcs
Iterator<Arc> rarcs = right.getArcsSet().iterator();
while (rarcs.hasNext()) {
Arc rArc = rarcs.next();
Arc invLArc = null;
if (!rule.isTargetOfEmbeddingRight(rArc)) {
Node itsLSource = (Node) table.get(rArc.getSource());
Node itsLTarget = (Node) table.get(rArc.getTarget());
try {
invLArc = invLeft.copyArc(rArc, itsLSource, itsLTarget);
table.put(rArc, invLArc);
} catch (TypeException e) {
e.getLocalizedMessage();
}
Enumeration<GraphObject> en = rule.getInverseImage(rArc);
if (en.hasMoreElements()) {
GraphObject la = en.nextElement();
// set mapping
try {
invRule.addMapping(invLArc, table.get(la));
} catch (BadMappingException ex) {
System.out.println(ex.getMessage());
}
}
} else {
Arc a = (Arc)table.get(rule.getEmbeddingRight().getInverseImage(rArc).nextElement());
invLArc = (Arc)invRule.getEmbeddingLeft().getImage(a);
table.put(rArc, invLArc);
}
}
boolean ok = true;
// converting PACs from LHS to RHS
if (this.convertPACsLeft2Right(rule, invRule, table)) {
// converting NACs from LHS to RHS
this.convertNACsLeft2Right(rule, invRule, table);
// converting GACs from LHS to RHS
this.convertGACsLeft2Right(rule, invRule, table);
// convert attr conditions
this.convertAttrConditionLeft2Right(rule, invRule);
}
else
ok = false;
return ok;
}
private void copyAttrContextFromTo(AttrContext from, AttrContext to) {
// copy attr context : variables
VarTuple avt = (VarTuple) to.getVariables();
VarTuple avtOther = (VarTuple) from.getVariables();
for (int i = 0; i < avtOther.getSize(); i++) {
VarMember varOther = avtOther.getVarMemberAt(i);
// System.out.println(varOther.getName() +" mark:
// "+varOther.getMark());
VarMember var = avt.getVarMemberAt(varOther.getName());
if (var == null) {
avt.declare(agg.attribute.facade.impl.DefaultInformationFacade
.self().getJavaHandler(), varOther.getDeclaration()
.getTypeName(), varOther.getDeclaration().getName());
var = avt.getVarMemberAt(varOther.getName());
}
if (var != null) {
var.setMark(varOther.getMark());
var.setInputParameter(varOther.isInputParameter());
}
}
// copy attr conditions
CondTuple act = (CondTuple) to.getConditions();
CondTuple actOther = (CondTuple) from.getConditions();
for (int i = 0; i < actOther.getSize(); i++) {
CondMember condOther = actOther.getCondMemberAt(i);
// System.out.println(condOther+" mark: "+condOther.getMark());
CondMember cond = (CondMember) act.addCondition(condOther
.getExprAsText());
cond.setMark(condOther.getMark());
// System.out.println(cond+" mark: "+cond.getMark());
}
}
/**
* Creates a morphism from the given Graph <code>g</code> to the given Graph <code>gToExtend</code>.
* For each object of <code>g</code> a copie is created into <code>gToExtend</code>
* and a mapping set from an object of the Graph <code>g</code> to its copy
* in the Graph <code>gToExtend</code>.
*
* @param gToExtend
* @param g
* @return morphism from <code>g</code> to <code>gToExtend</code>
* @throws Exception
*/
public OrdinaryMorphism extendGraphByGraph(final Graph gToExtend, final Graph g)
throws Exception{
// System.out.println("BF.extendGraphByGraph:: "+gToExtend.getName()+" by "+g.getName());
final OrdinaryMorphism g2extendedg = this.createMorphism(g, gToExtend);
Iterator<Node> nodes = g.getNodesSet().iterator();
while (nodes.hasNext()) {
Node elem= nodes.next();
try {
Node copy = gToExtend.copyNode(elem);
g2extendedg.addMapping(elem, copy);
}
catch (TypeException ex) {
// System.out.println("BF.extendGraphByGraph:: Node copy failed: "+ex.getMessage());
throw ex;
}
catch (BadMappingException e) {
// System.out.println("BF.extendGraphByGraph:: Node copy failed: "+e.getMessage());
throw e;
}
}
Iterator<Arc> arcs = g.getArcsSet().iterator();
while (arcs.hasNext()) {
Arc elem = arcs.next();
try {
Node s = (Node) g2extendedg.getImage(elem.getSource());
Node t = (Node) g2extendedg.getImage(elem.getTarget());
Arc copy = gToExtend.copyArc(elem, s, t);
g2extendedg.addMapping(elem, copy);
}
catch (TypeException ex) {
// System.out.println("BF.extendGraphByGraph:: Arc copy failed: "+ex.getMessage());
throw ex;
}
catch (BadMappingException e) {
// System.out.println("BF.extendGraphByGraph:: Arc copy failed: "+e.getMessage());
throw e;
}
}
return g2extendedg;
}
/**
* Create an parent atomic to construct an atomic graph constraint.
*/
public final AtomConstraint createAtomic(TypeSet types, String name) {
Graph g1 = createGraph(types);
g1.setKind(GraphKind.PREMISE);
Graph g2 = createGraph(types);
g2.setKind(GraphKind.CONCLUSION);
return new AtomConstraint(g1, g2, agg.attribute.impl.AttrTupleManager
.getDefaultManager().newContext(AttrMapping.PLAIN_MAP), name);
}
/** Create an ordinary morphism. */
public final OrdinaryMorphism createMorphism(final Graph orig, final Graph img) {
AttrContext context = agg.attribute.impl.AttrTupleManager
.getDefaultManager().newContext(AttrMapping.PLAIN_MAP);
OrdinaryMorphism output = new OrdinaryMorphism(orig, img, context);
// hier nicht!! seiten effekt: attribute (type) konflikt
// AttrContext aLeftContext =
// agg.attribute.impl.AttrTupleManager.getDefaultManager().newLeftContext(context);
// AttrContext aRightContext =
// agg.attribute.impl.AttrTupleManager.getDefaultManager().newRightContext(context);
// output.getSource().setAttrContext(aLeftContext);
// output.getTarget().setAttrContext(aRightContext);
//
declareVariable(output.getSource(), (VarTuple) output.getAttrContext()
.getVariables());
declareVariable(output.getTarget(), (VarTuple) output.getAttrContext()
.getVariables());
return output;
}
/** Create an general (nested) morphism. */
public final NestedApplCond createGeneralMorphism(Graph orig, Graph img) {
AttrContext context = agg.attribute.impl.AttrTupleManager
.getDefaultManager().newContext(AttrMapping.PLAIN_MAP);
AttrContext aLeftContext =
agg.attribute.impl.AttrTupleManager.getDefaultManager().newLeftContext(context);
AttrContext aRightContext =
agg.attribute.impl.AttrTupleManager.getDefaultManager().newRightContext(context);
NestedApplCond output = new NestedApplCond(orig, img, context);
// new
output.getSource().setAttrContext(aLeftContext);
output.getTarget().setAttrContext(aRightContext);
//
declareVariable(output.getSource(), (VarTuple) output.getAttrContext()
.getVariables());
declareVariable(output.getTarget(), (VarTuple) output.getAttrContext()
.getVariables());
return output;
}
/**
* Create an ordinary morphism. The original or image graph objects can have
* unset attribute members. If implicit is TRUE a variable will be used as
* value of those attribute members.
*
* @param orig
* The original graph.
* @param img
* The image graph.
* @param implicit
* If true, all unset attributes of the target graph will get a
* variable as value.
* @return The new ordinary morphism.
*/
public final OrdinaryMorphism createMorphism(final Graph orig, final Graph img, boolean implicit) {
return createMorphism(orig, img, implicit, "");
}
/**
* Create an ordinary morphism. The original or image graph objects can have
* unset attribute members. If implicit is TRUE a variable will be used as
* value of those attribute members.
*
* @param orig
* The original graph.
* @param img
* The image graph.
* @param implicit
* If true, all unset attributes of the target graph will get a
* variable as value.
* @param helpMarkOfVars
* The help name of the implicitly set variables.
* @return The new ordinary morphism.
*/
public final OrdinaryMorphism createMorphism(
final Graph orig,
final Graph img,
boolean implicit,
String helpMarkOfVars) {
OrdinaryMorphism m = createMorphism(orig, img);
int count = m.getAttrContext().getVariables().getSize();
if (implicit) {
String mark = "_" + helpMarkOfVars;
Iterator<?> elements = img.getNodesSet().iterator();
while (elements.hasNext()) {
GraphObject grob = (GraphObject) elements.next();
if (grob.getAttribute() == null)
continue;
agg.attribute.AttrInstance attrs = grob.getAttribute();
agg.attribute.impl.ValueTuple values = (agg.attribute.impl.ValueTuple) attrs;
for (int i = 0; i < values.getNumberOfEntries(); i++) {
agg.attribute.impl.ValueMember vm = values
.getValueMemberAt(i);
if (!vm.isSet()) {
String t = vm.getName() + String.valueOf(count) + mark;
vm.setExprAsText(t);
vm.setTransient(true);
count++;
}
}
}
elements = img.getArcsSet().iterator();
while (elements.hasNext()) {
GraphObject grob = (GraphObject) elements.next();
if (grob.getAttribute() == null)
continue;
agg.attribute.AttrInstance attrs = grob.getAttribute();
agg.attribute.impl.ValueTuple values = (agg.attribute.impl.ValueTuple) attrs;
for (int i = 0; i < values.getNumberOfEntries(); i++) {
agg.attribute.impl.ValueMember vm = values
.getValueMemberAt(i);
if (!vm.isSet()) {
String t = vm.getName() + String.valueOf(count) + mark;
vm.setExprAsText(t);
vm.setTransient(true);
count++;
}
}
}
}
return m;
}
public VarMember declareVariable(
AttrHandler attrHandler, String typeName,
String name, VarTuple tuple) {
VarMember var = tuple.getVarMemberAt(name);
if (var == null) {
tuple.declare(attrHandler, typeName, name);
var = (VarMember) tuple.getEntryAt(name);
}
else if (!var.getDeclaration().getTypeName().equals(typeName)) {
String name1 = name.concat(String.valueOf(tuple.getNumberOfEntries()));
tuple.declare(attrHandler, typeName, name1);
var = tuple.getVarMemberAt(name1);
}
return var;
}
/**
* Adds not declared variable of attributes to the specified variable tuple.
* @param g graph which nodes and edges are searched for not declared variables
* @param tuple variable tuple to declare new variables
*/
public void declareVariable(Graph g, VarTuple tuple) {
for (Iterator<Node> elements = g.getNodesSet().iterator(); elements.hasNext();) {
GraphObject grob = elements.next();
if (grob.getAttribute() == null)
continue;
AttrInstance attrs = grob.getAttribute();
ValueTuple values = (agg.attribute.impl.ValueTuple) attrs;
for (int i = 0; i < values.getNumberOfEntries(); i++) {
ValueMember vm = values.getValueMemberAt(i);
if (vm.isSet() && vm.getExpr().isVariable()) {
declareVariable(vm.getDeclaration().getHandler(),
vm.getDeclaration().getTypeName(),
vm.getExprAsText(), tuple);
}
}
}
for (Iterator<Arc> elements = g.getArcsSet().iterator(); elements.hasNext();) {
GraphObject grob = elements.next();
if (grob.getAttribute() == null)
continue;
AttrInstance attrs = grob.getAttribute();
ValueTuple values = (agg.attribute.impl.ValueTuple) attrs;
for (int i = 0; i < values.getNumberOfEntries(); i++) {
ValueMember vm = values.getValueMemberAt(i);
if (vm.isSet() && vm.getExpr().isVariable()) {
declareVariable(vm.getDeclaration().getHandler(),
vm.getDeclaration().getTypeName(),
vm.getExprAsText(), tuple);
}
}
}
}
private void declareVar(Graph g, VarTuple tuple, ContextView conview) {
for (Iterator<Node> elements = g.getNodesSet().iterator(); elements.hasNext();) {
GraphObject grob = elements.next();
if (grob.getAttribute() == null)
continue;
AttrInstance attrs = grob.getAttribute();
ValueTuple vt = (agg.attribute.impl.ValueTuple) attrs;
for (int i = 0; i < vt.getNumberOfEntries(); i++) {
ValueMember vm = vt.getValueMemberAt(i);
if (vm.isSet() && vm.getExpr().isVariable()) {
declareVariable(vm.getDeclaration().getHandler(),
vm.getDeclaration().getTypeName(),
vm.getExprAsText(), tuple);
}
}
vt.resetContextView(conview);
}
for (Iterator<Arc> elements = g.getArcsSet().iterator(); elements.hasNext();) {
GraphObject grob = elements.next();
if (grob.getAttribute() == null)
continue;
AttrInstance attrs = grob.getAttribute();
ValueTuple vt = (agg.attribute.impl.ValueTuple) attrs;
for (int i = 0; i < vt.getNumberOfEntries(); i++) {
ValueMember vm = vt.getValueMemberAt(i);
if (vm.isSet() && vm.getExpr().isVariable()) {
declareVariable(vm.getDeclaration().getHandler(),
vm.getDeclaration().getTypeName(),
vm.getExprAsText(), tuple);
}
}
vt.resetContextView(conview);
}
}
public final OrdinaryMorphism createMatchfromMorph(
final OrdinaryMorphism base,
final AttrContext base_context) {
OrdinaryMorphism match = new OrdinaryMorphism(
base.getOriginal(),
base.getImage(),
base.getAttrManager().newContext(AttrMapping.MATCH_MAP, base_context));
declareVariable(match.getOriginal(), (VarTuple) match.getAttrContext()
.getVariables());
declareVariable(match.getImage(), (VarTuple) match.getAttrContext()
.getVariables());
// set mappings
Iterator<?> elems = match.getOriginal().getNodesSet().iterator();
while (elems.hasNext()) {
GraphObject o = (GraphObject) elems.next();
GraphObject i = base.getImage(o);
if (i != null) {
try {
match.addMapping(o, i);
} catch (BadMappingException ex) {
System.out.println(ex.getMessage());
}
}
}
elems = match.getOriginal().getArcsSet().iterator();
while (elems.hasNext()) {
GraphObject o = (GraphObject) elems.next();
GraphObject i = base.getImage(o);
if (i != null) {
try {
match.addMapping(o, i);
} catch (BadMappingException ex) {
System.out.println(ex.getMessage());
}
}
}
return match;
}
public final boolean createMatchfromMorph(
final OrdinaryMorphism baseMorph,
final OrdinaryMorphism targetMatch,
final AttrContext base_context) {
targetMatch.setSource(baseMorph.getOriginal());
targetMatch.setTarget(baseMorph.getImage());
targetMatch.setAttrContext(baseMorph.getAttrManager().newContext(
AttrMapping.MATCH_MAP, base_context));
declareVariable(targetMatch.getOriginal(), (VarTuple) targetMatch
.getAttrContext().getVariables());
declareVariable(targetMatch.getImage(), (VarTuple) targetMatch
.getAttrContext().getVariables());
// set mappings
Iterator<?> elems = targetMatch.getOriginal().getNodesSet().iterator();
while (elems.hasNext()) {
GraphObject o = (GraphObject) elems.next();
GraphObject i = baseMorph.getImage(o);
if (i != null) {
try {
targetMatch.addMapping(o, i);
} catch (BadMappingException ex) {
targetMatch.clear();
return false;
}
}
}
elems = targetMatch.getOriginal().getArcsSet().iterator();
while (elems.hasNext()) {
GraphObject o = (GraphObject) elems.next();
GraphObject i = baseMorph.getImage(o);
if (i != null) {
try {
targetMatch.addMapping(o, i);
} catch (BadMappingException ex) {
targetMatch.clear();
return false;
}
}
}
return true;
}
public final OrdinaryMorphism createMorphfromMorph(
final OrdinaryMorphism base,
final AttrContext base_context) {
// System.out.println("BaseFactory.createMorphfromMorph");
OrdinaryMorphism match = new OrdinaryMorphism(
base.getOriginal(),
base.getImage(),
base.getAttrManager().newContext(AttrMapping.PLAIN_MAP, base_context));
/* set mappings */
Iterator<?> elems = match.getOriginal().getNodesSet().iterator();
while (elems.hasNext()) {
GraphObject o = (GraphObject) elems.next();
GraphObject i = base.getImage(o);
if (i != null) {
try {
match.addMapping(o, i);
} catch (BadMappingException ex) {
}
}
}
elems = match.getOriginal().getArcsSet().iterator();
while (elems.hasNext()) {
GraphObject o = (GraphObject) elems.next();
GraphObject i = base.getImage(o);
if (i != null) {
try {
match.addMapping(o, i);
} catch (BadMappingException ex) {
}
}
}
return match;
}
/** Dispose the specified morphism. */
public final void destroyMorphism(OrdinaryMorphism morph) {
if (morph != null)
morph.dispose();
}
/**
* Create an empty match morphism between the left side of the given rule
* and my start graph. Note that this does not yield a valid match (unless
* the left side of the given rule is empty), because matches have to be
* total morphisms.
*
* @param rule
* The rule.
* @param graph
* The graph.
* @return The new match.
*/
public final Match createMatch(Rule rule, Graph graph) {
final Match match = new Match(rule, graph);
if (match.getImage().getVariableNamesOfAttributes().size() != 0)
((ContextView) match.getAttrContext()).setVariableContext(true);
return match;
}
/**
* Create an empty match between the left side of the given rule and a start
* graph. Note that this does not yield a valid match (unless the left side
* of the given rule is empty), because matches have to be total morphisms.
* The graph objects can have unset attribute members. If implicit is TRUE a
* variable will be used as value of those attribute members.
*
* @param rule
* The rule.
* @param graph
* The graph.
* @return The new match.
*/
public final Match createMatch(Rule rule, Graph graph, boolean implicit) {
return createMatch(rule, graph, implicit, "");
}
/**
* Create an empty match between the left side of the given rule and a start
* graph. Note that this does not yield a valid match (unless the left side
* of the given rule is empty), because matches have to be total morphisms.
* The graph objects can have unset attribute members. If implicit is TRUE a
* variable will be used as value of those attribute members.
*
* @param rule
* The rule.
* @param graph
* The graph.
* @return The new match.
*/
public final Match createMatch(
final Rule rule,
final Graph graph,
boolean implicit,
final String helpMarkOfVars) {
Match match = createMatch(rule, graph);
int count = match.getAttrContext().getVariables().getSize();
VarTuple vars = (VarTuple) match.getAttrContext().getVariables();
if (implicit) {
String mark = "_" + helpMarkOfVars;
Iterator<Node> nodes = graph.getNodesSet().iterator();
while (nodes.hasNext()) {
GraphObject grob = nodes.next();
if (grob.getAttribute() != null) {
ValueTuple values = (ValueTuple) grob.getAttribute();
for (int i = 0; i < values.getNumberOfEntries(); i++) {
ValueMember vm = values.getValueMemberAt(i);
if (!vm.isSet()) {
String t = vm.getName() + String.valueOf(count) + mark;
VarMember var = declareVariable(vm.getDeclaration().getHandler(),
vm.getDeclaration().getTypeName(),
t,
vars);
var.setTransient(true);
count++;
vm.setTransient(true);
vm.setExprAsText(var.getName());
}
}
}
}
Iterator<Arc> arcs = graph.getArcsSet().iterator();
while (arcs.hasNext()) {
GraphObject grob = arcs.next();
if (grob.getAttribute() != null) {
ValueTuple values = (ValueTuple) grob.getAttribute();
for (int i = 0; i < values.getNumberOfEntries(); i++) {
ValueMember vm = values.getValueMemberAt(i);
if (!vm.isSet()) {
String t = vm.getName() + String.valueOf(count) + mark;
VarMember var = declareVariable(vm.getDeclaration().getHandler(),
vm.getDeclaration().getTypeName(),
t,
vars);
var.setTransient(true);
count++;
vm.setTransient(true);
vm.setExprAsText(var.getName());
}
}
}
}
}
return match;
}
/**
* Makes a match for a rule and a morphism from the left hand side to a
* graph. The mapping of the morphism will be to a mapping of the match. The
* graph objects can have unset attribute members. A variable will be used
* as value of those attribute members.
*
* @param rule
* The rule.
* @param morph
* The morphism.
* @return The new match.
*/
public Match makeMatch(Rule rule, OrdinaryMorphism morph) {
return makeMatch(rule, morph, "");
}
/**
* Makes a match for a rule and a morphism from the left hand side of a rule
* to the target graph of a morphism. The mapping of the morphism will be to
* a mapping of the match. The graph objects can have unset attribute
* members. A variable will be used as value of those attribute members.
*
* @param rule
* The rule.
* @param morph
* The morphism.
* @return The new match.
*/
public Match makeMatch(
final Rule rule,
final OrdinaryMorphism morph,
final String helpMarkOfVars) {
String mark = "";
if (!helpMarkOfVars.equals(""))
mark = "_" + helpMarkOfVars;
Match m = createMatch(rule, morph.getImage(), true);
boolean variableContext = false;
if ((m.getImage().getVariableNamesOfAttributes().size() != 0)
|| ((ContextView) morph.getAttrContext()).isVariableContext()) {
((ContextView) m.getAttrContext()).setVariableContext(true);
variableContext = true;
}
VarTuple vars = (VarTuple) m.getAttrContext().getVariables();
int count = vars.getSize();
Enumeration<GraphObject> elements = morph.getDomain();
while (elements.hasMoreElements()) {
GraphObject obj = elements.nextElement();
GraphObject img = morph.getImage(obj);
if (img != null) {
if (obj.getAttribute() == null && img.getAttribute() == null) {
try {
m.addMapping(obj, img);
} catch (BadMappingException e) {
// System.out.println("BaseFactory.makeMatch: (no attrs) "+ e.getMessage());
destroyMatch(m);
m = null;
return null;
}
continue;
}
if (variableContext
&& obj.getAttribute() != null
&& img.getAttribute() != null) {
AttrInstance objAttrs = obj.getAttribute();
ValueTuple objValues = (agg.attribute.impl.ValueTuple) objAttrs;
AttrInstance imgAttrs = img.getAttribute();
ValueTuple imgValues = (agg.attribute.impl.ValueTuple) imgAttrs;
for (int i = 0; i < imgValues.getNumberOfEntries(); i++) {
ValueMember imgvm = imgValues.getValueMemberAt(i);
ValueMember objvm = objValues.getValueMemberAt(imgvm.getName());
if (objvm != null) {
if (objvm.isSet()) {
if (!imgvm.isSet()) {
if (objvm.getExpr().isVariable()) {
String t = imgvm.getName() + String.valueOf(count)
+ mark;
declareVariable(imgvm.getDeclaration()
.getHandler(), imgvm.getDeclaration()
.getTypeName(), t, vars);
count++;
imgvm.setExprAsText(t);
imgvm.setTransient(true);
} else if (objvm.getExpr().isConstant()) {
imgvm.setExprAsObject(objvm.getExpr().getCopy());
imgvm.setTransient(true);
}
}
}
else {
if (!imgvm.isSet()) {
String t = imgvm.getName() + String.valueOf(count)
+ mark;
declareVariable(imgvm.getDeclaration().getHandler(),
imgvm.getDeclaration().getTypeName(), t, vars);
count++;
imgvm.setExprAsText(t);
imgvm.setTransient(true);
}
}
}
}
}
try {
m.addMapping(obj, img);
} catch (BadMappingException e) {
destroyMatch(m);
m = null;
return null;
}
}
}
return m;
}
/** Dispose the specified match morphism. */
public final void destroyMatch(OrdinaryMorphism match) {
if (match != null)
match.dispose();
}
/**
* Here:<br>
* cond.getSource() == morph.getSource()<br>
* Returns morphism :<br>
* m = morph.getTarget() -> cond.getTargetCopy()
*/
public OrdinaryMorphism shiftApplCondRight(
final OrdinaryMorphism cond,
final OrdinaryMorphism morph) {
if (cond.getSource() == morph.getSource()) {
final OrdinaryMorphism condIso = cond.getTarget().isomorphicCopy();
if (condIso == null)
return null;
OrdinaryMorphism shiftCond = (cond instanceof NestedApplCond)?
BaseFactory.theFactory().createGeneralMorphism(morph.getTarget(), condIso.getTarget())
: BaseFactory.theFactory().createMorphism(morph.getTarget(), condIso.getTarget());
Enumeration<GraphObject> condDom = cond.getDomain();
while (condDom.hasMoreElements()) {
GraphObject go = condDom.nextElement();
if (go.isNode()) {
GraphObject condImg = cond.getImage(go);
if (condImg != null) {
GraphObject morphImg = morph.getImage(go);
GraphObject isoImg = condIso.getImage(condImg);
if (morphImg != null && isoImg != null) {
try {
shiftCond.addMapping(morphImg, isoImg);
} catch (BadMappingException ex) {}
}
}
}
}
condDom = cond.getDomain();
while (condDom.hasMoreElements()) {
GraphObject go = condDom.nextElement();
if (go.isArc()) {
GraphObject condImg = cond.getImage(go);
if (condImg != null) {
GraphObject morphImg = morph.getImage(go);
GraphObject isoImg = condIso.getImage(condImg);
if (morphImg != null) {
if (isoImg != null) {
try {
shiftCond.addMapping(morphImg, isoImg);
} catch (BadMappingException ex) {}
}
}
else {
try {
shiftCond.getTarget().destroyArc((Arc)isoImg);
} catch (TypeException ex) {}
}
}
}
}
condDom = cond.getDomain();
while (condDom.hasMoreElements()) {
GraphObject go = condDom.nextElement();
if (go.isNode()) {
GraphObject condImg = cond.getImage(go);
if (condImg != null) {
GraphObject morphImg = morph.getImage(go);
GraphObject isoImg = condIso.getImage(condImg);
if (morphImg == null && isoImg != null) {
try {
shiftCond.getTarget().destroyNode((Node)isoImg);
} catch (TypeException ex) {}
}
}
}
}
return shiftCond;
}
return null;
}
/**
* Here:<br>
* cond.getSource() == morph.getTarget()<br>
* Returns morphism : morph.getSource() -> cond.getTarget()
*/
public OrdinaryMorphism shiftApplCondLeft(
final OrdinaryMorphism cond,
final OrdinaryMorphism morph) {
if (cond.getSource() == morph.getTarget()) {
OrdinaryMorphism shiftCond = (cond instanceof NestedApplCond)?
BaseFactory.theFactory().createGeneralMorphism(morph.getSource(), cond.getTarget())
: BaseFactory.theFactory().createMorphism(morph.getSource(), cond.getTarget());
if (shiftCond.completeDiagram3(morph, cond)) {
return shiftCond;
}
else {
shiftCond.dispose();
shiftCond = null;
}
}
return null;
}
/**
* Given a list of PACs. This method replaces each PAC by a General AC and
* builds a boolean formula over GACs defined as<br>
* <code>f = OR{ci}</code> as disjunction with <code>ci</code> as an element of GACs.
* After that the given list contains the GACs and the PACs are disposed.
* @param list
* A list with PACs
* @return
* A formula over GACs
*/
public Formula replacePACsByGACs(final List<OrdinaryMorphism> list) {
// replace PACs by GACs and build formula = GAC1 || GAC2 || ...
List<Evaluable> shiftEvals = new Vector<Evaluable>(list.size());
for (int k=0; k<list.size(); k++) {
OrdinaryMorphism c = list.get(k);
NestedApplCond nc = BaseFactory.theBaseFactory.createGeneralMorphism(c.getSource(), c.getTarget());
nc.getDomainObjects().addAll(c.getDomainObjects());
nc.getCodomainObjects().addAll(c.getCodomainObjects());
BaseFactory.theBaseFactory.unsetAllTransientAttrValues(nc);
// set and adjust attr context
BaseFactory.theBaseFactory.declareVariable(nc.getTarget(), (VarTuple)nc.getAttrContext().getVariables());
BaseFactory.theBaseFactory.adjustAttributeValueAlongMorphismMapping(nc);
nc.setEnabled(c.isEnabled());
nc.setName(c.getName());
if (nc.isEnabled())
shiftEvals.add(nc);
list.remove(k);
list.add(k, nc);
c.dispose();
}
Formula f = new Formula(shiftEvals, Formula.OR);
return f;
}
/**
* Given a list of NACs. This method replaces each NAC by a General AC and
* builds a boolean formula over GACs defined as<br>
* <code>f = NOT(OR{ci})</code> as disjunction with <code>ci</code> as an element of GACs.
* After that the given list contains the GACs and the NACs are disposed.
* @param list
* A list with NACs
* @return
* A formula over GACs
*/
public Formula replaceNACsByGACs(final List<OrdinaryMorphism> list) {
// replace NACs by GACs and build formula = !(GAC1 || GAC2 || ...)
List<Evaluable> shiftEvals = new Vector<Evaluable>(list.size());
for (int k=0; k<list.size(); k++) {
OrdinaryMorphism c = list.get(k);
NestedApplCond nc = BaseFactory.theBaseFactory.createGeneralMorphism(c.getSource(), c.getTarget());
nc.getDomainObjects().addAll(c.getDomainObjects());
nc.getCodomainObjects().addAll(c.getCodomainObjects());
BaseFactory.theBaseFactory.unsetAllTransientAttrValues(nc);
// set and adjust attr context
BaseFactory.theBaseFactory.declareVariable(nc.getTarget(), (VarTuple)nc.getAttrContext().getVariables());
BaseFactory.theBaseFactory.adjustAttributeValueAlongMorphismMapping(nc);
nc.setEnabled(c.isEnabled());
nc.setName(c.getName());
if (nc.isEnabled())
shiftEvals.add(nc);
list.remove(k);
list.add(k, nc);
c.dispose();
}
Formula f = new Formula(Formula.NOT, new Formula(shiftEvals, Formula.OR), null);
return f;
}
public void extendAttrContextVariableByPrefix(final Rule rule, final String prefix, final String oppositePrefix) {
VarTuple varsm = (VarTuple) rule.getAttrContext().getVariables();
for (int i = 0; i < varsm.getSize(); i++) {
final VarMember vm = varsm.getVarMemberAt(i);
final String from = vm.getName();
if (from.startsWith(prefix)
|| from.startsWith(oppositePrefix)) {
continue;
}
final String to = prefix+from;
// System.out.println(from+" "+to);
vm.getDeclaration().setName(to);
// rename variables in left/right graphs of morphs
setAttributeVariable(rule.getSource(), from, to, rule.getAttrContext(), varsm);
setAttributeVariable(rule.getTarget(), from, to, rule.getAttrContext(), varsm);
// rename variables in conditions
final CondTuple conds = (CondTuple) rule.getAttrContext().getConditions();
renameVariableOfCondition(rule.getAttrContext(), conds, from, to);
// rename variables in NACs
final List<OrdinaryMorphism> nacs = rule.getNACsList();
for(int j=0; j<nacs.size(); j++) {
OrdinaryMorphism nac = nacs.get(j);
setAttributeVariable(nac.getTarget(), from, to, rule.getAttrContext(), varsm);
}
// rename variables in PACs
final List<OrdinaryMorphism> pacs = rule.getPACsList();
for(int j=0; j<pacs.size(); j++) {
OrdinaryMorphism pac = pacs.get(j);
setAttributeVariable(pac.getTarget(), from, to, rule.getAttrContext(), varsm);
}
}
}
public void trimAttrContextVariableByPrefix(final Rule rule, final String prefix, final String oppositePrefix) {
VarTuple varsm = (VarTuple) rule.getAttrContext().getVariables();
for (int i = 0; i < varsm.getSize(); i++) {
VarMember vm = varsm.getVarMemberAt(i);
String from = vm.getName();
if (from.startsWith(prefix)
|| from.startsWith(oppositePrefix)) {
String to = from.substring(prefix.length());
vm.getDeclaration().setName(to);
// System.out.println(from+" "+to);
// rename variables in left/right graphs of morphs
setAttributeVariable(rule.getSource(), from, to, rule.getAttrContext(), varsm);
setAttributeVariable(rule.getTarget(), from, to, rule.getAttrContext(), varsm);
// rename variables in conditions
CondTuple conds = (CondTuple) rule.getAttrContext().getConditions();
renameVariableOfCondition(rule.getAttrContext(), conds, from, to);
// rename variables in NACs
final List<OrdinaryMorphism> nacs = rule.getNACsList();
for(int j=0; j<nacs.size(); j++) {
OrdinaryMorphism nac = nacs.get(j);
setAttributeVariable(nac.getTarget(), from, to, rule.getAttrContext(), varsm);
}
// rename variables in PACs
final List<OrdinaryMorphism> pacs = rule.getPACsList();
for(int j=0; j<pacs.size(); j++) {
OrdinaryMorphism pac = pacs.get(j);
setAttributeVariable(pac.getTarget(), from, to, rule.getAttrContext(), varsm);
}
}
}
}
/**
* Rename variable in the attribute context of the Rule r2, if a similar
* variable is already used in the attribute context of the Rule r1.
* Use defined prefix to rename variable.
* Store old name by new name into defined store container.
*/
public void renameSimilarVariable(
final Rule r1,
final Rule r2,
final String prefix,
final Hashtable<String, String> storeNewName2OldName) {
int index = 1;
String mark = String.valueOf(index);
VarTuple varsm1 = (VarTuple) r1.getAttrContext().getVariables();
VarTuple varsm2 = (VarTuple) r2.getAttrContext().getVariables();
for (int i = 0; i < varsm1.getSize(); i++) {
VarMember vm1 = varsm1.getVarMemberAt(i);
VarMember vm2 = varsm2.getVarMemberAt(vm1.getName());
if (vm2 != null) {
String from = vm2.getName();
String to = prefix.concat(vm2.getName());
while (varsm2.getVarMemberAt(to) != null
|| varsm1.getVarMemberAt(to) != null) {
to = prefix.concat(vm2.getName()).concat(mark);
mark = String.valueOf(index++);
}
if (storeNewName2OldName != null)
storeNewName2OldName.put(to, from);
vm2.getDeclaration().setName(to);
// rename variables in left/right graphs of morphs
setAttributeVariable(r2.getSource(), from, to, r2.getAttrContext(), varsm2);
setAttributeVariable(r2.getTarget(), from, to, r2.getAttrContext(), varsm2);
// rename variables in NACs
final List<OrdinaryMorphism> nacs = r2.getNACsList();
for(int j=0; j<nacs.size(); j++) {
OrdinaryMorphism nac = nacs.get(j);
setAttributeVariable(nac.getTarget(), from, to, r2.getAttrContext(), varsm2);
}
// rename variables in PACs
final List<OrdinaryMorphism> pacs = r2.getPACsList();
for(int j=0; j<pacs.size(); j++) {
OrdinaryMorphism pac = pacs.get(j);
setAttributeVariable(pac.getTarget(), from, to, r2.getAttrContext(), varsm2);
}
// rename variables in conditions
CondTuple conds = (CondTuple) r2.getAttrContext()
.getConditions();
renameVariableOfCondition(r2.getAttrContext(), conds, from, to);
}
}
}
/**
* Restores renamed variable of the defined rule.
*
* @param r
* @param storeNewName2OldName
*/
public void restoreVariableNameOfRule(
final Rule r,
final Hashtable<String, String> storeNewName2OldName) {
VarTuple varsm2 = (VarTuple) r.getAttrContext().getVariables();
for (int i = 0; i < varsm2.getSize(); i++) {
VarMember vm2 = varsm2.getVarMemberAt(i);
String from = vm2.getName();
String to = storeNewName2OldName.get(from);
if (to != null) {
vm2.getDeclaration().setName(to);
// rename variables in left/right graphs of morphs
setAttributeVariable(r.getSource(), from, to, r.getAttrContext(), varsm2);
setAttributeVariable(r.getTarget(), from, to, r.getAttrContext(), varsm2);
// rename variables in NACs
final List<OrdinaryMorphism> nacs = r.getNACsList();
for(int j=0; j<nacs.size(); j++) {
OrdinaryMorphism nac = nacs.get(j);
setAttributeVariable(nac.getTarget(), from, to, r.getAttrContext(), varsm2);
}
// rename variables in PACs
final List<OrdinaryMorphism> pacs = r.getPACsList();
for(int j=0; j<pacs.size(); j++) {
OrdinaryMorphism pac = pacs.get(j);
setAttributeVariable(pac.getTarget(), from, to, r.getAttrContext(), varsm2);
}
// rename variables in conditions
CondTuple conds = (CondTuple) r.getAttrContext()
.getConditions();
renameVariableOfCondition(r.getAttrContext(), conds, from, to);
}
}
}
/**
* Rename variable in the attribute context of the Rule r2, if a similar
* variable is already used in the attribute context of the Rule r1.
*/
public void renameSimilarVariable(Rule r1, Rule r2) {
int index = 1;
String mark = String.valueOf(index);
VarTuple varsm1 = (VarTuple) r1.getAttrContext().getVariables();
VarTuple varsm2 = (VarTuple) r2.getAttrContext().getVariables();
for (int i = 0; i < varsm1.getSize(); i++) {
VarMember vm1 = varsm1.getVarMemberAt(i);
VarMember vm2 = varsm2.getVarMemberAt(vm1.getName());
if ((vm2 != null)
/*
* &&
* vm1.getDeclaration().getTypeName().equals(vm2.getDeclaration().getTypeName())
*/) {
String from = vm2.getName();
String to = vm2.getName() + mark;
while (varsm2.getVarMemberAt(to) != null) {
mark = String.valueOf(index++);
to = vm2.getName() + mark;
}
vm2.getDeclaration().setName(to);
// System.out.println(" variable "+from+" renamed to :
// "+vm2.getName());
// rename variables in left/right graphs of morphs
setAttributeVariable(r2.getSource(), from, to, r2.getAttrContext(), varsm2);
setAttributeVariable(r2.getTarget(), from, to, r2.getAttrContext(), varsm2);
// System.out.println("--------rename variables in
// conditions--------");
// rename variables in conditions
CondTuple conds = (CondTuple) r2.getAttrContext()
.getConditions();
renameVariableOfCondition(r2.getAttrContext(), conds, from, to);
// rename variables in NACs
final List<OrdinaryMorphism> nacs = r2.getNACsList();
for(int j=0; j<nacs.size(); j++) {
OrdinaryMorphism nac = nacs.get(j);
setAttributeVariable(nac.getTarget(), from, to, r2.getAttrContext(), varsm2);
}
// rename variables in PACs
final List<OrdinaryMorphism> pacs = r2.getPACsList();
for(int j=0; j<pacs.size(); j++) {
OrdinaryMorphism pac = pacs.get(j);
setAttributeVariable(pac.getTarget(), from, to, r2.getAttrContext(), varsm2);
}
}
}
}
/**
* Rename variable in the attribute context of the OrdinaryMorphism m2, if a
* similar variable is already used in the attribute context of the
* OrdinaryMorphism m1.
*/
public void renameSimilarVariable(OrdinaryMorphism m1, OrdinaryMorphism m2) {
int index = 1;
String mark = String.valueOf(index);
VarTuple varsm1 = (VarTuple) m1.getAttrContext().getVariables();
VarTuple varsm2 = (VarTuple) m2.getAttrContext().getVariables();
for (int i = 0; i < varsm1.getSize(); i++) {
VarMember vm1 = varsm1.getVarMemberAt(i);
VarMember vm2 = varsm2.getVarMemberAt(vm1.getName());
if ((vm2 != null)
&& vm1.getDeclaration().getTypeName().equals(
vm2.getDeclaration().getTypeName())) {
String from = vm2.getName();
String to = vm2.getName().concat(mark);
while (varsm2.getVarMemberAt(to) != null) {
mark = String.valueOf(index++);
to = vm2.getName().concat(mark);
}
vm2.getDeclaration().setName(to);
// System.out.println(" variable "+from+" renamed to :
// "+vm2.getName());
// rename variables in left/right graphs of morphs
setAttributeVariable(m2.getSource(), from, to, m2.getAttrContext(), varsm2);
setAttributeVariable(m2.getTarget(), from, to, m2.getAttrContext(), varsm2);
// System.out.println("--------rename variables in
// conditions--------");
CondTuple conds = (CondTuple) m2.getAttrContext()
.getConditions();
renameVariableOfCondition(m2.getAttrContext(), conds, from, to);
}
}
}
public void renameVariableOfCondition(
final AttrContext ac,
CondTuple conds,
String from,
String to) {
// rename variables in conditions
for (int j = 0; j < conds.getSize(); j++) {
CondMember cm = conds.getCondMemberAt(j);
Vector<String> v1 = cm.getAllVariables();
if (v1.contains(from)) {
JexExpr oldExpr = (JexExpr) cm.getExpr();
// System.out.println(cm.getExpr());
// test output
// System.out.println("ast: "+oldExpr.getAST());
// System.out.println("Children of ast:
// "+oldExpr.getAST().jjtGetNumChildren());
// Vector<String> variables = new Vector<String>();
// oldExpr.getAllVariables(variables);
/*
* System.out.println("Variables of ast: "+variables.size());
* for(int ii=0; ii<variables.size(); ii++) {
* System.out.println("ast variable:
* "+(String)variables.get(ii)); }
*/
//
findPrimaryAndReplace((SimpleNode) oldExpr.getAST(), from, to, ac,
null);
// System.out.println(cm.getExpr());
// System.out.println("--------------------------");
}
}
}
public void renameVariableOfExpression(
final AttrContext ac,
ValueTuple value, String from,
String to) {
// rename variables in conditions
for (int j = 0; j < value.getSize(); j++) {
ValueMember vm = value.getValueMemberAt(j);
Vector<String> v1 = vm.getAllVariableNamesOfExpression();
if (v1.contains(from)) {
JexExpr oldExpr = (JexExpr) vm.getExpr();
// test output
// System.out.println("ast: "+oldExpr.getAST());
// System.out.println("Children of ast:
// "+oldExpr.getAST().jjtGetNumChildren());
// Vector<String> variables = new Vector<String>();
// oldExpr.getAllVariables(variables);
/*
* System.out.println("Variables of ast: "+variables.size());
* for(int ii=0; ii<variables.size(); ii++) {
* System.out.println("ast variable:
* "+(String)variables.get(ii)); }
*/
//
findPrimaryAndReplace((SimpleNode) oldExpr.getAST(), from, to, ac,
null);
// System.out.println("--------------------------");
}
}
}
protected void setAttributeVariable(
final Graph g,
final String from,
final String to,
final AttrContext ac,
final VarTuple vars) {
// System.out.println("OrdinaryMorphism.setAttributeVariable ...");
Iterator<?> e = g.getNodesSet().iterator();
while (e.hasNext()) {
GraphObject obj = (GraphObject) e.next();
if (obj.getAttribute() == null)
continue;
ValueTuple fromObj = (ValueTuple) obj.getAttribute();
for (int i = 0; i < fromObj.getSize(); i++) {
ValueMember fromVM = fromObj.getValueMemberAt(i);
if (fromVM.isSet()) {
if (fromVM.getExpr().isVariable()) {
if (fromVM.getExprAsText().equals(from)
&& (vars.getVarMemberAt(to) != null)) {
fromVM.setExprAsText(to);
if (!fromVM.isTransient())
fromVM.setTransient(vars.getVarMemberAt(to).isTransient()); // NEW
// System.out
// .println(">>>>>BaseFactory:: set Attribute expr (is Variable) : "
// + from + " to " + to);
}
} else if (fromVM.getExpr().isComplex()) {
// System.out.println("\n--------- set Attribute (is
// Complex) : "+fromVM.getName()+" =
// "+fromVM.getExprAsText());
// VarMember toVM = vars.getVarMemberAt(to);
// System.out.println("(to) VarMember :
// "+toVM.getName()+" "+toVM);
JexExpr oldExpr = (JexExpr) fromVM.getExpr();
// System.out.println("ast: "+oldExpr.getAST());
// System.out.println("Children of ast:
// "+oldExpr.getAST().jjtGetNumChildren());
Vector<String> variables = new Vector<String>();
oldExpr.getAllVariables(variables);
/*
* System.out.println("Variables of ast:
* "+variables.size()); for(int ii=0; ii<variables.size();
* ii++) { System.out.println("ast variable:
* "+(String)variables.get(ii)); }
*/
findPrimaryAndReplace((SimpleNode) oldExpr.getAST(),
from, to, ac, vars);
fromVM.setTransient(true); // NEW
// System.out.println("------------------------------");
}
}
}
}
e = g.getArcsSet().iterator();
while (e.hasNext()) {
GraphObject obj = (GraphObject) e.next();
if (obj.getAttribute() == null)
continue;
ValueTuple fromObj = (ValueTuple) obj.getAttribute();
for (int i = 0; i < fromObj.getSize(); i++) {
ValueMember fromVM = fromObj.getValueMemberAt(i);
if (fromVM.isSet()) {
if (fromVM.getExpr().isVariable()) {
if (fromVM.getExprAsText().equals(from)
&& (vars.getVarMemberAt(to) != null)) {
fromVM.setExprAsText(to);
// System.out
// .println(">>>>>BaseFactory:: set Attribute expr (is Variable) : "
// + from + " to " + to);
}
} else if (fromVM.getExpr().isComplex()) {
// System.out.println("\n--------- set Attribute (is
// Complex) : "+fromVM.getName()+" =
// "+fromVM.getExprAsText());
// VarMember toVM = vars.getVarMemberAt(to);
// System.out.println("(to) VarMember :
// "+toVM.getName()+" "+toVM);
JexExpr oldExpr = (JexExpr) fromVM.getExpr();
// System.out.println("ast: "+oldExpr.getAST());
// System.out.println("Children of ast:
// "+oldExpr.getAST().jjtGetNumChildren());
Vector<String> variables = new Vector<String>();
oldExpr.getAllVariables(variables);
/*
* System.out.println("Variables of ast:
* "+variables.size()); for(int ii=0; ii<variables.size();
* ii++) { System.out.println("ast variable:
* "+(String)variables.get(ii)); }
*/
findPrimaryAndReplace((SimpleNode) oldExpr.getAST(),
from, to, ac, vars);
// System.out.println("------------------------------");
}
}
}
}
}
private void findPrimaryAndReplace(
final SimpleNode node,
final String from,
final String to,
final AttrContext ac,
final VarTuple vars) {
// System.out.println("OrdinaryMorphism.findPrimaryAndChange: in "+node);
SymbolTable symbs = ac;
for (int j = 0; j < node.jjtGetNumChildren(); j++) {
SimpleNode n = (SimpleNode) node.jjtGetChild(j);
// System.out.println(j+" Child of ast: "+n+" is "+n.getString());
if (n instanceof ASTPrimaryExpression
|| n instanceof ASTId) {
// System.out.println("OrdinaryMorphism.findPrimaryAndChange:
// ASTPrimaryExpression: "+n+" NumChildren: " +n.jjtGetNumChildren());
/*
for (int j1 = 0; j1 < n.jjtGetNumChildren(); j1++) {
SimpleNode n1 = (SimpleNode) n.jjtGetChild(j1);
if (n1 instanceof ASTExpression) {
findPrimaryAndReplace(n1, from, to, ac, vars);
}
}
*/
// String ident = ((ASTPrimaryExpression) n).getIdentifier();
// System.out.println("Identifier: "+ ident+" "+
// ((ASTPrimaryExpression) n).getString());
if (n.getString().equals(from)) {
// System.out.println("from is found: getString()=
// "+n.getString()+" toString()= "+n.toString()+"
// hasStringType()= "+n.hasStringType()+" getSymbolTable()=
// "+n.getSymbolTable());
// SymbolTable symbs = SimpleNode.getSymbolTable();
// System.out.println("SymbolTable: "+from+" type=
// "+symbs.getType(from)+" expr= "+ symbs.getExpr(from));
// System.out.println("SymbolTable: "+to+" type=
// "+symbs.getType(to)+" expr= "+ symbs.getExpr(to));
boolean to_found = false;
ContextView context = (ContextView) symbs;
VarTuple vt = (VarTuple) context.getVariables();
for (int i = 0; i < vt.getSize(); i++) {
VarMember vm = vt.getVarMemberAt(i);
// System.out.println(vm.getName()+" "+vm);
if (vm.getName().equals(to)) {
to_found = true;
// System.out.println(to+" exists in SymbolTable ::
// "+vm.getName()+" "+vm);
HandlerType t = vm.getDeclaration().getType();
try {
HandlerExpr expression = vm.getHandler()
.newHandlerExpr(t, to);
// System.out.println(expression.getAST());
SimpleNode test = (SimpleNode) expression
.getAST().jjtGetChild(0);
// System.out.println(test);
node.replaceChild(n, test);
// System.out.println("child replaced:
// getString()=
// "+node.jjtGetChild(0).getString()+"
// "+node.jjtGetChild(0).toString());
} catch (AttrHandlerException ex) {}
}
}
if (!to_found) {
// System.out.println("Something wrong: "+to+" NOT FOUND
// in SymbolTable! Try to replace if variable exists in
// VarTuple.");
for (int i = 0; i < vars.getSize(); i++) {
VarMember vm = vars.getVarMemberAt(i);
// System.out.println(vm.getName()+" "+vm);
if (vm.getName().equals(to)) {
to_found = true;
// System.out.println(to+" exists in vars
// "+vm.getName()+" "+vm);
HandlerType t = vm.getDeclaration().getType();
try {
HandlerExpr expression = vm.getHandler()
.newHandlerExpr(t, to);
// System.out.println(expression.getAST());
SimpleNode test = (SimpleNode) expression
.getAST().jjtGetChild(0);
// System.out.println(test);
node.replaceChild(n, test);
// System.out.println("child replaced:
// getString()=
// "+node.jjtGetChild(0).getString()+"
// "+node.jjtGetChild(0).toString());
} catch (AttrHandlerException ex) {}
}
}
}
} else if (n.getString().contains(from)) {
// System.out.println("Take Child of ast: "+n);
findPrimaryAndReplace(n, from, to, ac, vars);
}
} else {
// System.out.println("Take Child of ast: "+n);
findPrimaryAndReplace(n, from, to, ac, vars);
}
}
}
/* Graph overlappings */
/**
* Computes possible overlappings with defined size of inclusion of this and
* another graph g. The return value is an enumeration of pairs of morphisms.
* Each pair consists of a morphism from thisGraph to the overlap graph and a
* morphism from the other graph to the overlap graph.
*/
public Enumeration<Pair<OrdinaryMorphism, OrdinaryMorphism>> overlappingSet(
final Graph thisGraph,
final Graph g,
final int sizeOfInclusion,
final boolean union,
final boolean withIsomorphic) {
final Vector<Pair<OrdinaryMorphism, OrdinaryMorphism>> oSet = new Vector<Pair<OrdinaryMorphism, OrdinaryMorphism>>();
Vector<OrdinaryMorphism> subs = new Vector<OrdinaryMorphism>();
final Enumeration<GraphObject> itsGOs = thisGraph.getElements();
final Vector<GraphObject> itsGOSet = new Vector<GraphObject>();
int size = 0;
int minGraphSize;
if (union)
minGraphSize = 0;
else
minGraphSize = 1;
while (itsGOs.hasMoreElements()) {
itsGOSet.addElement(itsGOs.nextElement());
size++;
}
if (sizeOfInclusion == -1) {
// compute all possible inclusions
for (int i = minGraphSize; i <= size; i++) {
subs = generateAllSubgraphsWithInclusionsOfSize(thisGraph, i, itsGOSet,
subs, withIsomorphic, null, false);
}
} else if (sizeOfInclusion >= minGraphSize) {
subs = generateAllSubgraphsWithInclusionsOfSize(thisGraph, sizeOfInclusion,
itsGOSet, subs, withIsomorphic, null, false);
} else
return oSet.elements();
makeOverlappingPairs(thisGraph, g, subs, oSet);
subs.clear();
return (oSet.elements());
}
public Enumeration<Pair<OrdinaryMorphism, OrdinaryMorphism>> overlappingSet(
final Graph thisGraph,
final Graph g,
final int sizeOfInclusion,
final Hashtable<Object, Object> objectMap,
final boolean union,
final boolean withIsomorphic) {
final Vector<Pair<OrdinaryMorphism, OrdinaryMorphism>> oSet = new Vector<Pair<OrdinaryMorphism, OrdinaryMorphism>>();
Vector<OrdinaryMorphism> subs = new Vector<OrdinaryMorphism>();
final Enumeration<GraphObject> itsGOs = thisGraph.getElements();
final Vector<GraphObject> itsGOSet = new Vector<GraphObject>();
int size = 0;
int minGraphSize;
if (union)
minGraphSize = 0;
else
minGraphSize = 1;
while (itsGOs.hasMoreElements()) {
itsGOSet.addElement(itsGOs.nextElement());
size++;
}
List<Object> requiredInsideSubgraphs = null;
if (objectMap != null && !objectMap.isEmpty())
requiredInsideSubgraphs = new Vector<Object>(objectMap.keySet());
if (sizeOfInclusion == -1) {
// compute all possible inclusions
for (int i = minGraphSize; i <= size; i++) {
subs = generateAllSubgraphsWithInclusionsOfSize(thisGraph, i, itsGOSet,
subs, withIsomorphic, requiredInsideSubgraphs, true);
}
} else if (sizeOfInclusion >= minGraphSize) {
subs = generateAllSubgraphsWithInclusionsOfSize(thisGraph, sizeOfInclusion,
itsGOSet, subs, withIsomorphic, requiredInsideSubgraphs, true);
} else
return oSet.elements();
makeOverlappingPairs(thisGraph, g, subs, oSet, objectMap);
subs.clear();
return (oSet.elements());
}
private void makeOverlappingPairs(
final Graph thisGraph,
final Graph g,
final Vector<OrdinaryMorphism> subs,
final Vector<Pair<OrdinaryMorphism, OrdinaryMorphism>> oSet,
final Hashtable<Object, Object> objectMap) {
if (objectMap == null || objectMap.isEmpty()) {
makeOverlappingPairs(thisGraph, g, subs, oSet);
return;
}
// make mapping with respect to required object map
MorphCompletionStrategy strategy = (thisGraph.getTypeSet().hasInheritance())?
(new Completion_InheritCSP()): (new Completion_InjCSP());
for (int i = 0; i < subs.size(); i++) {
OrdinaryMorphism h = subs.elementAt(i);
Pair<Rule, Pair<OrdinaryMorphism, OrdinaryMorphism>>
rulePair = (BaseFactory.theFactory()).constructIsomorphicRule(h, true, false);
if (rulePair == null)
continue;
// Rule r = rulePair.first;
Match match = (BaseFactory.theFactory()).createMatch(rulePair.first, g, true);
match.setCompletionStrategy(strategy, true);
while (match.nextCompletion()) {
boolean allOfObjectFlow = true;
int count = 0;
Enumeration<GraphObject> dom = match.getDomain();
while (dom.hasMoreElements()) {
// obj corresponds to an object of L2 which is key of the objectMap
final GraphObject obj = dom.nextElement();
if (rulePair.second.first.getInverseImage(obj).hasMoreElements()) {
// obj1 is equivalent to obj
final GraphObject obj1 = rulePair.second.first.getInverseImage(obj).nextElement();
// objL2 is the object of L2 which can be a key of the objectMap
final GraphObject objL2 = h.getImage(obj1);
// obj2 is the value of the key (objL2) of the objectMap
final GraphObject obj2 = (GraphObject)objectMap.get(objL2);
if (obj2 != null) {
// objR1 is the object of R1
final GraphObject objR1 = match.getImage(obj);
if (obj2 == objR1) {
count++;
}
}
} else {
allOfObjectFlow = false;
break;
}
}
allOfObjectFlow = allOfObjectFlow && (count == objectMap.size());
if (allOfObjectFlow && match.isValid(true)) {
// constract the overlapping graph
OrdinaryMorphism rStar = g.isomorphicCopy();
if (rStar != null) {
Match m = (BaseFactory.theFactory()).createMatch(
rulePair.first, rStar.getImage(), true);
if (m.doCompose(match, rStar)) {
// try execute step; it may throw an exception
// when multiplicity constraint failed
try {
// Variables in graph are allowed
OrdinaryMorphism ms = (OrdinaryMorphism) TestStep.execute(m, true);
if (ms != null) {
OrdinaryMorphism mStar = rulePair.second.second.compose(ms);
if (mStar != null) {
// make result overlapping pair
final Pair<OrdinaryMorphism, OrdinaryMorphism>
p = new Pair<OrdinaryMorphism, OrdinaryMorphism>(
mStar, rStar);
oSet.addElement(p);
}
ms.dispose();
ms = null;
} else {
rStar.dispose();
rStar = null;
}
} catch (TypeException e) {}
} else {
rStar.dispose();
rStar = null;
}
m.dispose();
m = null;
}
}
}
// dispose helpers
match.dispose();
rulePair.second.first.dispose();
rulePair.second.second.dispose();
rulePair.first.disposeSuper();
h.dispose(true, false);
rulePair.first = null;
h = null;
rulePair.second.first = null;
rulePair.second.second = null;
rulePair = null;
// System.gc();
}
}
private void makeOverlappingPairs(
final Graph thisGraph,
final Graph g,
final Vector<OrdinaryMorphism> subs,
final Vector<Pair<OrdinaryMorphism, OrdinaryMorphism>> oSet) {
MorphCompletionStrategy strategy = (thisGraph.getTypeSet().hasInheritance())?
(new Completion_InheritCSP()): (new Completion_InjCSP());
for (int i = 0; i < subs.size(); i++) {
OrdinaryMorphism h = subs.elementAt(i);
makeOverlappingPair(thisGraph, g, h, strategy, oSet);
h.dispose(true, false);
h = null;
}
}
private void makeOverlappingPair(
final Graph thisGraph,
final Graph g,
final OrdinaryMorphism inclusion,
final MorphCompletionStrategy strategy,
final Vector<Pair<OrdinaryMorphism, OrdinaryMorphism>> oSet) {
Pair<Rule, Pair<OrdinaryMorphism, OrdinaryMorphism>>
rulePair = (BaseFactory.theFactory()).constructIsomorphicRule(inclusion, true, false);
if (rulePair == null)
return;
// Rule r = rulePair.first;
Match match = (BaseFactory.theFactory()).createMatch(rulePair.first, g, true);
match.setCompletionStrategy(strategy, true);
if (match.getCompletionStrategy() instanceof Completion_InheritCSP) {
((Completion_InheritCSP)match.getCompletionStrategy()).initialize(match);
match.getTarget().getTypeObjectsMap().clear();
match.getCompletionStrategy().resetTypeMap(g);
}
boolean nextMatch = true;
while (nextMatch) {
nextMatch = match.nextCompletion();
if (nextMatch && match.isValid(true)) {
OrdinaryMorphism rStar = g.isomorphicCopy();
if (rStar == null)
break;
Match m = (BaseFactory.theFactory()).createMatch(rulePair.first, rStar.getTarget(), true);
boolean compose = false;
if (match.getCompletionStrategy() instanceof Completion_InheritCSP) {
compose = m.doComposeInherit(match, rStar);
} else {
compose = m.doCompose(match, rStar);
}
if (compose) {
if (!(match.getCompletionStrategy() instanceof Completion_InheritCSP)
|| BaseFactory.theFactory().replaceParentByChild(rulePair.first, m, rStar)) {
// m.adaptAttrContextValues(match.getAttrContext());
// try execute step; it may throw an exception
// when multiplicity constraint failed
try {
// Variables in graph are allowed
OrdinaryMorphism ms = (OrdinaryMorphism) TestStep.execute(m, true);
if (ms != null) {
OrdinaryMorphism mStar = rulePair.second.second.compose(ms);
if (mStar != null) {
final Pair<OrdinaryMorphism, OrdinaryMorphism>
p = new Pair<OrdinaryMorphism, OrdinaryMorphism>(
mStar, rStar);
oSet.addElement(p);
} else {
rStar.dispose();
rStar = null;
}
ms.dispose();
ms = null;
}
} catch (TypeException e) {}
}
} else {
rStar.dispose();
rStar = null;
}
m.dispose();
m = null;
}
}
// dispose helpers
match.dispose();
rulePair.second.first.dispose();
rulePair.second.second.dispose();
rulePair.first.disposeSuper();
rulePair.second.first = null;
rulePair.second.second = null;
rulePair.first = null;
rulePair = null;
}
private void makeOverlappingPairByPredefinedIntersection(
final Graph thisGraph,
final Graph g,
final Hashtable<Object, Object> intersection, // thisGraph -> g
final OrdinaryMorphism inclusion, // subgraph -> thisGraph
final MorphCompletionStrategy strategy,
final Vector<Pair<OrdinaryMorphism, OrdinaryMorphism>> oSet) {
// System.out.println("===) BaseFactory.makeOverlappingPair");
Pair<Rule, Pair<OrdinaryMorphism, OrdinaryMorphism>>
rulePair = (BaseFactory.theFactory()).constructIsomorphicRule(inclusion, true, false);
if (rulePair == null)
return;
// Rule r = rulePair.first;
Match match = (BaseFactory.theFactory()).createMatch(rulePair.first, g, true);
match.setCompletionStrategy(strategy, true);
// set match mapping: first of nodes
boolean mappingOK = true;
Enumeration<Object> keys = intersection.keys();
while (keys.hasMoreElements() && mappingOK) {
Object thisGraph_obj = keys.nextElement();
if (thisGraph_obj instanceof Node) {
Object g_obj = intersection.get(thisGraph_obj);
if (inclusion.getInverseImage((GraphObject) thisGraph_obj).hasMoreElements()) {
GraphObject sub_obj = inclusion.getInverseImage((GraphObject) thisGraph_obj).nextElement();
GraphObject lhs_obj = rulePair.second.first.getImage(sub_obj);
if (lhs_obj != null && g_obj != null) {
try {
// match.addMapping(lhs_obj, (GraphObject)g_obj);
match.addChild2ParentMapping(lhs_obj, (GraphObject)g_obj);
} catch (BadMappingException ex) {
mappingOK = false;
}
} else {
mappingOK = false;
}
} else {
mappingOK = false;
}
}
}
// set match mapping: now of edges
keys = intersection.keys();
while (keys.hasMoreElements() && mappingOK) {
Object thisGraph_obj = keys.nextElement();
if (thisGraph_obj instanceof Arc) {
Object g_obj = intersection.get(thisGraph_obj);
if (inclusion.getInverseImage((GraphObject) thisGraph_obj).hasMoreElements()) {
GraphObject sub_obj = inclusion.getInverseImage((GraphObject) thisGraph_obj).nextElement();
GraphObject lhs_obj = rulePair.second.first.getImage(sub_obj);
if (lhs_obj != null && g_obj != null) {
try {
match.addMapping(lhs_obj, (GraphObject)g_obj);
// match.addChild2ParentMapping(lhs_obj, (GraphObject)g_obj);
} catch (BadMappingException ex) {
mappingOK = false;
}
} else {
mappingOK = false;
}
} else {
mappingOK = false;
}
}
}
if (match.isTotal() && match.isValid(true)) {
OrdinaryMorphism rStar = g.isomorphicCopy();
if (rStar != null) {
Match m = (BaseFactory.theFactory()).createMatch(rulePair.first, rStar.getTarget(), true);
boolean compose = false;
if (match.getCompletionStrategy() instanceof Completion_InheritCSP) {
compose = m.doComposeInherit(match, rStar);
} else {
compose = m.doCompose(match, rStar);
}
if (compose) {
if (!(match.getCompletionStrategy() instanceof Completion_InheritCSP)
|| BaseFactory.theFactory().replaceParentByChild(rulePair.first, m, rStar)) {
// m.adaptAttrContextValues(match.getAttrContext());
// try execute step; it may throw an exception
// when multiplicity constraint failed
try {
// Variables in graph are allowed
OrdinaryMorphism ms = (OrdinaryMorphism) TestStep.execute(m, true);
if (ms != null) {
OrdinaryMorphism mStar = rulePair.second.second.compose(ms);
if (mStar != null) {
final Pair<OrdinaryMorphism, OrdinaryMorphism>
p = new Pair<OrdinaryMorphism, OrdinaryMorphism>(
mStar, rStar);
oSet.addElement(p);
}
ms.dispose();
ms = null;
}
} catch (TypeException e) {}
}
} else {
rStar.dispose();
rStar = null;
}
}
}
// dispose helpers
match.dispose();
rulePair.second.first.dispose();
rulePair.second.second.dispose();
rulePair.first.disposeSuper();
rulePair.second.first = null;
rulePair.second.second = null;
rulePair.first = null;
rulePair = null;
}
/**
* Computes all possible overlappings (withoutdisjoint union) of this and
* another graph g. The return value is an enumeration of pairs of morphisms.
* Each pair consists of a morphism from thisGraph to the overlap graph and a
* morphism from the other graph to the overlap graph.
*/
public Enumeration<Pair<OrdinaryMorphism, OrdinaryMorphism>> overlapSet(
final Graph thisGraph,
final Graph g,
final boolean withIsomorphic) {
return overlappingSet(thisGraph, g, -1, false, withIsomorphic);
}
/**
* Compute all possible overlappings of this and another graph g. The return
* value is an eneration of pairs of morphisms. Each pair consists of a
* morphism from thisGraph to the overlap graph and a morphism from the other graph
* to the overlap graph.
*/
public Enumeration<Pair<OrdinaryMorphism, OrdinaryMorphism>> overlapSet(
final Graph thisGraph,
final Graph g,
final boolean union,
final boolean withIsomorphic) {
return overlappingSet(thisGraph, g, -1, union, withIsomorphic);
}
/**
* Computes an overlapping set.
*
* @param g
* The graph to overlap with
* @param withIsomorphic
* true if isomorphic overlappings should be preserved,
* otherwise only one of isomorphic overlappings preserved,
* the other will be deleted
*/
public Enumeration<Pair<OrdinaryMorphism, OrdinaryMorphism>> getOverlappings(
final Graph thisGraph,
final Graph g, final boolean withIsomorphic) {
return getOverlappings(thisGraph, g, false, withIsomorphic);
}
/**
* Computes an overlapping set.
*
* @param g
* The graph to overlap with
* @param disjunion
* true if disjoint union
* @param withIsomorphic
* true if isomorphic overlappings should be preserved,
* otherwise only one of isomorphic overlappings preserved,
* the other will be deleted
*/
public Enumeration<Pair<OrdinaryMorphism, OrdinaryMorphism>> getOverlappings(
final Graph thisGraph,
final Graph g, final boolean disjunion,
final boolean withIsomorphic) {
return overlapSet(thisGraph, g, disjunion, withIsomorphic);
}
/**
* Computes an overlapping set.
*
* @param thisGraph
* A given graph
* @param g
* A graph to overlap with
* @param sizeOfInclusion
* The number of elements of an overlapping part
* @param withIsomorphic
* It is <code>true</code> if isomorphic overlappings should be preserved,
* otherwise only one of isomorphic overlappings preserved,
* the other will be ignored.
*
* @return
* An enumeration with pairs of the overlapping morphisms
*/
public Enumeration<Pair<OrdinaryMorphism, OrdinaryMorphism>> getOverlappings(
final Graph thisGraph,
final Graph g,
final int sizeOfInclusion,
final boolean withIsomorphic) {
return overlappingSet(thisGraph, g, sizeOfInclusion, false, withIsomorphic);
}
/**
* Computes an overlapping set.
*
* @param g
* The graph to overlap with
* @param sizeOfInclusions
* size of elements of the overlapping part
* @param disjunion
* true if disjoint union
* @param withIsomorphic
* true if isomorphic overlappings should be preserved,
* otherwise only one of isomorphic overlappings preserved,
* the other will be deleted
*/
public Enumeration<Pair<OrdinaryMorphism, OrdinaryMorphism>> getOverlappings(
final Graph thisGraph,
final Graph g,
int sizeOfInclusions,
boolean disjunion,
boolean withIsomorphic) {
return overlappingSet(thisGraph, g, sizeOfInclusions, disjunion, withIsomorphic);
}
public Enumeration<Pair<OrdinaryMorphism, OrdinaryMorphism>> getOverlappings(
final Graph thisGraph,
final Graph g,
final int sizeOfInclusion,
final Hashtable<Object, Object> objectMap,
boolean disjunion,
boolean withIsomorphic) {
return overlappingSet(thisGraph, g, sizeOfInclusion, objectMap, disjunion, withIsomorphic);
}
public Enumeration<Pair<OrdinaryMorphism, OrdinaryMorphism>> getOverlappingByPredefinedIntersection(
final Graph thisGraph,
final Graph g,
final Hashtable<Object, Object> intersection) {
if (intersection != null && !intersection.isEmpty()) {
final Set<Object> intersectionOfThisGraph = intersection.keySet();
List<GraphObject> goSet = new Vector<GraphObject>();
Iterator<Object> keys = intersectionOfThisGraph.iterator();
while (keys.hasNext()) {
Object obj = keys.next();
if (obj instanceof Node)
goSet.add(0, (GraphObject) obj);
else
goSet.add((GraphObject) obj);
}
OrdinaryMorphism inclusion = this.makeInclusion(thisGraph, goSet);
if (inclusion != null) {
// Completion_InjCSP strategy = new Completion_InjCSP();
MorphCompletionStrategy strategy = null;
if (thisGraph.getTypeSet().hasInheritance())
strategy = new Completion_InheritCSP();
else
strategy = new Completion_InjCSP();
final Vector<Pair<OrdinaryMorphism, OrdinaryMorphism>>
oSet = new Vector<Pair<OrdinaryMorphism, OrdinaryMorphism>>(1);
makeOverlappingPairByPredefinedIntersection(thisGraph, g, intersection, inclusion, strategy, oSet);
if (!oSet.isEmpty())
return oSet.elements();
}
}
return null;
}
public Enumeration<Pair<OrdinaryMorphism, OrdinaryMorphism>> getOverlappingByPartialPredefinedIntersection(
final Graph thisGraph,
final Graph g,
final List<Object> requiredInsideSubgraphs,
final Hashtable<Object, Object> partialIntersection,
boolean onlyRequiredObjectsInsideSubgraphs) {
final Vector<Pair<OrdinaryMorphism, OrdinaryMorphism>>
oSet = new Vector<Pair<OrdinaryMorphism, OrdinaryMorphism>>();
Vector<OrdinaryMorphism> subs = new Vector<OrdinaryMorphism>();
final Vector<GraphObject> itsGOSet = new Vector<GraphObject>();
final Enumeration<GraphObject> itsGOs = thisGraph.getElements();
int size = 0;
while (itsGOs.hasMoreElements()) {
itsGOSet.addElement(itsGOs.nextElement());
}
size = (itsGOSet.size() <= g.getSize())? itsGOSet.size() : g.getSize();
int mins = (requiredInsideSubgraphs.size()>1)? requiredInsideSubgraphs.size(): 1;
// compute all possible inclusions
for (int i = mins; i <= size; i++) {
subs = generateAllSubgraphsWithInclusionsOfSize(thisGraph, i, itsGOSet,
subs, false, requiredInsideSubgraphs, onlyRequiredObjectsInsideSubgraphs);
}
makeOverlappingPairs(thisGraph, g, subs, oSet, partialIntersection);
subs.clear();
return (oSet.elements());
}
/**
* Returns a set of OrdinaryMorphism with
* the source graph is a subgraph of the given Graph <code>thisGraph</code>
* and the target graph is the given Graph <code>thisGraph</code>.
*/
public Vector<OrdinaryMorphism> generateAllSubgraphs(
final Graph thisGraph,
int sizeOfInclusions,
boolean union,
boolean withIsomorphic) {
Vector<OrdinaryMorphism> subs = new Vector<OrdinaryMorphism>(0);
Enumeration<GraphObject> itsGOs = thisGraph.getElements();
Vector<GraphObject> itsGOSet = new Vector<GraphObject>();
int size = 0;
int minGraphSize;
if (union)
minGraphSize = 0;
else
minGraphSize = 1;
while (itsGOs.hasMoreElements()) {
itsGOSet.addElement(itsGOs.nextElement());
size++;
}
if (sizeOfInclusions == -1) {
// compute all possible inclusions
for (int i = minGraphSize; i <= size; i++) {
subs = generateAllSubgraphsWithInclusionsOfSize(thisGraph,
i, itsGOSet,
subs, withIsomorphic, null, false);
}
} else if (sizeOfInclusions >= minGraphSize) {
subs = generateAllSubgraphsWithInclusionsOfSize(thisGraph,
sizeOfInclusions,
itsGOSet, subs, withIsomorphic, null, false);
}
// System.out.println("Graph.generateAllSubgraphs:: (subg -> g):
// "+subs.size());
return subs;
}
/**
* Returns a set of OrdinaryMorphism with
* the source graph is a subgraph of the given Graph <code>thisGraph</code>
* and the target graph is the given Graph <code>thisGraph</code>.<br>
* Additionally, the objects of the given List <code>requiredObjectsInsideSubgraphs</code>
* contained in all subgraphs.
*/
public Vector<OrdinaryMorphism> generateAllSubgraphsWithInclusionsOfSize(
final Graph thisGraph,
int i,
Vector<GraphObject> itsGOSet,
Vector<OrdinaryMorphism> inclusions,
boolean withIsomorphic,
final List<Object> requiredObjectsInsideSubgraphs,
boolean onlyRequiredObjectsInsideSubgraphs) {
if (i == 0) {
return putInclusion(thisGraph, new Vector<GraphObject>(), inclusions);
}
Vector<Integer> select = new Vector<Integer>();
if (i <= itsGOSet.size()) {
for (int j = 1; j <= i; j++) {
select.addElement(Integer.valueOf(j - 1));
}
computeSelection(thisGraph, 1, itsGOSet, select, inclusions,
requiredObjectsInsideSubgraphs, onlyRequiredObjectsInsideSubgraphs);
}
if (!withIsomorphic) {
checkIsomorphicInclusions(inclusions);
}
return inclusions;
}
private Vector<OrdinaryMorphism> computeSelection(
final Graph thisGraph,
int s,
Vector<GraphObject> itsGOSet,
Vector<Integer> select,
Vector<OrdinaryMorphism> inclusions,
final List<Object> requiredObjectsInsideSubgraph,
boolean onlyRequiredObjectsInsideSubgraphs) {
int max = itsGOSet.size();
int selSize = select.size();
int v;
Vector<GraphObject> goSet;
if (s <= selSize && s >= 1) {
try {
v = select.elementAt(s - 1).intValue();
while (v < max - selSize + s) {
// int tmp = max - selSize + s;
inclusions = computeSelection(thisGraph, s + 1, itsGOSet, select,
inclusions, requiredObjectsInsideSubgraph, onlyRequiredObjectsInsideSubgraphs);
if (s == selSize) {
goSet = makeGraphObjectSet(select, itsGOSet, requiredObjectsInsideSubgraph, onlyRequiredObjectsInsideSubgraphs);
if (!goSet.isEmpty() && thisGraph.isGraph(goSet)) {
inclusions = putInclusion(thisGraph, goSet, inclusions);
}
}
select.setElementAt(Integer.valueOf(v + 1), s - 1);
v = select.elementAt(s - 1).intValue();
}
if (s > 1) {
v = select.elementAt(s - 2).intValue();
if (v < max - selSize + s + 1) {
select.setElementAt(Integer.valueOf(v + 1), s - 2);
for (int j = 1; j <= selSize - s + 1; j++) {
select.setElementAt(Integer.valueOf(v + 1 + j), s + j
- 2);
}
}
}
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}
}
return (inclusions);
}
private Vector<GraphObject> makeGraphObjectSet(
Vector<Integer> select,
Vector<GraphObject> itsGOSet,
final List<Object> requiredObjectsInsideSubgraph,
boolean onlyRequiredObjectsInsideSubgraphs) {
final Vector<GraphObject> tmp = new Vector<GraphObject>();
if (requiredObjectsInsideSubgraph == null
|| requiredObjectsInsideSubgraph.isEmpty()) {
for (int i = 0; i < select.size(); i++) {
int v = select.elementAt(i).intValue();
tmp.addElement(itsGOSet.elementAt(v));
}
}
else if (onlyRequiredObjectsInsideSubgraphs
&& (select.size() == requiredObjectsInsideSubgraph.size())) {
// all required objects must be in subgraph but not more
int found = 0;
for (int i = 0; i < select.size(); i++) {
int v = select.elementAt(i).intValue();
GraphObject go = itsGOSet.elementAt(v);
if (requiredObjectsInsideSubgraph.contains(go)) {
found++;
tmp.addElement(go);
}
}
if (found != requiredObjectsInsideSubgraph.size()) {
tmp.clear();
}
} else { // at least as required
int found = 0;
for (int i = 0; i < select.size(); i++) {
int v = select.elementAt(i).intValue();
GraphObject go = itsGOSet.elementAt(v);
if (requiredObjectsInsideSubgraph.contains(go)) {
found++;
}
tmp.addElement(go);
}
if (found < requiredObjectsInsideSubgraph.size()) {
tmp.clear();
}
}
return tmp;
}
private Vector<OrdinaryMorphism> putInclusion(
final Graph thisGraph,
final Vector<GraphObject> goSet,
final Vector<OrdinaryMorphism> inclusions) {
Node source = null;
Node target = null;
Graph subGraph = BaseFactory.theFactory().createGraph(thisGraph.getTypeSet());
OrdinaryMorphism inclusion = (BaseFactory.theFactory()).createMorphism(
subGraph, thisGraph);
for (int i = 1; i <= goSet.size(); i++) {
GraphObject go = goSet.elementAt(i - 1);
if (go.isNode()) {
Node n = null;
try {
n = subGraph.copyNode((Node) go);
n.setContextUsage(((Node) go).getContextUsage());
} catch (TypeException e) {
// while loading the type check should be disabled,
// so this Exception should never be thrown
e.printStackTrace();
}
try {
inclusion.addMapping(n, go);
} catch (BadMappingException e) {
e.printStackTrace();
}
}
}
for (int i = 1; i <= goSet.size(); i++) {
GraphObject go = goSet.elementAt(i - 1);
if (go.isArc()) {
Enumeration<GraphObject> sources = inclusion.getInverseImage(((Arc) go)
.getSource());
if (sources.hasMoreElements()) {
source = (Node) sources.nextElement();
Enumeration<GraphObject> targets = inclusion.getInverseImage(((Arc) go)
.getTarget());
if (targets.hasMoreElements()) {
target = (Node) targets.nextElement();
Arc a = null;
try {
a = subGraph.copyArc((Arc) go, source, target);
a.setContextUsage(((Arc) go).getContextUsage());
} catch (TypeException e) {
// during load process the type check should be disabled,
// so this Exception should never be thrown
System.out.println(e);
// e.printStackTrace();
}
try {
inclusion.addMapping(a, go);
} catch (BadMappingException e) {
System.out.println(e);
// e.printStackTrace();
}
}
}
}
}
inclusions.addElement(inclusion);
return (inclusions);
}
private OrdinaryMorphism makeInclusion(
final Graph thisGraph,
final List<GraphObject> goSet) {
Node source = null;
Node target = null;
Graph subGraph = BaseFactory.theFactory().createGraph(thisGraph.getTypeSet());
OrdinaryMorphism inclusion = (BaseFactory.theFactory()).createMorphism(
subGraph, thisGraph);
for (int i = 0; i < goSet.size(); i++) {
GraphObject go = goSet.get(i);
if (go.isNode()) {
Node n = null;
try {
n = subGraph.copyNode((Node) go);
n.setContextUsage(((Node) go).getContextUsage());
} catch (TypeException e) {
// during load process the type check should be disabled,
// so this Exception should never be thrown
e.printStackTrace();
}
try {
inclusion.addMapping(n, go);
} catch (BadMappingException e) {
e.printStackTrace();
}
}
}
for (int i = 0; i < goSet.size(); i++) {
GraphObject go = goSet.get(i);
if (go.isArc()) {
Enumeration<GraphObject> sources = inclusion.getInverseImage(((Arc) go)
.getSource());
if (sources.hasMoreElements()) {
source = (Node) sources.nextElement();
Enumeration<GraphObject> targets = inclusion.getInverseImage(((Arc) go)
.getTarget());
if (targets.hasMoreElements()) {
target = (Node) targets.nextElement();
Arc a = null;
try {
a = subGraph.copyArc((Arc) go, source, target);
a.setContextUsage(((Arc) go).getContextUsage());
} catch (TypeException e) {
// while loading the type check should be disabled,
// so this Exception should never be thrown
System.out.println(e);
// e.printStackTrace();
}
try {
inclusion.addMapping(a, go);
} catch (BadMappingException e) {
System.out.println(e);
// e.printStackTrace();
}
}
}
}
}
return inclusion;
}
protected void checkIsomorphicInclusions(Vector<OrdinaryMorphism> inclusions) {
int size = inclusions.size();
for (int i = 0; i < size; i++) {
OrdinaryMorphism inclusion = inclusions
.elementAt(i);
for (int j = i + 1; j < size; j++) {
OrdinaryMorphism inc = inclusions
.elementAt(j);
if (inclusion.getSource().isIsomorphicTo(inc.getSource())) {
inclusions.removeElement(inc);
j--;
size = inclusions.size();
BaseFactory.theFactory().destroyMorphism(inc);
inc = null;
}
}
}
}
/**
* Here the given morphism <code>matchMorph</code> can contain mapping
* from a source node with a child type of an inheritance relation
* to a target node with a parent type.
* In this case this target (parent) node will be replaced by a copy
* of the child node.<br>
* The source graph of the <code>matchMorph</code> is the source graph
* of the <code>ruleMorph</code>,
* the target graph of the <code>matchMorph</code> is the target graph of
* the <code>isoMorph</code>.
* The edges from / to the (parent) node are copied, too.
*
* @param ruleMorph
* @param matchMorph
* @param isoMorph
* @return true by success, otherwise false
*/
public boolean replaceParentByChild(
final OrdinaryMorphism ruleMorph,
final OrdinaryMorphism matchMorph,
final OrdinaryMorphism isoMorph) {
final Hashtable<Arc, Arc> img2origInArc = new Hashtable<Arc, Arc>();
final Hashtable<Arc, Arc> img2origOutArc = new Hashtable<Arc, Arc>();
final Hashtable<Arc, Arc> orig2img_isoMorph = new Hashtable<Arc, Arc>();
final Iterator<Node> en = matchMorph.getSource().getNodesSet().iterator();
while (en.hasNext()) {
img2origInArc.clear();
img2origOutArc.clear();
orig2img_isoMorph.clear();
Node go = en.next();
Node img1 = (Node) ruleMorph.getImage(go);
Node img2 = (Node) matchMorph.getImage(go);
if (img1 != null && img2 != null) {
if (go.getType().isChildOf(img2.getType())) {
Node child = go;
Node parent = img2;
// save original of parent and its edges
Node orig_rStar = (Node) isoMorph.getInverseImage(parent).nextElement();
Iterator<Arc> arcs = orig_rStar.getOutgoingArcsSet().iterator();
while (arcs.hasNext()) {
Arc a = arcs.next();
Arc img = (Arc)isoMorph.getImage(a);
orig2img_isoMorph.put(a, img);
}
arcs = orig_rStar.getIncomingArcsSet().iterator();
while (arcs.hasNext()) {
Arc a = arcs.next();
Arc img = (Arc)isoMorph.getImage(a);
orig2img_isoMorph.put(a, img);
}
isoMorph.removeMapping(orig_rStar);
// save parent's edges
arcs = parent.getOutgoingArcsSet().iterator();
while (arcs.hasNext()) {
Arc a = arcs.next();
Enumeration<GraphObject> orig = matchMorph.getInverseImage(a);
if (orig.hasMoreElements())
img2origOutArc.put(a, (Arc)orig.nextElement());
else
img2origOutArc.put(a, a);
}
arcs = parent.getIncomingArcsSet().iterator();
while (arcs.hasNext()) {
Arc a = arcs.next();
Enumeration<GraphObject> orig = matchMorph.getInverseImage(a);
if (orig.hasMoreElements())
img2origInArc.put(a, (Arc)orig.nextElement());
else
img2origInArc.put(a, a);
}
final Type childT = child.getType();
try {
final Node childNode = matchMorph.getTarget().createNode(childT);
// handle attributes
if (parent.getAttribute() != null) {
for (int i=0; i<parent.getAttribute().getNumberOfEntries(); i++) {
ValueMember pvm = (ValueMember) parent.getAttribute().getMemberAt(i);
ValueMember vm = (ValueMember) childNode.getAttribute().getMemberAt(pvm.getName());
if (pvm.isSet()) {
vm.setExprAsText(pvm.getExprAsText());
if (!vm.isTransient())
vm.setTransient(pvm.isTransient());
}
else {
vm.setExprAsText("vm_"+i);
vm.setTransient(true);
}
}
for (int i=0; i<childNode.getAttribute().getNumberOfEntries(); i++) {
ValueMember vm = (ValueMember) childNode.getAttribute().getMemberAt(i);
if (!vm.isSet()) {
vm.setExprAsText("vm_"+i);
vm.setTransient(true);
}
}
}
try {
matchMorph.removeMapping(child);
// reset mappings
matchMorph.addMapping(child, childNode);
Enumeration<Arc> keys = img2origOutArc.keys();
while (keys.hasMoreElements()) {
Arc img = keys.nextElement();
Arc orig = img2origOutArc.get(img);
// ADD MULTIPLICITY CHECK ???
if (img.getSource() != img.getTarget()) {
img.setSource(childNode);
if (orig != img) {
try {
matchMorph.addMapping(orig, img);
} catch (BadMappingException e) {
// System.out.println("replaceParentByChild:BadMappingException:Arc "+e.getStackTrace());
return false;
}
}
}
}
keys = img2origInArc.keys();
while (keys.hasMoreElements()) {
Arc img = keys.nextElement();
Arc orig = img2origInArc.get(img);
// ADD MULTIPLICITY CHECK ???
if (img.getSource() == img.getTarget())
img.setSource(childNode);
img.setTarget(childNode);
if (orig != img) {
try {
matchMorph.addMapping(orig, img);
} catch (BadMappingException e) {
// System.out.println("replaceParentByChild:BadMappingException:Arc "+e.getStackTrace());
return false;
}
}
}
if (parent.getNumberOfInOutArcs() == 0) {
// reset mappings
isoMorph.addMapping(orig_rStar, childNode);
keys = orig2img_isoMorph.keys();
while (keys.hasMoreElements()) {
Arc a = keys.nextElement();
Arc img = orig2img_isoMorph.get(a);
try {
isoMorph.addMapping(a, img);
} catch (BadMappingException e) {
// System.out.println("replaceParentByChild:BadMappingException:Arc "+e.getStackTrace());
return false;
}
}
// System.out.println("ExcludePair.replaceParentByChild:: DONE: "+parent.getType().getName()+" by "+childNode.getType().getName());
matchMorph.getTarget().destroyNode(parent, true, false);
}
else {
return false;
}
} catch (BadMappingException ex1) {
// System.out.println("replaceParentByChild:BadMappingException:Node "+ex1.getStackTrace());
return false;
}
} catch (TypeException ex) {
// System.out.println("replaceParentByChild:TypeException "+ex.getStackTrace());
return false;
}
}
}
}
return true;
}
/**
* Here the given morphism <code>morph2</code> can contain mapping
* from a source node with a child type of an inheritance relation
* to a target node with a parent type.
* The given morphism <code>morph1</code> maps
* a source node with a parent type of an inheritance relation
* to the same target node of the morphism <code>morph2</code>.
* In this case this target node will be replaced by a copy
* of the child node. All in-/out-edges of the (parent) node are copied, too.<br>
* The target graph of the morphism <code>morph2</code> is the same target graph
* of the <code>morph1</code>, the source graphs are different.
*
* @param morph1
* @param morph2
* @return true by success, otherwise false
*/
public boolean replaceParentByChild(
final OrdinaryMorphism morph1,
final OrdinaryMorphism morph2) {
final Hashtable<Arc, Arc> img2origInArc = new Hashtable<Arc, Arc>();
final Hashtable<Arc, Arc> img2origOutArc = new Hashtable<Arc, Arc>();
final Hashtable<Arc, Arc> orig2img_isoMorph = new Hashtable<Arc, Arc>();
final Iterator<Node> en = morph1.getSource().getNodesSet().iterator();
while (en.hasNext()) {
img2origInArc.clear();
img2origOutArc.clear();
orig2img_isoMorph.clear();
Node go = en.next();
Node img2 = (Node) morph1.getImage(go);
if (img2 != null) {
if (go.getType().isChildOf(img2.getType())) {
Node child = go;
Node parent = img2;
// save original of parent and its edges
Node orig_rStar = (Node) morph2.getInverseImage(parent).nextElement();
Iterator<Arc> arcs = orig_rStar.getOutgoingArcsSet().iterator();
while (arcs.hasNext()) {
Arc a = arcs.next();
Arc img = (Arc)morph2.getImage(a);
orig2img_isoMorph.put(a, img);
}
arcs = orig_rStar.getIncomingArcsSet().iterator();
while (arcs.hasNext()) {
Arc a = arcs.next();
Arc img = (Arc)morph2.getImage(a);
orig2img_isoMorph.put(a, img);
}
morph2.removeMapping(orig_rStar);
// save parent's edges
arcs = parent.getOutgoingArcsSet().iterator();
while (arcs.hasNext()) {
Arc a = arcs.next();
Enumeration<GraphObject> orig = morph1.getInverseImage(a);
if (orig.hasMoreElements())
img2origOutArc.put(a, (Arc)orig.nextElement());
else
img2origOutArc.put(a, a);
}
arcs = parent.getIncomingArcsSet().iterator();
while (arcs.hasNext()) {
Arc a = arcs.next();
Enumeration<GraphObject> orig = morph1.getInverseImage(a);
if (orig.hasMoreElements())
img2origInArc.put(a, (Arc)orig.nextElement());
else
img2origInArc.put(a, a);
}
final Type childT = child.getType();
try {
final Node childNode = morph1.getTarget().createNode(childT);
// handle attributes
if (parent.getAttribute() != null) {
for (int i=0; i<parent.getAttribute().getNumberOfEntries(); i++) {
ValueMember pvm = (ValueMember) parent.getAttribute().getMemberAt(i);
ValueMember vm = (ValueMember) childNode.getAttribute().getMemberAt(pvm.getName());
if (!vm.isSet() &&
pvm.isSet()) {
vm.setExprAsText(pvm.getExprAsText());
if (!vm.isTransient())
vm.setTransient(pvm.isTransient());
}
else {
vm.setExprAsText("vm_"+i);
vm.setTransient(true);
}
}
for (int i=0; i<childNode.getAttribute().getNumberOfEntries(); i++) {
ValueMember vm = (ValueMember) childNode.getAttribute().getMemberAt(i);
if (!vm.isSet()) {
vm.setExprAsText("vm_"+i);
vm.setTransient(true);
}
}
}
try {
// reset mappings
// remove old mapping
morph1.removeMapping(child);
// add new mapping
morph1.addMapping(child, childNode);
// reset mapping of arcs
Enumeration<Arc> keys = img2origOutArc.keys();
while (keys.hasMoreElements()) {
Arc img = keys.nextElement();
Arc orig = img2origOutArc.get(img);
// ADD MULTIPLICITY CHECK ???
if (img.getSource() != img.getTarget()) {
img.setSource(childNode);
if (orig != img) {
try {
morph1.addMapping(orig, img);
} catch (BadMappingException e) {
// System.out.println("replaceParentByChild:BadMappingException:Arc "+e.getStackTrace());
return false;
}
}
}
}
keys = img2origInArc.keys();
while (keys.hasMoreElements()) {
Arc img = keys.nextElement();
Arc orig = img2origInArc.get(img);
// ADD MULTIPLICITY CHECK ???
if (img.getSource() == img.getTarget())
img.setSource(childNode);
img.setTarget(childNode);
if (orig != img) {
try {
morph1.addMapping(orig, img);
} catch (BadMappingException e) {
// System.out.println("replaceParentByChild:BadMappingException:Arc "+e.getStackTrace());
return false;
}
}
}
if (parent.getNumberOfInOutArcs() == 0) {
// reset mappings
morph2.addMapping(orig_rStar, childNode);
keys = orig2img_isoMorph.keys();
while (keys.hasMoreElements()) {
Arc a = keys.nextElement();
Arc img = orig2img_isoMorph.get(a);
try {
morph2.addMapping(a, img);
} catch (BadMappingException e) {
// System.out.println("replaceParentByChild:BadMappingException:Arc "+e.getStackTrace());
return false;
}
}
// System.out.println("ExcludePair.replaceParentByChild:: DONE: "+parent.getType().getName()+" by "+childNode.getType().getName());
// destroy not more needed parent node
morph1.getTarget().destroyNode(parent, true, false);
}
else {
return false;
}
} catch (BadMappingException ex1) {
System.out.println("replaceParentByChild:BadMappingException:Node "+ex1.getStackTrace());
return false;
}
} catch (TypeException ex) {
System.out.println("replaceParentByChild:TypeException "+ex.getStackTrace());
return false;
}
}
}
}
return true;
}
}