001: /******************************************************************
002: * File: RuleContext.java
003: * Created by: Dave Reynolds
004: * Created on: 15-Apr-2003
005: *
006: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
007: * [See end of file]
008: * $Id: BFRuleContext.java,v 1.18 2008/01/02 12:06:17 andy_seaborne Exp $
009: *****************************************************************/package com.hp.hpl.jena.reasoner.rulesys.impl;
010:
011: import com.hp.hpl.jena.reasoner.*;
012: import com.hp.hpl.jena.reasoner.rulesys.*;
013: import com.hp.hpl.jena.util.PrintUtil;
014: import com.hp.hpl.jena.util.iterator.ClosableIterator;
015: import com.hp.hpl.jena.graph.*;
016:
017: import java.util.*;
018: import org.apache.commons.logging.Log;
019: import org.apache.commons.logging.LogFactory;
020:
021: /**
022: * An implementation of the generic RuleContext interface used by
023: * the basic forward (BF) rule engine. This provides additional
024: * methods specific to the functioning of that engine.
025: *
026: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
027: * @version $Revision: 1.18 $ on $Date: 2008/01/02 12:06:17 $
028: */
029: public class BFRuleContext implements RuleContext {
030: /** The binding environment which represents the state of the current rule execution. */
031: protected BindingStack env;
032:
033: /** The rule current being executed. */
034: protected Rule rule;
035:
036: /** The enclosing inference graph. */
037: protected ForwardRuleInfGraphI graph;
038:
039: /** A stack of triples which have been added to the graph but haven't yet been processed. */
040: protected List stack;
041:
042: /** A temporary list of Triples which will be added to the stack and triples at the end of a rule scan */
043: protected List pending;
044:
045: /** A temporary list of Triples which will be removed from the graph at the end of a rule scan */
046: protected List deletesPending = new ArrayList();
047:
048: /** A searchable index into the pending triples */
049: protected Graph pendingCache;
050:
051: protected static Log logger = LogFactory
052: .getLog(BFRuleContext.class);
053:
054: /**
055: * Constructor.
056: * @param graph the inference graph which owns this context.
057: */
058: public BFRuleContext(ForwardRuleInfGraphI graph) {
059: this .graph = graph;
060: env = new BindingStack();
061: stack = new ArrayList();
062: pending = new ArrayList();
063: pendingCache = Factory.createGraphMem();
064: }
065:
066: /**
067: * Returns the current variable binding environment for the current rule.
068: * @return BindingEnvironment
069: */
070: public BindingEnvironment getEnv() {
071: return env;
072: }
073:
074: /**
075: * Variant of the generic getEnv interface specific to the basic
076: * forward rule system.
077: * Returns the current variable binding environment for the current rule.
078: * @return BindingStack
079: */
080: public BindingStack getEnvStack() {
081: return env;
082: }
083:
084: /**
085: * Returns the graph.
086: * @return InfGraph
087: */
088: public InfGraph getGraph() {
089: return graph;
090: }
091:
092: /**
093: * Returns the rule.
094: * @return Rule
095: */
096: public Rule getRule() {
097: return rule;
098: }
099:
100: /**
101: * Sets the rule.
102: * @param rule The rule to set
103: */
104: public void setRule(Rule rule) {
105: this .rule = rule;
106: }
107:
108: /**
109: * Add a triple to the stack of triples to waiting to be processed by the rule engine.
110: */
111: public void addTriple(Triple t) {
112: if (graph.shouldTrace()) {
113: if (rule != null) {
114: logger.debug("Adding to stack (" + rule.toShortString()
115: + "): " + PrintUtil.print(t));
116: } else {
117: logger.debug("Adding to stack : " + PrintUtil.print(t));
118: }
119: }
120: stack.add(t);
121: }
122:
123: /**
124: * Add a triple to a temporary "pending" store, ready to be added to added to the
125: * deductions graph and the processing stack later.
126: * <p>This is needed to prevent concurrrent modification exceptions which searching
127: * the deductions for matches to a given rule.
128: */
129: public void add(Triple t) {
130: if (graph.shouldTrace()) {
131: if (rule != null) {
132: logger.debug("Adding to pending ("
133: + rule.toShortString() + "): "
134: + PrintUtil.print(t));
135: } else {
136: logger.debug("Adding to pending : "
137: + PrintUtil.print(t));
138: }
139: }
140: pending.add(t);
141: //pendingCache.add(t);
142: }
143:
144: /**
145: * Take all the pending triples and add them to both the given graph and
146: * to the processing stack.
147: */
148: public void flushPending() {
149: for (Iterator i = pending.iterator(); i.hasNext();) {
150: Triple t = (Triple) i.next();
151: stack.add(t);
152: graph.addDeduction(t);
153: i.remove();
154: // pendingCache.delete(t);
155: }
156: pending.clear();
157: // Flush out pending removes as well
158: for (Iterator i = deletesPending.iterator(); i.hasNext();) {
159: Triple t = (Triple) i.next();
160: graph.delete(t);
161: }
162: deletesPending.clear();
163: }
164:
165: /**
166: * Return true if the triple is already in either the graph or the stack.
167: * I.e. it has already been deduced.
168: */
169: public boolean contains(Triple t) {
170: // Can't use stackCache.contains because that does not do semantic equality
171: return contains(t.getSubject(), t.getPredicate(), t.getObject());
172: }
173:
174: /**
175: * Return true if the triple pattern is already in either the graph or the stack.
176: * I.e. it has already been deduced.
177: */
178: public boolean contains(Node s, Node p, Node o) {
179: // Can't use stackCache.contains because that does not do semantic equality
180: ClosableIterator it = find(s, p, o);
181: boolean result = it.hasNext();
182: it.close();
183: return result;
184: }
185:
186: /**
187: * In some formulations the context includes deductions that are not yet
188: * visible to the underlying graph but need to be checked for.
189: * However, currently this calls the graph find directly.
190: */
191: public ClosableIterator find(Node s, Node p, Node o) {
192: //return graph.find(s, p, o).andThen(pendingCache.find(s, p, o));
193: return graph.findDataMatches(s, p, o);
194: }
195:
196: /**
197: * Return the next triple to be added to the graph, removing it from
198: * the stack.
199: * @return the Triple or null if there are no more
200: */
201: public Triple getNextTriple() {
202: if (stack.size() > 0) {
203: Triple t = (Triple) stack.remove(stack.size() - 1);
204: return t;
205: } else {
206: return null;
207: }
208: }
209:
210: /**
211: * Reset the binding environemnt back to empty.
212: * @param newSize the number of variables needed for processing the new rule
213: */
214: public void resetEnv(int newSize) {
215: env.reset(newSize);
216: }
217:
218: /**
219: * Assert a new triple in the deduction graph, bypassing any processing machinery.
220: */
221: public void silentAdd(Triple t) {
222: ((SilentAddI) graph).silentAdd(t);
223: }
224:
225: /**
226: * Remove a triple from the deduction graph (and the original graph if relevant).
227: */
228: public void remove(Triple t) {
229: deletesPending.add(t);
230: // graph.delete(t);
231: }
232:
233: }
234:
235: /*
236: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
237: All rights reserved.
238:
239: Redistribution and use in source and binary forms, with or without
240: modification, are permitted provided that the following conditions
241: are met:
242:
243: 1. Redistributions of source code must retain the above copyright
244: notice, this list of conditions and the following disclaimer.
245:
246: 2. Redistributions in binary form must reproduce the above copyright
247: notice, this list of conditions and the following disclaimer in the
248: documentation and/or other materials provided with the distribution.
249:
250: 3. The name of the author may not be used to endorse or promote products
251: derived from this software without specific prior written permission.
252:
253: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
254: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
255: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
256: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
257: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
258: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
259: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
260: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
261: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
262: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
263: */
|