001: /******************************************************************
002: * File: GoalResults.java
003: * Created by: Dave Reynolds
004: * Created on: 03-May-2003
005: *
006: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
007: * [See end of file]
008: * $Id: GoalResults.java,v 1.8 2008/01/02 12:09:45 andy_seaborne Exp $
009: *****************************************************************/package com.hp.hpl.jena.reasoner.rulesys.impl.oldCode;
010:
011: import com.hp.hpl.jena.graph.Triple;
012: import com.hp.hpl.jena.reasoner.*;
013: import com.hp.hpl.jena.reasoner.rulesys.*;
014:
015: import java.util.*;
016: import org.apache.commons.logging.Log;
017: import org.apache.commons.logging.LogFactory;
018:
019: /**
020: * Part of the backward chaining rule interpreter. The goal table
021: * is a table of partially evaluated goals. Each entry is an instance
022: * of GoalResults which contains the goal (a generalized triple pattern
023: * which supports structured literals), a set of triple values, a completion
024: * flag and a generator (which represents a continuation point for
025: * finding further goal values). This is essentially an encapsulation of
026: * the OR graph of the evaluation trace.
027: * <p>
028: * This implementation is not very space efficient. Once a GoalResult is
029: * complete we could flush all the results out to a single shared deductions
030: * graph in the inference engine wrapper. Care would be needed to do this
031: * in a thread-safe fashion since there can be multiple GoalStates scanning each
032: * GoalResult at any given time.
033: * </p>
034: *
035: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
036: * @version $Revision: 1.8 $ on $Date: 2008/01/02 12:09:45 $
037: */
038: public class GoalResults {
039:
040: // =======================================================================
041: // variables
042:
043: /** The goal who values are being memoised by this entry */
044: protected TriplePattern goal;
045:
046: /** The sequence of answers available so far */
047: protected ArrayList resultSet;
048:
049: /** A searchable version of the resultSet */
050: protected HashSet resultSetIndex;
051:
052: /** True if all the values for this goal are known */
053: protected boolean isComplete;
054:
055: /** True if this goal generator has started running */
056: protected boolean started = false;
057:
058: /** The set of RuleStates which are currently blocked
059: * waiting for this table entry to have more results */
060: protected Set dependents = new HashSet();
061:
062: /** The rule engine which this table entry is part of */
063: protected BRuleEngine engine;
064:
065: /** Reference count of the number of rulestates working on values for this entry */
066: protected int refCount = 0;
067:
068: /** Flag to indicate that the goal is a singleton and so should close once one result is in */
069: protected boolean isSingleton = false;
070:
071: static Log logger = LogFactory.getLog(GoalResults.class);
072:
073: // =======================================================================
074: // methods
075:
076: /**
077: * Contructor.
078: *
079: * @param goal the goal whose matches are to be memoised.
080: * @param ruleEngine the parent rule engine for the goal table containing this entry
081: */
082: public GoalResults(TriplePattern goal, BRuleEngine ruleEngine) {
083: this .goal = goal;
084: resultSet = new ArrayList();
085: resultSetIndex = new HashSet();
086: isComplete = false;
087: engine = ruleEngine;
088: isSingleton = !(goal.getSubject().isVariable()
089: || goal.getPredicate().isVariable() || goal.getObject()
090: .isVariable());
091: }
092:
093: /**
094: * Return true of this goal is known to have been completely
095: * evaluated.
096: */
097: public boolean isComplete() {
098: return isComplete;
099: }
100:
101: /**
102: * Return the number of available memoized results for this goal.
103: */
104: public int numResults() {
105: if (!started)
106: start();
107: return resultSet.size();
108: }
109:
110: /**
111: * Return the n'th memoized result for this goal.
112: */
113: public Triple getResult(int n) {
114: return (Triple) resultSet.get(n);
115: }
116:
117: /**
118: * Record that a rule node has suspened waiting for more
119: * results from this subgoal
120: */
121: public void addDependent(RuleState dependent) {
122: if (!isComplete)
123: dependents.add(dependent);
124: }
125:
126: /**
127: * Move all the blocked dependents to the agenda for further processing.
128: */
129: public void flushDependents() {
130: for (Iterator i = dependents.iterator(); i.hasNext();) {
131: RuleState dep = (RuleState) i.next();
132: engine.prependToAgenda(dep);
133: }
134: // dependents.clear();
135: }
136:
137: /**
138: * Return the rule engine processing this goal
139: */
140: public BRuleEngine getEngine() {
141: return engine;
142: }
143:
144: /**
145: * Indicate that the goal has completed.
146: */
147: public void setComplete() {
148: if (!isComplete) {
149: if (engine.isTraceOn()) {
150: logger.debug("Completed " + this );
151: }
152: isComplete = true;
153: resultSetIndex = null;
154: flushDependents();
155: dependents.clear();
156: }
157: }
158:
159: /**
160: * Indicate that all goals have been completed, sets this to complete
161: * but does not bother to add the dependents to the agenda.
162: */
163: public void setAllComplete() {
164: isComplete = true;
165: dependents.clear();
166: }
167:
168: /**
169: * Start up a GoalResults stream. This finds all the relevant rules
170: * and adds initial states for them to the agenda.
171: */
172: public void start() {
173: List rules = engine.rulesFor(goal);
174: for (Iterator i = rules.iterator(); i.hasNext();) {
175: Rule rule = (Rule) i.next();
176: RuleState rs = RuleState.createInitialState(rule, this );
177: if (rs != null) {
178: engine.appendToAgenda(rs);
179: }
180: }
181: if (refCount <= 0)
182: setComplete();
183: started = true;
184: }
185:
186: /**
187: * Add a new result to the result set for this goal.
188: * @return ture if this is a new result for this goal
189: */
190: public boolean addResult(Triple result) {
191: if (!isComplete && !resultSetIndex.contains(result)) {
192: // Temp ... replace when we flush results to the deductions graph
193: // TODO remove
194: // if (engine.infGraph.dataContains(result)) return false;
195: // ... end temp
196: resultSet.add(result);
197: resultSetIndex.add(result);
198: if (isSingleton) {
199: setComplete();
200: } else {
201: flushDependents();
202: }
203: return true;
204: }
205: return false;
206: }
207:
208: /**
209: * Increment the reference count, called when a new RuleState refering to this result set
210: * is created.
211: */
212: public void incRefCount() {
213: refCount++;
214: }
215:
216: /**
217: * Decrement the reference count, called when a RuleState for this result set either
218: * fails or completes.
219: */
220: public void decRefCount() {
221: refCount--;
222: if (refCount <= 0) {
223: setComplete();
224: }
225: }
226:
227: /**
228: * Printable form
229: */
230: public String toString() {
231: return "GoalResult for: " + goal;
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: */
|