// $Id: Variable.java,v 1.25 2010/09/23 08:26:52 olga Exp $ // $Log: Variable.java,v $ // Revision 1.25 2010/09/23 08:26:52 olga // tuning // // Revision 1.24 2010/06/09 10:24:32 olga // tuning // // Revision 1.23 2010/03/18 18:18:30 olga // tuning // // Revision 1.22 2010/03/08 15:50:35 olga // code optimizing // // Revision 1.21 2010/03/04 14:13:51 olga // code optimizing // // Revision 1.20 2010/02/22 14:43:23 olga // code optimizing // // Revision 1.19 2010/02/07 16:43:57 olga // tuning // // Revision 1.18 2009/10/22 11:16:37 olga // tuning and tests // // Revision 1.17 2009/10/05 08:53:25 olga // RSA check - bug fixed // // Revision 1.16 2009/05/28 13:18:29 olga // Amalgamated graph transformation - development stage // // Revision 1.15 2009/05/12 10:36:53 olga // CPA: bug fixed // Applicability of Rule Seq. : bug fixed // // Revision 1.14 2008/04/07 09:36:55 olga // Code tuning: refactoring + profiling // Extension: CPA - two new options added // // Revision 1.13 2007/12/10 08:42:58 olga // CPA of grammar with node type inheritance for attributed graphs - bug fixed // // Revision 1.12 2007/11/01 09:58:19 olga // Code refactoring: generic types- done // // Revision 1.11 2007/10/11 15:03:38 olga // code tuning // // Revision 1.10 2007/09/10 13:05:07 olga // In this update: // - package xerces2.5.0 is not used anymore; // - class com.objectspace.jgl.Pair is replaced by the agg own generic class agg.util.Pair; // - bugs fixed in: usage of PACs in rules; match completion; // usage of static method calls in attr. conditions // - graph editing: added some new features // // Revision 1.9 2007/01/11 10:21:17 olga // Optimized Version 1.5.1beta , free for tests // // Revision 1.8 2006/12/13 13:33:04 enrico // reimplemented code // // Revision 1.7 2006/11/15 09:00:32 olga // Transform with input parameter : bug fixed // // Revision 1.6 2006/11/01 11:17:29 olga // Optimized agg sources of CSP algorithm, match usability, // graph isomorphic copy, // node/edge type multiplicity check for injective rule and match // // Revision 1.5 2006/05/22 08:27:33 olga // CPA: Bug fixed // Gragra trash: tuning // // Revision 1.4 2006/05/08 15:47:10 olga // some tests with variable order and queries // // Revision 1.3 2006/05/08 08:24:12 olga // Some extentions of GUI: - Undo Delete button of tool bar to undo deletions // if grammar elements like rule, NAC, graph constraints; // - the possibility to add a new graph to a grammar or a copy of the current // host graph; // - to set one or more layer for consistency constraints. // Also some bugs fixed of matching and some optimizations of CSP algorithmus done. // // Revision 1.2 2006/04/20 11:58:39 olga // Attr type check: Bug fixed // // Revision 1.1 2005/08/25 11:56:55 enrico // *** empty log message *** // // Revision 1.2 2005/07/11 09:30:19 olga // This is test version AGG V1.2.8alfa . // What is new: // - saving rule option <disabled> // - setting trigger rule for layer // - display attr. conditions in gragra tree view // - CPA algorithm <dependencies> // - creating and display CPA graph with conflicts and/or dependencies // based on (.cpx) file // // Revision 1.1 2005/05/30 12:58:01 olga // Version with Eclipse // // Revision 1.6 2004/12/20 14:53:48 olga // Changes because of matching optimisation. // // Revision 1.5 2004/05/06 17:23:27 olga // graph matching OK // // Revision 1.4 2004/04/28 12:46:38 olga // test CSP // // Revision 1.3 2003/12/18 16:27:25 olga // . // // Revision 1.2 2003/03/05 18:24:25 komm // sorted/optimized import statements // // Revision 1.1.1.1 2002/07/11 12:17:26 olga // Imported sources // // Revision 1.7 2000/07/31 09:46:19 shultzke // Nichtdeterministische Regelauswahl und Ansatzsuche ist moeglich // // Revision 1.6 1999/06/28 16:42:05 shultzke // Hoffentlich erzeigen wir eine uebersetzungsfaehige Version // // Revision 1.5 1998/04/07 14:22:32 mich // Updated for use with JGL V3.1. // // Revision 1.4 1997/12/26 20:43:17 mich // + First revision after extinction of "impl" package. // + Debug output now uses Debug.println(). // // Revision 1.3 1997/10/15 04:57:09 mich // + InstantiationHook funcionality added. // Tested. // // Revision 1.2 1997/09/22 22:22:04 mich // + checkConstraints() added // // Revision 1.1 1997/09/16 15:56:18 mich // Initial revision // package agg.util.csp; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; //import java.util.LinkedHashSet; import java.util.Vector; import agg.util.OrderedSet; import agg.xt_basis.Arc; import agg.xt_basis.GraphObject; import agg.xt_basis.Node; import agg.xt_basis.csp.Query_Type; /** Implements a variable of the CSP algorithm. */ public class Variable { public final static int NODE = 0; public final static int ARC = 1; private final static BinaryPredicate theirQueryOrder = new QueryOrder(); final private OrderedSet<Object> itsConstraints; final private OrderedSet<Query> itsOutgoingQueries; final private OrderedSet<Query> itsIncomingQueries; private Object itsInstance; private Iterator<?> itsDomain; // private boolean randomizedDomain; private boolean enabled; final private Vector<InstantiationHook> itsInstantiationHooks; private Object LHSgo; // node or arc from LHS of a rule // private boolean isEdge; private String convertedTypeString; private int kind=-1; // 0 is Node, 1 is Arc, otherwise is -1; private int domainsize; private int itsWeight; private Query_Type itsTypeQuery; public Variable() { // randomizedDomain = true; this.enabled = true; this.itsConstraints = new OrderedSet<Object>(); this.itsOutgoingQueries = new OrderedSet<Query>(theirQueryOrder); this.itsIncomingQueries = new OrderedSet<Query>(theirQueryOrder); this.itsInstantiationHooks = new Vector<InstantiationHook>(2, 2); } public void clear() { this.LHSgo = null; this.itsTypeQuery = null; this.itsIncomingQueries.clear(); this.itsOutgoingQueries.clear(); final Enumeration<?> allConstraints = this.itsConstraints.elements(); while (allConstraints.hasMoreElements()) { ((BinaryConstraint) allConstraints.nextElement()).clear(); } this.itsConstraints.clear(); this.itsInstantiationHooks.clear(); } /** * Return my current value, <code>null</code> if uninstantiated. */ public final Object getInstance() { return this.itsInstance; } /** * Instantiate me by given value. */ public final void setInstance(Object value) { Enumeration<InstantiationHook> en; if (this.itsInstance != null) { en = this.itsInstantiationHooks.elements(); while (en.hasMoreElements()) en.nextElement().uninstantiate(this); } this.itsInstance = value; if (this.itsInstance != null) { en = this.itsInstantiationHooks.elements(); while (en.hasMoreElements()) en.nextElement().instantiate(this); } } /** * Check all my applicable constraints, i.e., check the consistency of my * current instantiation with all previously instantiated variables. * <p> * <b>Pre:</b> <code>getInstance() != null</code>. * * @return An Enumeration of all the Variables whose instantiations conflict * with my current instantiation. If all applicable constraints are * satisfied, the Enumeration is empty. Enumeration elements are of * type <code>Variable</code>. */ public final Enumeration<Variable> checkConstraints() { Vector<Variable> allConflictVars = new Vector<Variable>(5); Enumeration<?> allConstraints = this.itsConstraints.elements(); while (allConstraints.hasMoreElements()) { BinaryConstraint aConstraint = (BinaryConstraint) allConstraints .nextElement(); if (aConstraint.isApplicable() && !aConstraint.execute()) { allConflictVars.addElement(aConstraint.getCause(this)); } } return allConflictVars.elements(); } /** * Add <code>hook</code> to the set of my InstantiationHooks. I will call * the encapsulated operations at the respective times of * instantiation/uninstantiation, with myself as an argument. * * @see agg.util.csp.InstantiationHook */ public final void addInstantiationHook(InstantiationHook hook) { this.itsInstantiationHooks.addElement(hook); } /** * Return next object of the enumeration of my domain. This enumeration continues at the * position where a previous access left off. The type of enumeration elements * is dependent on the concrete domain. */ public final Object getNext() { // try { return this.itsDomain.next(); // } catch (java.util.ConcurrentModificationException ex) { // return null; // } } public boolean hasNext() { return this.itsDomain.hasNext(); } /** * Set my domain in an enumeration representation. This very same enumeration is * returned from a subsequent call of <code>getDomainEnum()</code>. */ public final void setDomainEnum(final HashSet<?> dom) { // NOTE: randomization will be done in Query_Type.setObjects(List<GraphObject> objects) this.itsDomain = dom.iterator(); } // public void setRandomizedDomain(boolean randomized) { // this.randomizedDomain = randomized; // } public int getDomainSize() { return this.domainsize; } /** * Return my weight. It is computed as the sum of the weights of all * constraints attached and of all outgoing queries. */ public final int getWeight() { return this.itsWeight; } public final void addWeight(int w) { this.itsWeight += w; } /** * Return an enumeration of all the constraints I'm involved in. Enumeration * elements are of type <code>BinaryConstraint</code>. * * @see agg.util.csp.BinaryConstraint */ public final Enumeration<?> getConstraints() { return this.itsConstraints.elements(); } public void setDomainSize(int size) { this.domainsize = size; } /** * Return an anumeration of all my outgoing queries. Elements are * of type <code>Query</code>. * * @see agg.util.csp.Query */ public final Enumeration<?> getOutgoingQueries() { return this.itsOutgoingQueries.elements(); } public final int getOutgoingQueriesCount() { return this.itsOutgoingQueries.size(); } /** * Return an enumeration of all my incoming queries. Enumeration elements * are of type <code>Query</code>. * * @see agg.util.csp.Query */ public final Enumeration<?> getIncomingQueries() { return this.itsIncomingQueries.elements(); } public final int getIncomingQueriesCount() { return this.itsIncomingQueries.size(); } public final Vector<Variable> getIncomingVariables() { Vector<Variable> vec = new Vector<Variable>(2); Enumeration<?> e = this.itsIncomingQueries.elements(); while (e.hasMoreElements()) { Variable v = ((Query) e.nextElement()).getTarget(); if (this != v) vec.add(v); } return vec; } public final Vector<Variable> getOutgoingVariables() { Vector<Variable> vec = new Vector<Variable>(2); Enumeration<?> e = this.itsOutgoingQueries.elements(); while (e.hasMoreElements()) { Variable v = ((Query) e.nextElement()).getTarget(); if (this != v) vec.add(v); } return vec; } /** Let me know of a new constraint which I'm involved in. */ protected final void addConstraint(BinaryConstraint c) { this.itsConstraints.add(c); this.itsWeight += c.getWeight(); } public final void removeConstraint(BinaryConstraint c) { this.itsWeight -= c.getWeight(); this.itsConstraints.remove(c); } /** Let me know of a query for which I am a source variable. */ protected final void addOutgoingQuery(Query q) { this.itsOutgoingQueries.add(q); this.itsWeight += q.getWeight(); } /** Let me know of a query for which I am the target variable. */ protected final void addIncomingQuery(Query q) { if (q instanceof Query_Type) { this.itsTypeQuery = (Query_Type) q; } this.itsIncomingQueries.add(q); } public Query_Type getTypeQuery() { return this.itsTypeQuery; } /** * Set the object for which this variable is defined. */ public void setGraphObject(final Object go) { this.LHSgo = go; if (this.LHSgo != null) { if (((GraphObject)this.LHSgo).isArc()) { // isEdge = true; this.convertedTypeString = ((Arc) this.LHSgo).convertToKey(); } else { this.convertedTypeString = ((Node) this.LHSgo).convertToKey(); } } } public String getConvertedTypeString() { return this.convertedTypeString; } /** * Get the object for which this variable defined. */ public Object getGraphObject() { return this.LHSgo; } /** * Set 0, if an object behind this variable is of type Node, set 1, if an * object behind this variable is of type Arc, otherwise -1. Default is -1. */ public void setKind(int kind) { this.kind = kind; } /** * Returns 0, if the object behind this variable is a Node, <br> * returns 1, if the object behind this variable is an Arc, <br> * otherwise -1. */ public int getKind() { if (this.kind == 0 || this.kind == 1) return this.kind; return -1; } public void setEnabled(boolean e) { this.enabled = e; } public boolean isEnabled() { return this.enabled; } }