📄 bindingvector.java
字号:
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < environment.length; i++) {
if (environment[i] == null) {
buffer.append("-");
} else {
buffer.append(PrintUtil.print(environment[i]));
}
buffer.append(" ");
}
return buffer.toString();
}
/**
* Unify a goal with the head of a rule. This is a poor-man's unification,
* we should try swtiching to a more conventional global-variables-with-trail
* implementation in the future.
* @param goal the goal pattern which it being matched to a rule
* @param head the head pattern of the rule which is being instantiated
* @param numRuleVars the length of the environment to allocate.
* @return An initialized binding environment for the rule variables
* or null if the unification fails. If a variable in the environment becomes
* aliased to another variable through the unification this is represented
* by having its value in the environment be the variable to which it is aliased.
*/
public static BindingVector unify(TriplePattern goal, TriplePattern head, int numRuleVars) {
Node[] gEnv = new Node[numRuleVars]; // TODO: check
Node[] hEnv = new Node[numRuleVars];
if (!unify(goal.getSubject(), head.getSubject(), gEnv, hEnv)) {
return null;
}
if (!unify(goal.getPredicate(), head.getPredicate(), gEnv, hEnv)) {
return null;
}
Node gObj = goal.getObject();
Node hObj = head.getObject();
if (Functor.isFunctor(gObj)) {
Functor gFunctor = (Functor)gObj.getLiteralValue();
if (Functor.isFunctor(hObj)) {
Functor hFunctor = (Functor)hObj.getLiteralValue();
if ( ! gFunctor.getName().equals(hFunctor.getName()) ) {
return null;
}
Node[] gArgs = gFunctor.getArgs();
Node[] hArgs = hFunctor.getArgs();
if ( gArgs.length != hArgs.length ) return null;
for (int i = 0; i < gArgs.length; i++) {
if (! unify(gArgs[i], hArgs[i], gEnv, hEnv) ) {
return null;
}
}
} else if (hObj instanceof Node_RuleVariable) {
// temp debug ...
// Check the goal functor is fully ground
if (gFunctor.isGround(new BindingVector(gEnv))) {
if (!unify(gObj, hObj, gEnv, hEnv)) return null;
}
// ... end debug
} else {
// unifying simple ground object with functor, failure
return null;
}
} else {
if (!unify(gObj, hObj, gEnv, hEnv)) return null;
}
// Successful bind if we get here
return new BindingVector(hEnv);
}
/**
* Unify a single pair of goal/head nodes. Unification of a head var to
* a goal var is recorded using an Integer in the head env to point to a
* goal env and storing the head var in the goal env slot.
* @return true if they are unifiable, side effects the environments
*/
private static boolean unify(Node gNode, Node hNode, Node[] gEnv, Node[] hEnv) {
if (hNode instanceof Node_RuleVariable) {
int hIndex = ((Node_RuleVariable)hNode).getIndex();
if (gNode instanceof Node_RuleVariable) {
// Record variable bind between head and goal to detect aliases
int gIndex = ((Node_RuleVariable)gNode).getIndex();
if (gIndex < 0) return true;
if (gEnv[gIndex] == null) {
// First time bind so record link
gEnv[gIndex] = hNode;
} else {
// aliased var so follow trail to alias
// but ignore self-aliases
Node gVal = gEnv[gIndex];
if (hIndex != gIndex || ! (gVal instanceof Node_RuleVariable)) {
hEnv[hIndex] = gVal;
}
}
} else {
Node hVal = hEnv[hIndex];
if (hVal == null) {
hEnv[hIndex] = gNode;
} else {
// Already bound
if (hVal instanceof Node_RuleVariable) {
// Already an aliased variable, so bind both this an the alias
hEnv[((Node_RuleVariable)hVal).getIndex()] = gNode;
hEnv[hIndex] = gNode;
} else {
// Already bound to a ground node
return hVal.sameValueAs(gNode);
}
}
}
return true;
} else {
if (gNode instanceof Node_RuleVariable) {
int gIndex = ((Node_RuleVariable)gNode).getIndex();
if (gIndex < 0) return true;
Node gVal = gEnv[gIndex];
if (gVal == null) {
//. No variable alias so just record binding
gEnv[gIndex] = hNode;
} else if (gVal instanceof Node_RuleVariable) {
// Already an alias
hEnv[((Node_RuleVariable)gVal).getIndex()] = hNode;
gEnv[gIndex] = hNode;
} else {
return gVal.sameValueAs(hNode);
}
return true;
} else {
return hNode.sameValueAs(gNode);
}
}
}
/** Equality override */
public boolean equals(Object o) {
// Pass 1 - just check basic shape
if (! (o instanceof BindingVector) ) return false;
Node[] other = ((BindingVector)o).environment;
if (environment.length != other.length) return false;
for (int i = 0; i < environment.length; i++) {
Node n = environment[i];
Node no = other[i];
if (n == null) {
if (no != null) return false;
} else {
if (! n.sameValueAs(no)) return false;
}
}
return true;
}
/** hash function override */
public int hashCode() {
int hash = 0;
for (int i = 0; i < environment.length; i++) {
Node n = environment[i];
hash = (hash << 1) ^ (n == null ? 0x537c: n.hashCode());
}
return hash;
}
}
/*
(c) Copyright 2003, 2004, 2005, 2006, 2007 Hewlett-Packard Development Company, LP
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -