📄 basicforwardruleinfgraph.java
字号:
/******************************************************************
* File: BasicForwardRuleInfGraph.java
* Created by: Dave Reynolds
* Created on: 30-Mar-03
*
* (c) Copyright 2003, 2004, 2005, 2006, 2007 Hewlett-Packard Development Company, LP
* [See end of file]
* $Id: BasicForwardRuleInfGraph.java,v 1.48 2007/01/12 14:13:48 chris-dollin Exp $
*****************************************************************/
package com.hp.hpl.jena.reasoner.rulesys;
import com.hp.hpl.jena.reasoner.*;
import com.hp.hpl.jena.reasoner.rulesys.impl.*;
import com.hp.hpl.jena.shared.ReificationStyle;
import com.hp.hpl.jena.graph.*;
import java.util.*;
import com.hp.hpl.jena.util.OneToManyMap;
import com.hp.hpl.jena.util.iterator.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* An inference graph interface that runs a set of forward chaining
* rules to conclusion on each added triple and stores the entire
* result set.
* <p>
* This implementation has a horribly inefficient rule chainer built in.
* Once we have this working generalize this to an interface than
* can call out to a rule engine and build a real rule engine (e.g. Rete style). </p>
*
* @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
* @version $Revision: 1.48 $ on $Date: 2007/01/12 14:13:48 $
*/
public class BasicForwardRuleInfGraph extends BaseInfGraph implements ForwardRuleInfGraphI {
//=======================================================================
// variables
/** Table of derivation records, maps from triple to RuleDerivation */
protected OneToManyMap derivations;
/** The set of deduced triples, this is in addition to base triples in the fdata graph */
protected FGraph fdeductions;
/** Reference to any schema graph data bound into the parent reasoner */
protected Graph schemaGraph;
/** The forward rule engine being used */
protected FRuleEngineI engine;
/** The original rule set as supplied */
protected List rules;
/** Flag which, if true, enables tracing of rule actions to logger.info */
protected boolean traceOn = false;
protected static Log logger = LogFactory.getLog(BasicForwardRuleInfGraph.class);
//=======================================================================
// Core methods
/**
* Constructor. Creates a new inference graph to which a (compiled) rule set
* and a data graph can be attached. This separation of binding is useful to allow
* any configuration parameters (such as logging) to be set before the data is added.
* Note that until the data is added using {@link #rebind rebind} then any operations
* like add, remove, find will result in errors.
*
* @param reasoner the parent reasoner
* @param schema the (optional) schema data which is being processed
*/
public BasicForwardRuleInfGraph(Reasoner reasoner, Graph schema) {
super(null, reasoner);
instantiateRuleEngine(null);
this.schemaGraph = schema;
}
/**
* Constructor. Creates a new inference graph based on the given rule set.
* No data graph is attached at this stage. This is to allow
* any configuration parameters (such as logging) to be set before the data is added.
* Note that until the data is added using {@link #rebind rebind} then any operations
* like add, remove, find will result in errors.
*
* @param reasoner the parent reasoner
* @param rules the list of rules to use this time
* @param schema the (optional) schema or preload data which is being processed
*/
public BasicForwardRuleInfGraph(Reasoner reasoner, List rules, Graph schema) {
this( reasoner, rules, schema, ReificationStyle.Minimal );
}
public BasicForwardRuleInfGraph( Reasoner reasoner, List rules, Graph schema, ReificationStyle style )
{
super( null, reasoner, style );
instantiateRuleEngine( rules );
this.rules = rules;
this.schemaGraph = schema;
}
/**
* Constructor. Creates a new inference graph based on the given rule set
* then processes the initial data graph. No precomputed deductions are loaded.
*
* @param reasoner the parent reasoner
* @param rules the list of rules to use this time
* @param schema the (optional) schema or preload data which is being processed
* @param data the data graph to be processed
*/
public BasicForwardRuleInfGraph(Reasoner reasoner, List rules, Graph schema, Graph data) {
this(reasoner, rules, schema);
rebind(data);
}
/**
* Instantiate the forward rule engine to use.
* Subclasses can override this to switch to, say, a RETE imlementation.
* @param rules the rule set or null if there are not rules bound in yet.
*/
protected void instantiateRuleEngine(List rules) {
if (rules != null) {
engine = new FRuleEngine(this, rules);
} else {
engine = new FRuleEngine(this);
}
}
/**
* Attach a compiled rule set to this inference graph.
* @param ruleStore a compiled set of rules (i.e. the result of an FRuleEngine.compile).
*/
public void setRuleStore(Object ruleStore) {
engine.setRuleStore(ruleStore);
}
/**
* Replace the underlying data graph for this inference graph and start any
* inferences over again. This is primarily using in setting up ontology imports
* processing to allow an imports multiunion graph to be inserted between the
* inference graph and the raw data, before processing.
* @param data the new raw data graph
*/
public void rebind(Graph data) {
fdata = new FGraph( data );
rebind();
}
/**
* Cause the inference graph to reconsult the underlying graph to take
* into account changes. Normally changes are made through the InfGraph's add and
* remove calls are will be handled appropriately. However, in some cases changes
* are made "behind the InfGraph's back" and this forces a full reconsult of
* the changed data.
*/
public void rebind() {
version++;
isPrepared = false;
}
/**
* Return the schema graph, if any, bound into this inference graph.
*/
public Graph getSchemaGraph() {
return schemaGraph;
}
/**
* Perform any initial processing and caching. This call is optional. Most
* engines either have negligable set up work or will perform an implicit
* "prepare" if necessary. The call is provided for those occasions where
* substantial preparation work is possible (e.g. running a forward chaining
* rule system) and where an application might wish greater control over when
* this prepration is done.
*/
public synchronized void prepare() {
if (isPrepared) return;
isPrepared = true;
// initilize the deductions graph
fdeductions = new FGraph( createDeductionsGraph() );
boolean rulesLoaded = false;
if (schemaGraph != null) {
rulesLoaded = preloadDeductions(schemaGraph);
}
if (rulesLoaded) {
engine.fastInit(fdata);
} else {
engine.init(true, fdata);
}
}
/**
* Adds a set of precomputed triples to the deductions store. These do not, themselves,
* fire any rules but provide additional axioms that might enable future rule
* firing when real data is added. Used to implement bindSchema processing
* in the parent Reasoner.
* @return return true if the rule set has also been loaded
*/
protected boolean preloadDeductions(Graph preloadIn) {
Graph d = fdeductions.getGraph();
BasicForwardRuleInfGraph preload = (BasicForwardRuleInfGraph) preloadIn;
// If the rule set is the same we can reuse those as well
if (preload.rules == rules) {
// Load raw deductions
for (Iterator i = preload.find(null, null, null); i.hasNext(); ) {
d.add((Triple)i.next());
}
engine.setRuleStore(preload.engine.getRuleStore());
return true;
} else {
return false;
}
}
/**
* Add a new deduction to the deductions graph.
*/
public void addDeduction(Triple t) {
getDeductionsGraph().add(t);
}
/**
* Extended find interface used in situations where the implementator
* may or may not be able to answer the complete query. It will
* attempt to answer the pattern but if its answers are not known
* to be complete then it will also pass the request on to the nested
* Finder to append more results.
* @param pattern a TriplePattern to be matched against the data
* @param continuation either a Finder or a normal Graph which
* will be asked for additional match results if the implementor
* may not have completely satisfied the query.
*/
public ExtendedIterator findWithContinuation(TriplePattern pattern, Finder continuation) {
checkOpen();
if (!isPrepared) prepare();
ExtendedIterator result = null;
if (fdata == null) {
result = fdeductions.findWithContinuation(pattern, continuation);
} else {
if (continuation == null) {
result = fdata.findWithContinuation(pattern, fdeductions);
} else {
result = fdata.findWithContinuation(pattern, FinderUtil.cascade(fdeductions, continuation) );
}
}
return result.filterDrop(Functor.acceptFilter);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -