📄 ruleclausecode.java
字号:
/******************************************************************
* File: RuleCode.java
* Created by: Dave Reynolds
* Created on: 18-Jul-2003
*
* (c) Copyright 2003, 2004, 2005, 2006, 2007 Hewlett-Packard Development Company, LP
* [See end of file]
* $Id: RuleClauseCode.java,v 1.11 2007/01/02 11:48:41 andy_seaborne Exp $
*****************************************************************/
package com.hp.hpl.jena.reasoner.rulesys.impl;
import com.hp.hpl.jena.reasoner.TriplePattern;
import com.hp.hpl.jena.reasoner.rulesys.*;
import com.hp.hpl.jena.graph.*;
import java.io.PrintStream;
import java.util.*;
/**
* Object used to hold the compiled bytecode stream for a single rule clause.
* This uses a slightly WAM-like code stream but gluing of the clauses together
* into disjunctions is done in the interpreter loop so a complete predicate is
* represented as a list of RuleClauseCode objects.
*
* @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
* @version $Revision: 1.11 $ on $Date: 2007/01/02 11:48:41 $
*/
public class RuleClauseCode {
// =======================================================================
// Variables
/** The rule from which is code was derived */
protected Rule rule;
/** The byte code sequence */
protected byte[] code;
/** Any Object argements needed by the byte codes */
protected Object[] args;
/** starting byte code offset for body terms */
protected int[] termStart;
// =======================================================================
// Instruction set constants
/** fetch constant argument (const, Ai) */
public static final byte GET_CONSTANT = 0x1;
/** fetch permanent variable argument, first occurance (Yi, Ai) */
public static final byte GET_VARIABLE = 0x2;
/** fetch permanent variable argument, later occurance (Yi, Ai) */
public static final byte UNIFY_VARIABLE = 0x3;
/** fetch temporary variable argument (Ti, Ai) */
public static final byte GET_TEMP = 0x4;
/** fetch temporary variable argument, later occurance (Ti, Ai) */
public static final byte UNIFY_TEMP = 0x12;
/** put constant value into call parameter (const, Ai) */
public static final byte PUT_CONSTANT = 0x5;
/** put permanaent variable into call parameter, first occurance (Yi, Ai) */
public static final byte PUT_NEW_VARIABLE = 0x6;
/** put permanaent variable into call parameter (Yi, Ai) */
public static final byte PUT_VARIABLE = 0x7;
/** put a dereferenced permanent variable into call parameter ready for BUILTIN call (Yi, Ai) */
public static final byte PUT_DEREF_VARIABLE = 0x14;
/** put temp variable into call parameter (Ti, Ai) */
public static final byte PUT_TEMP = 0x8;
/** call a predicate code object (predicateCodeList) */
public static final byte CALL_PREDICATE = 0x9;
/** deconstruct a functor argument (functor) */
public static final byte GET_FUNCTOR = 0xa;
/** call a predicate code object with run time indexing (predicateCodeList) */
public static final byte CALL_PREDICATE_INDEX = 0x17;
/** call a pure triple match (predicate) */
public static final byte CALL_TRIPLE_MATCH = 0x11;
/** variant on CALL_PREDICATE using the last call optimization, only current used in chain rules */
public static final byte LAST_CALL_PREDICATE = 0x13;
/** call a table code object () */
public static final byte CALL_TABLED = 0x18;
/** call a table code object from a wildcard () */
public static final byte CALL_WILD_TABLED = 0x19;
/** return from a call, proceeed along AND tree */
public static final byte PROCEED = 0xb;
/** create a functor object from a rule template (templateFunctor) */
public static final byte MAKE_FUNCTOR = 0xc;
/** call a built-in operation defined by a rule clause (clauseIndex( */
public static final byte CALL_BUILTIN = 0xd;
/** reset a permanent variable to an unbound variable (Yi) */
public static final byte CLEAR_VARIABLE = 0xe;
/** reset a temp variable to an unbound variable (Ti) */
public static final byte CLEAR_TEMP = 0xf;
/** reset an argument to an unbound variable (Ai) */
public static final byte CLEAR_ARG = 0x10;
/** Allocate a new environment frame */
public static final byte ALLOCATE = 0x16;
/** Test if an argument is bound (Ai) */
public static final byte TEST_BOUND = 0x20;
/** Test if an argument is unbound (Ai) */
public static final byte TEST_UNBOUND = 0x21;
// current next = 0x22
/** The maximum number of permanent variables allowed in a single rule clause.
* Now only relevent for initial holding clause. */
public static final int MAX_PERMANENT_VARS = 15;
/** The maximum number of argument variables allowed in a single goal
* Future refactorings will remove this restriction. */
public static final int MAX_ARGUMENT_VARS = 8;
/** The maximum number of temporary variables allowed in a single rule clause. */
public static final int MAX_TEMPORARY_VARS = 8;
/** Dummy code block which just returns */
public static RuleClauseCode returnCodeBlock;
static {
returnCodeBlock = new RuleClauseCode(null);
returnCodeBlock.code = new byte[] {PROCEED};
}
// =======================================================================
// Methods and constructors
/**
* Constructor.
* @param rule the rule to be compiled
*/
public RuleClauseCode(Rule rule) {
this.rule = rule;
}
/**
* Return the byte code vector for this clause.
*/
public byte[] getCode() {
return code;
}
/**
* Return the argument vector associated with this clauses' byte codes.
*/
public Object[] getArgs() {
return args;
}
/**
* Return the rule from which this code block was compiled.
*/
public Rule getRule() {
return rule;
}
/**
* Compile the rule into byte code.
* @param ruleStore the store of LP rules through which calls to other predicates
* can be resolved.
*/
public void compile(LPRuleStore ruleStore) {
CompileState state = new CompileState(rule);
// Compile any early binding tests
int skip = 0; // state.emitBindingTests();
// Compile the head operations
ClauseEntry head = rule.getHeadElement(0);
if (!(head instanceof TriplePattern)) {
throw new LPRuleSyntaxException("Heads of backward rules must be triple patterns", rule);
}
state.emitHead((TriplePattern)head);
// Compile the body operations
termStart = new int[rule.bodyLength()];
for (int i = skip; i < rule.bodyLength(); i++) {
termStart[i] = state.p;
ClauseEntry entry = rule.getBodyElement(i);
if (entry instanceof TriplePattern) {
state.emitBody((TriplePattern)entry, ruleStore);
} else if (entry instanceof Functor) {
state.emitBody((Functor)entry);
} else {
throw new LPRuleSyntaxException("can't create new bRules in an bRule", rule);
}
}
// Extract the final code
code = state.getFinalCode();
args = state.getFinalArgs();
}
/**
* Translate a program counter offset to the index of the corresponding
* body term (or -1 if a head term or a dummy rule).
*/
public int termIndex(int pc) {
if (rule == null) return -1;
int term = 0;
// Trivial linear search because this is only used for logging which is
// horribly expensive anyway.
while (term < rule.bodyLength()) {
if (pc <= termStart[term]) {
return term - 1;
}
term++;
}
return term - 1;
}
/**
* Debug helper - list the code to a stream
*/
public void print(PrintStream out) {
if (code == null) {
out.println("Code not available");
} else {
int argi = 0;
for (int p = 0; p < code.length; ) {
byte instruction = code[p++];
switch (instruction) {
case GET_CONSTANT:
out.println("GET_CONSTANT " + args[argi++] + ", A" + code[p++]);
break;
case GET_VARIABLE:
out.println("GET_VARIABLE " + "Y" + code[p++] + ", A" + code[p++]);
break;
case UNIFY_VARIABLE:
out.println("UNIFY_VARIABLE " + "Y" + code[p++] + ", A" + code[p++]);
break;
case GET_TEMP:
out.println("GET_TEMP " + "T" + code[p++] + ", A" + code[p++]);
break;
case UNIFY_TEMP:
out.println("UNIFY_TEMP " + "T" + code[p++] + ", A" + code[p++]);
break;
case PUT_CONSTANT:
out.println("PUT_CONSTANT " + args[argi++] + ", A" + code[p++]);
break;
case PUT_NEW_VARIABLE:
out.println("PUT_NEW_VARIABLE " + "Y" + code[p++] + ", A" + code[p++]);
break;
case PUT_TEMP:
out.println("PUT_TEMP " + "T" + code[p++] + ", A" + code[p++]);
break;
case PUT_VARIABLE:
out.println("PUT_VARIABLE " + "Y" + code[p++] + ", A" + code[p++]);
break;
case PUT_DEREF_VARIABLE:
out.println("PUT_DEREF_VARIABLE " + "Y" + code[p++] + ", A" + code[p++]);
break;
case TEST_BOUND:
out.println("TEST_BOUND A" + code[p++]);
break;
case TEST_UNBOUND:
out.println("TEST_UNBOUND A" + code[p++]);
break;
case CALL_PREDICATE:
out.println("CALL_PREDICATE " + args[argi++]);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -