| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.jena.reasoner.rulesys; |
| |
| import org.apache.jena.graph.Node ; |
| import org.apache.jena.graph.Node_Variable ; |
| |
| /** |
| * A variation on the normal Node_Variable which support for value bindings. |
| * Currently the forward rule system stores the values externally but requires |
| * variables to have an offset index in the rule environment vector. The |
| * variables can also support prolog-like reference chains and trails but these |
| * are not yet used. |
| * <p> |
| * Note that this should not be used in a real Triple, in particular |
| * it should not end up in a Graph. It is only needed for the rule systems. </p> |
| */ |
| public class Node_RuleVariable extends Node_Variable { |
| /** The offset of this variable in the Frule's binding table */ |
| protected int index; |
| |
| /** The value to which this variable is bound, can be another variable, |
| * itself (meaning unbound) or an actual value */ |
| protected Node value; |
| |
| /** A flag to indicate that the value is reference (pointer to a var) */ |
| protected boolean isRef = true; |
| |
| /** A static wildcard - like Node.ANY but tests equal to other Node_RuleVariables */ |
| public static final Node_RuleVariable WILD = new Node_RuleVariable("*", -1); |
| |
| /** |
| * Constructor |
| * @param label the text label for the variable |
| * @param index the calculated index of this variable in the rule |
| */ |
| public Node_RuleVariable(String label, int index) { |
| //super(label==null ? "" : label); |
| super(label); |
| this.index = index; |
| this.value = this; |
| } |
| |
| /** |
| * Returns the variable's index in a binding vector. |
| * @return int |
| */ |
| public int getIndex() { |
| return index; |
| } |
| |
| /** |
| * Changes the variable's index. This is used in LP rules which classify the |
| * variables into different sequences. |
| */ |
| public void setIndex(int index) { |
| this.index = index; |
| } |
| |
| /** |
| * Return an indexable object for this Node. This is actually the |
| * rule label. This is weird but needed because equals is (deliberately) |
| * perverse on Node_RuleVariable so if we want to put then in a Set or Map |
| * we need something with a better equals function. |
| */ |
| // public Object getRepresentative() { |
| // return label; |
| // } |
| |
| /** |
| * Binds a value to the brule version of the variable. Does not follow |
| * any reference trail, assues we have already been derefenced. |
| * @param node a concrete Node value or another Node_RuleVariable |
| * to alias to |
| */ |
| public void simpleBind(Node node) { |
| value = node; |
| isRef = node instanceof Node_RuleVariable; |
| } |
| |
| /** |
| * Dereference a variable by following the reference chain. |
| * @return either a concrete node value or the last variable |
| * in the reference chain. |
| */ |
| public Node deref() { |
| Node_RuleVariable var = this; |
| while (var.isRef) { |
| if (var.value == var) { |
| return var; |
| } |
| var = (Node_RuleVariable)var.value; |
| } |
| return var.value; |
| } |
| |
| /** |
| * Return the raw value to which this variable is bound (via LP binding) with |
| * no dereferencing. |
| */ |
| public Node getRawBoundValue() { |
| return value; |
| } |
| |
| /** |
| * Set the variable to be unbound (in the brule sense) |
| */ |
| public void unbind() { |
| isRef = true; |
| value = this; |
| } |
| |
| /** |
| * Test if the variable is unbound (in the brule sense). |
| */ |
| public boolean isUnbound() { |
| return (isRef && (value == this)); |
| } |
| |
| /** |
| * Clone the rule variable to allow multiple rule instaces to be active at the same time. |
| */ |
| public Node_RuleVariable cloneNode() { |
| return new Node_RuleVariable(getName(), index); |
| } |
| |
| /** printable form */ |
| @Override |
| public String toString() { |
| if (getName() == null) return "*"; |
| return getName(); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (o instanceof Node_RuleVariable) { |
| String name = getName(); |
| if (name == null) { |
| return this == o; |
| } else { |
| return name.equals( ((Node_RuleVariable)o).getName() ); |
| } |
| } else |
| return false; |
| } |
| |
| @Override |
| public int hashCode() { |
| String name = getName(); |
| if (name == null) { |
| return 0xc3a7; |
| } else { |
| return name.hashCode(); |
| } |
| } |
| |
| /** |
| * Test that two nodes are semantically equivalent. |
| */ |
| @Override |
| public boolean sameValueAs(Object o) { |
| return o instanceof Node_RuleVariable; |
| } |
| |
| /** |
| * Compare two nodes, taking into account variable indices. |
| */ |
| public static boolean sameNodeAs(Node n, Node m) { |
| if (n instanceof Node_RuleVariable) { |
| if (m instanceof Node_RuleVariable) { |
| return ((Node_RuleVariable)n).getIndex() == ((Node_RuleVariable)m).getIndex(); |
| } else { |
| return false; |
| } |
| } else { |
| return n.sameValueAs(m); |
| } |
| } |
| |
| } |