⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ruleclausecode.java

📁 jena2.5.4推理机系统的一种最基本实现 HP实验室出品
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/******************************************************************
 * 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 + -