package agg.xt_basis.csp; import java.util.BitSet; import java.util.Enumeration; import java.util.HashSet; import java.util.Stack; import java.util.Vector; import java.util.HashMap; import java.util.Iterator; import java.util.Hashtable; import agg.attribute.impl.VarTuple; import agg.attribute.impl.VarMember; import agg.attribute.impl.ValueTuple; import agg.attribute.impl.ValueMember; import agg.attribute.impl.CondTuple; import agg.attribute.impl.CondMember; import agg.attribute.AttrVariableTuple; import agg.util.Pair; import agg.xt_basis.Arc; import agg.xt_basis.BadMappingException; import agg.xt_basis.Graph; import agg.xt_basis.GraphObject; import agg.xt_basis.MorphCompletionStrategy; import agg.xt_basis.NACStarMorphism; import agg.xt_basis.OrdinaryMorphism; //import com.objectspace.jgl.Deque; /** * Simple Backtracking implementation of morphism completion. * * @deprecated not used anymore */ public class Completion_SimpleBT extends MorphCompletionStrategy { private boolean itsInjectiveFlag; private boolean initialized; // private Vector<GraphObject> domain; public Completion_SimpleBT(int i) { // no properties supported: super(new BitSet(1)); this.itsInjectiveFlag = false; this.itsName = "Simple BT"; } public Completion_SimpleBT(boolean injective, int i) { // no properties supported: super(new BitSet(1)); this.itsInjectiveFlag = injective; this.itsName = "Simple BT"; } public final void initialize(OrdinaryMorphism morph) { this.itsMorphism = morph; this.itsStack = new Stack<StackItem>(); // this.itsObjectsToMap = new Deque(); this.itsObjectsToMap = new Vector<GraphObject>(); this.itsState = START; // itsPreviousCompletion = null; Iterator<?> iter = this.itsMorphism.getOriginal().getNodesSet().iterator(); while (iter.hasNext()) { GraphObject obj = (GraphObject) iter.next(); if (this.itsMorphism.getImage(obj) == null) { // this.itsObjectsToMap.pushBack(obj); this.itsObjectsToMap.add(obj); } } iter = this.itsMorphism.getOriginal().getArcsSet().iterator(); while (iter.hasNext()) { GraphObject obj = (GraphObject) iter.next(); if (this.itsMorphism.getImage(obj) == null) { // this.itsObjectsToMap.pushBack(obj); this.itsObjectsToMap.add(obj); } } this.initialized = true; } public void setPartialMorphism(OrdinaryMorphism morph) { if (!this.initialized) initialize(morph); else { this.itsMorphism = morph; this.itsStack.clear(); this.itsObjectsToMap.clear(); this.itsState = START; // System.out.println("Completion_SimpleBT.setPartialMorphism..."); Iterator<?> iter = this.itsMorphism.getOriginal().getNodesSet().iterator(); while (iter.hasNext()) { GraphObject obj = (GraphObject) iter.next(); if (this.itsMorphism.getImage(obj) == null) { // this.itsObjectsToMap.pushBack(obj); this.itsObjectsToMap.add(obj); } } iter = this.itsMorphism.getOriginal().getArcsSet().iterator(); while (iter.hasNext()) { GraphObject obj = (GraphObject) iter.next(); if (this.itsMorphism.getImage(obj) == null) { // this.itsObjectsToMap.pushBack(obj); this.itsObjectsToMap.add(obj); } } } } public void resetTypeMap(Graph g) { refreshStack(); } public void resetTypeMap(Hashtable<String, HashSet<GraphObject>> typeMap) { refreshStack(); } public void resetVariableDomain(boolean instanceNull) { refreshStack(); } private void refreshStack() { this.itsStack.clear(); // domain.clear(); // Enumeration en = this.itsMorphism.getTarget().getElements(); // while(en.hasMoreElements()){ // domain.add(en.nextElement()); // } this.itsState = START; // this.itsObjectsToMap.clear(); // Enumeration iter = this.itsMorphism.getOriginal().getElements(); // while ( iter.hasMoreElements() ){ // GraphObject obj = (GraphObject) iter.nextElement(); // this.itsObjectsToMap.pushBack( obj ); // } // System.out.println("Completion_SimpleBT.refreshStack()... DONE "); } // private void refreshObjectsMap() { // this.itsObjectsToMap.clear(); // Iterator<?> iter = this.itsMorphism.getOriginal().getNodesSet().iterator(); // while (iter.hasNext()) { // GraphObject obj = (GraphObject) iter.next(); // this.itsObjectsToMap.pushBack(obj); // } // iter = this.itsMorphism.getOriginal().getArcsSet().iterator(); // while (iter.hasNext()) { // GraphObject obj = (GraphObject) iter.next(); // this.itsObjectsToMap.pushBack(obj); // } // } private final GraphObject nextMapping() { if (this.itsStack.empty()) { return null; } GraphObject image; GraphObject obj = this.itsStack.peek().object; Enumeration<?> iter = this.itsStack.peek().iter; // System.out.println("obj tp map : "+obj); while (iter.hasMoreElements()) { try { image = (GraphObject) iter.nextElement(); // System.out.println("test image: "+image); Enumeration<GraphObject> e = this.itsMorphism.getInverseImage(image); GraphObject o = null; if (e.hasMoreElements()) o = e.nextElement(); // System.out.println("injective: "+this.itsInjectiveFlag+" inverse // image: "+o); if (!this.itsInjectiveFlag || (o == null)) { this.itsMorphism.addMapping(obj, image); if (this.itsMorphism.getImage(obj) != null) { // System.out.println("addMapping: "+ obj+" --> // "+this.itsMorphism.getImage(obj)); return image; } continue; } continue; } catch (BadMappingException exc) { continue; } } // System.out.println("Completion_SimpleBT: No mapping candidates!"); return null; } public final void reset() { } public final boolean next(OrdinaryMorphism morph) { this.errorMsg = ""; storeValueOfInputParameter(morph); if (morph != this.itsMorphism) { initialize(morph); } if (this.itsState == SUCCESS) { // savePreviousCompletion(); this.itsState = MAP_NEXT; } GraphObject obj; while (true) { switch (this.itsState) { case START: if (this.itsMorphism.getOriginal().isEmpty()) this.itsState = SUCCESS; else this.itsState = SELECT; break; case SELECT: obj = selectObjectToMap(); if (obj == null) this.itsState = SUCCESS; else { this.itsStack.push(new StackItem(obj, getDomain() ) ); this.itsState = MAP_NEXT; } break; case MAP_NEXT: obj = nextMapping(); if (obj != null) { // remove the Mappings corresponding to the recent // backtracking steps: // Enumeration iter = this.itsObjectsToMap.elements(); // for( itsPopNo; itsPopNo > 0; itsPopNo-- ) // { // do_removeMapping( (GraphObject) iter.nextElement() ); // } this.itsState = SELECT; } else { this.itsState = BACK; } restoreValueOfInputParameter(morph); break; case BACK: if (this.itsStack.size() > 1) { // this.itsObjectsToMap.pushFront( ((StackItem) // this.itsStack.pop()).object ); // itsPopNo++; back(); this.itsState = MAP_NEXT; } else { this.itsState = NO_MORE_COMPLETIONS; } break; case SUCCESS: if (!checkInputParameter(morph)) { this.itsState = MAP_NEXT; break; } if (!checkObjectsWithSameVariable(morph)) { this.itsState = MAP_NEXT; break; } if (!(morph instanceof NACStarMorphism)) { if (!checkAttrCondition(morph)) { this.itsState = MAP_NEXT; break; } } restoreValueOfInputParameter(morph); return true; case NO_MORE_COMPLETIONS: // if (itsPreviousCompletion != null) // restorePreviousCompletion(); // refreshStack(); // this.itsState = START; return false; default: // System.out.println("Completion_SimpleBT: Should have never // come here..."); } } } private Enumeration<GraphObject> getDomain() { return this.itsMorphism.getImage().getElements(); // return domain.elements(); } private final void back() { GraphObject obj = this.itsStack.pop().object; // this.itsObjectsToMap.pushFront(obj); this.itsObjectsToMap.add(0, obj); if (this.itsMorphism.getImage(obj) != null) this.itsMorphism.removeMapping(obj); } private final GraphObject selectObjectToMap() { if (this.itsObjectsToMap.isEmpty()) return null; // GraphObject obj = (GraphObject) this.itsObjectsToMap.popFront(); GraphObject obj = this.itsObjectsToMap.get(0); this.itsObjectsToMap.remove(0); if (areReferencesMapped(obj)) return obj; // this.itsObjectsToMap.pushBack(obj); this.itsObjectsToMap.add(obj); return selectObjectToMap(); } private final boolean areReferencesMapped(GraphObject obj) { if (obj.isArc()) { return (this.itsMorphism.getImage(((Arc) obj).getSource()) != null && this.itsMorphism .getImage(((Arc) obj).getTarget()) != null); } return true; } /* private final void savePreviousCompletion() { GraphObject obj; itsPreviousCompletion = new Vector<GraphObject>(2 * this.itsStack.size()); for (int i = 0; i < this.itsStack.size(); i++) { obj = this.itsStack.elementAt(i).object; itsPreviousCompletion.addElement(obj); itsPreviousCompletion.addElement(this.itsMorphism.getImage(obj)); } } private final void restorePreviousCompletion() { for (int i = 0; i < itsPreviousCompletion.size();) { this.itsMorphism.addMapping(itsPreviousCompletion.elementAt(i++), itsPreviousCompletion.elementAt(i++)); } } */ /* * first save values of attr. context variables used as input parameters, * otherwise its will be overwritten when next() done. */ private void storeValueOfInputParameter(OrdinaryMorphism morph) { this.mapInputParameter = new HashMap<Integer, String>(1); AttrVariableTuple avt = morph.getAttrContext().getVariables(); if (avt != null) { int num = avt.getSize(); for (int i = 0; i < num; i++) { VarMember var = avt.getVarMemberAt(i); if (var.isInputParameter()) { String val = var.getExprAsText(); if (val != null) { Integer key = new Integer(i); this.mapInputParameter.put(key, val); // System.out.println("Store input param: // "+var.getName()+" :: " +var); } } } } } /* * restore values of attr. context variables used as input parameters */ private void restoreValueOfInputParameter(OrdinaryMorphism morph) { if (morph.getAttrContext() == null) { return; } AttrVariableTuple avt = morph.getAttrContext().getVariables(); if (!this.mapInputParameter.isEmpty()) { Iterator<Integer> iter = this.mapInputParameter.keySet().iterator(); while (iter.hasNext()) { Integer key = iter.next(); String val = this.mapInputParameter.get(key); VarMember var = avt.getVarMemberAt(key.intValue()); String val1 = var.getExprAsText(); if (!val.equals(val1)) { // System.out.println(((VarTuple) // avt).getTupleType().getNameAsString(key.intValue())+" :: // "+var); var.setExprAsText(val); ((ValueMember) var).checkValidity(); // System.out.println("INPUT PARAMETER RESET :"); // System.out.println(((VarTuple) // avt).getTupleType().getNameAsString(key.intValue())+" :: // "+var); } } } } private boolean checkInputParameter(OrdinaryMorphism morph) { AttrVariableTuple avt = morph.getAttrContext().getVariables(); if (!this.mapInputParameter.isEmpty()) { Iterator<Integer> iter = this.mapInputParameter.keySet().iterator(); while (iter.hasNext()) { Integer key = iter.next(); String val = this.mapInputParameter.get(key); VarMember var = avt.getVarMemberAt(key.intValue()); if (var.isInputParameter()) { String val1 = var.getExprAsText(); // System.out.println("InputParameter: "+var.getName()+" // "+var.getMark()+" "+val1); if (!(morph instanceof NACStarMorphism)) { if ((val1 != null) && (var.getMark() != VarMember.NAC) && (var.getMark() != VarMember.PAC) && !val.equals(val1)) { this.errorMsg = "Value of the input parameter [ " + var.getName() + " ] not found."; return false; } } else { if ((val1 != null) && (var.getMark() == VarMember.NAC) && !val.equals(val1)) { this.errorMsg = "Value of the input parameter [ " + var.getName() + " ] not found."; return false; } } } } } return true; } private boolean checkObjectsWithSameVariable(OrdinaryMorphism morph) { // System.out.println("Completion_CSP.checkObjectsWithSameVariable"); VarTuple variables = (VarTuple) morph.getAttrContext().getVariables(); for (int i = 0; i < variables.getSize(); i++) { VarMember var = variables.getVarMemberAt(i); Vector<Pair<GraphObject, String>> v = new Vector<Pair<GraphObject, String>>(); Iterator<?> iter = morph.getOriginal().getNodesSet().iterator(); while (iter.hasNext()) { GraphObject orig = (GraphObject) iter.next(); if (orig.getAttribute() == null) continue; ValueTuple origVal = (ValueTuple) orig.getAttribute(); for (int k = 0; k < origVal.getSize(); k++) { ValueMember mem = origVal.getValueMemberAt(k); if (mem.isSet() && mem.getExpr().isVariable() && mem.getExprAsText().equals(var.getName()) && mem.getDeclaration().getTypeName().equals( var.getDeclaration().getTypeName())) { v .add(new Pair<GraphObject, String>(orig, mem .getName())); // System.out.println(var.getName()+" "+var); } } } iter = morph.getOriginal().getArcsSet().iterator(); while (iter.hasNext()) { GraphObject orig = (GraphObject) iter.next(); if (orig.getAttribute() == null) continue; ValueTuple origVal = (ValueTuple) orig.getAttribute(); for (int k = 0; k < origVal.getSize(); k++) { ValueMember mem = origVal.getValueMemberAt(k); if (mem.isSet() && mem.getExpr().isVariable() && mem.getExprAsText().equals(var.getName()) && mem.getDeclaration().getTypeName().equals( var.getDeclaration().getTypeName())) { v .add(new Pair<GraphObject, String>(orig, mem .getName())); // System.out.println(var.getName()+" "+var); } } } if (v.size() > 1) { Pair<GraphObject, String> p = v.elementAt(0); GraphObject img = morph.getImage(p.first); ValueTuple val = (ValueTuple) img.getAttribute(); ValueMember mem = val.getValueMemberAt(p.second); for (int j = 1; j < v.size(); j++) { Pair<GraphObject, String> pj = v.elementAt(j); GraphObject imgj = morph.getImage(pj.first); ValueTuple valj = (ValueTuple) imgj.getAttribute(); ValueMember memj = valj.getValueMemberAt(pj.second); // System.out.println(mem.getExprAsText()+" == ? // "+memj.getExprAsText()); if (!mem.getExprAsText().equals(memj.getExprAsText())) { this.errorMsg = "Attribute match is failed."; return false; } } } } return true; } private boolean checkAttrCondition(OrdinaryMorphism morph) { // System.out.println("Completion_SimpleBT.checkAttrCondition:: "); CondTuple conds = (CondTuple) morph.getAttrContext().getConditions(); for (int i = 0; i < conds.getSize(); i++) { CondMember cond = conds.getCondMemberAt(i); if (!cond.isDefinite()) { // System.out.println("Completion_SimpleBT.checkAttrCondition:: // "+cond.getExprAsText()+" NOT Definite --> TRUE"); // ((VarTuple)morph.getAttrContext().getVariables()).showVariables(); } else if (cond.isTrue()) { // System.out.println("Completion_SimpleBT.checkAttrCondition:: // "+cond.getExprAsText()+" TRUE"); // ((VarTuple)morph.getAttrContext().getVariables()).showVariables(); } else { this.errorMsg = "Attribute condition [ " + cond.getExprAsText() + " ] failed."; // System.out.println("Completion_SimpleBT : "+this.errorMsg); // ((VarTuple)morph.getAttrContext().getVariables()).showVariables(); return false; } } return true; } public String getErrorMsg() { return this.errorMsg; } // ---- member variables ------------------------ private OrdinaryMorphism itsMorphism; // private Deque itsObjectsToMap; private Vector<GraphObject> itsObjectsToMap; private Stack<StackItem> itsStack; private int itsState = START; // private Vector<GraphObject> itsPreviousCompletion; private HashMap<Integer, String> mapInputParameter = new HashMap<Integer, String>( 1); private String errorMsg; // constants for morphism completion state machine: private final static int START = 1; private final static int SELECT = 2; private final static int MAP_NEXT = 3; private final static int BACK = 4; private final static int SUCCESS = 5; private final static int NO_MORE_COMPLETIONS = 6; } class StackItem { protected StackItem(GraphObject obj, Enumeration<GraphObject> iter) { this.object = obj; this.iter = iter; } protected Enumeration<GraphObject> iter; protected GraphObject object; }