001: /******************************************************************
002: * File: Node_RuleVariable.java
003: * Created by: Dave Reynolds
004: * Created on: 30-Mar-03
005: *
006: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
007: * [See end of file]
008: * $Id: Node_RuleVariable.java,v 1.20 2008/01/02 12:07:47 andy_seaborne Exp $
009: *****************************************************************/package com.hp.hpl.jena.reasoner.rulesys;
010:
011: import com.hp.hpl.jena.graph.Node;
012: import com.hp.hpl.jena.graph.Node_Variable;
013:
014: /**
015: * A variation on the normal Node_Variable which support for value bindings.
016: * Currently the forward rule system stores the values externally but requires
017: * variables to have an offset index in the rule environment vector. The
018: * variables can also suport prolog-like reference chains and trails but these
019: * are not yet used.
020: * <p>
021: * Note that this should not be used in a real Triple, in particular
022: * it should not end up in a Graph. It is only needed for the rule systems. </p>
023: *
024: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
025: * @version $Revision: 1.20 $ on $Date: 2008/01/02 12:07:47 $
026: */
027: public class Node_RuleVariable extends Node_Variable {
028: /** The offset of this variable in the Frule's binding table */
029: protected int index;
030:
031: /** The value to which this variable is bound, can be another variable,
032: * itself (meaning unbound) or an actual value */
033: protected Node value;
034:
035: /** A flag to indicate that the value is reference (pointer to a var) */
036: protected boolean isRef = true;
037:
038: /** A static wildcard - like Node.ANY but tests equl to other Node_RuleVariables */
039: public static final Node_RuleVariable WILD = new Node_RuleVariable(
040: "*", -1);
041:
042: /**
043: * Constructor
044: * @param label the text label for the variable
045: * @param index the calculated index of this variable in the rule
046: */
047: public Node_RuleVariable(String label, int index) {
048: super (new VarLabel(label));
049: this .index = index;
050: this .value = this ;
051: }
052:
053: /**
054: * Constructor
055: * @param label the text label for the variable
056: * @param index the calculated index of this variable in the rule
057: */
058: private Node_RuleVariable(VarLabel label, int index) {
059: super (label);
060: this .index = index;
061: this .value = this ;
062: }
063:
064: /**
065: * Returns the variable's index in a binding vector.
066: * @return int
067: */
068: public int getIndex() {
069: return index;
070: }
071:
072: /**
073: * Changes the variable's index. This is used in LP rules which classify the
074: * variables into different sequences.
075: */
076: public void setIndex(int index) {
077: this .index = index;
078: }
079:
080: /**
081: * Return an indexable object for this Node. This is actually the
082: * rule label. This is weird but needed because equals is (deliberately)
083: * perverse on Node_RuleVariable so if we want to put then in a Set or Map
084: * we need something with a better equals function.
085: */
086: // public Object getRepresentative() {
087: // return label;
088: // }
089: /**
090: * Binds a value to the brule version of the variable. Does not follow
091: * any reference trail, assues we have already been derefenced.
092: * @param node a concrete Node value or another Node_RuleVariable
093: * to alias to
094: */
095: public void simpleBind(Node node) {
096: value = node;
097: isRef = node instanceof Node_RuleVariable;
098: }
099:
100: /**
101: * Dereference a variable by following the reference chain.
102: * @return either a concrete node value or the last variable
103: * in the reference chain.
104: */
105: public Node deref() {
106: Node_RuleVariable var = this ;
107: while (var.isRef) {
108: if (var.value == var) {
109: return var;
110: }
111: var = (Node_RuleVariable) var.value;
112: }
113: return var.value;
114: }
115:
116: /**
117: * Return the raw value to which this variable is bound (via LP binding) with
118: * no dereferencing.
119: */
120: public Node getRawBoundValue() {
121: return value;
122: }
123:
124: /**
125: * Set the variable to be unbound (in the brule sense)
126: */
127: public void unbind() {
128: isRef = true;
129: value = this ;
130: }
131:
132: /**
133: * Test if the variable is unbound (in the brule sense).
134: */
135: public boolean isUnbound() {
136: return (isRef && (value == this ));
137: }
138:
139: /**
140: * Clone the rule variable to allow multiple rule instaces to be active at the same time.
141: */
142: public Node_RuleVariable cloneNode() {
143: return new Node_RuleVariable((VarLabel) label, index);
144: }
145:
146: /** printable form */
147: public String toString() {
148: String l = ((VarLabel) label).getLabel();
149: return (l == null) ? "*" : l;
150: }
151:
152: // Obsolete equality override this functionality has been moved into TriplePattern
153:
154: // /** Equality override - all rule variables are treated as equal
155: // * to support easy variant matching. */
156: // public boolean equals(Object o) {
157: // return o instanceof Node_RuleVariable;
158: // }
159: //
160: // /** hash function override - all vars have same hash code to support fast
161: // * search of variant tables */
162: // public int hashCode() {
163: // return 0xc3a7;
164: // }
165:
166: /**
167: * Test that two nodes are semantically equivalent.
168: */
169: public boolean sameValueAs(Object o) {
170: return o instanceof Node_RuleVariable;
171: }
172:
173: /**
174: * Compare two nodes, taking into account variable indices.
175: */
176: public static boolean sameNodeAs(Node n, Node m) {
177: if (n instanceof Node_RuleVariable) {
178: if (m instanceof Node_RuleVariable) {
179: return ((Node_RuleVariable) n).getIndex() == ((Node_RuleVariable) m)
180: .getIndex();
181: } else {
182: return false;
183: }
184: } else {
185: return n.sameValueAs(m);
186: }
187: }
188:
189: /** Inner class to wrap the label to ensure it is distinct from other usages */
190: static class VarLabel {
191:
192: /** The label being wrapped */
193: String label;
194:
195: VarLabel(String label) {
196: this .label = label;
197: }
198:
199: public String getLabel() {
200: return label;
201: }
202: }
203:
204: }
205:
206: /*
207: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
208: * All rights reserved.
209: *
210: * Redistribution and use in source and binary forms, with or without
211: * modification, are permitted provided that the following conditions
212: * are met:
213: * 1. Redistributions of source code must retain the above copyright
214: * notice, this list of conditions and the following disclaimer.
215: * 2. Redistributions in binary form must reproduce the above copyright
216: * notice, this list of conditions and the following disclaimer in the
217: * documentation and/or other materials provided with the distribution.
218: * 3. The name of the author may not be used to endorse or promote products
219: * derived from this software without specific prior written permission.
220: *
221: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
222: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
223: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
224: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
225: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
226: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
227: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
228: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
229: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
230: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
231: */
|