001: /******************************************************************
002: * File: RuleStore.java
003: * Created by: Dave Reynolds
004: * Created on: 04-May-2003
005: *
006: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
007: * [See end of file]
008: * $Id: RuleStore.java,v 1.18 2008/01/02 12:06:15 andy_seaborne Exp $
009: *****************************************************************/package com.hp.hpl.jena.reasoner.rulesys.impl;
010:
011: import java.util.*;
012:
013: import com.hp.hpl.jena.graph.*;
014: import com.hp.hpl.jena.reasoner.*;
015: import com.hp.hpl.jena.reasoner.rulesys.*;
016: import com.hp.hpl.jena.util.OneToManyMap;
017:
018: /**
019: * Indexes a collection of rule. The currently implementation is
020: * a crude first version aimed at supporting the backchaining
021: * interpreter. It only indexes on predicate.
022: * <p>
023: * The rules are normalized to only contain a single head element
024: * by duplicating any multi headed rules.
025: * </p>
026: *
027: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
028: * @version $Revision: 1.18 $ on $Date: 2008/01/02 12:06:15 $
029: */
030: public class RuleStore {
031:
032: /** The set of rules indexed by head predicate */
033: protected OneToManyMap goalMap = new OneToManyMap();
034:
035: /** The list of all rules in the store */
036: protected List allRules;
037:
038: /** Index of the rules, used to block multiple entries */
039: protected Set ruleIndex = new HashSet();
040:
041: /**
042: * Constructor. Create an empty rule store.
043: */
044: public RuleStore() {
045: allRules = new ArrayList();
046: };
047:
048: /**
049: * Constructor. Stores and indexes a list of rules.
050: */
051: public RuleStore(List rules) {
052: for (Iterator i = rules.iterator(); i.hasNext();) {
053: addRule((Rule) i.next());
054: }
055: allRules = rules;
056: }
057:
058: /**
059: * Add all the rules and from an existing rulestore into this one.
060: */
061: public void addAll(RuleStore store) {
062: for (Iterator i = store.getAllRules().iterator(); i.hasNext();) {
063: addRule((Rule) i.next());
064: }
065: }
066:
067: /**
068: * Add a single rule to the store.
069: */
070: public void addRule(Rule rule) {
071: addRemoveRule(rule, true);
072: }
073:
074: /**
075: * Remove a single rule from the store
076: */
077: public void deleteRule(Rule rule) {
078: addRemoveRule(rule, false);
079: }
080:
081: /**
082: * Add a single/remove a compound rule from the store.
083: * @param rule the rule, may have multiple heads
084: * @param isAdd true to add, false to remove
085: */
086: private void addRemoveRule(Rule rule, boolean isAdd) {
087: if (rule.headLength() != 1) {
088: for (int j = 0; j < rule.headLength(); j++) {
089: Rule newRule = new Rule(rule.getName(),
090: new ClauseEntry[] { rule.getHeadElement(j) },
091: rule.getBody());
092: newRule.setNumVars(rule.getNumVars());
093: doAddRemoveRule(newRule, isAdd);
094: }
095:
096: } else {
097: doAddRemoveRule(rule, isAdd);
098: }
099: }
100:
101: /**
102: * Add/remove a single rule from the store.
103: * @param rule the rule, single headed only
104: * @param isAdd true to add, false to remove
105: */
106: protected void doAddRemoveRule(Rule rule, boolean isAdd) {
107: if (isAdd && ruleIndex.contains(rule))
108: return;
109: if (isAdd) {
110: ruleIndex.add(rule);
111: if (allRules != null)
112: allRules.add(rule);
113: } else {
114: ruleIndex.remove(rule);
115: if (allRules != null)
116: allRules.remove(rule);
117: }
118: Object headClause = rule.getHeadElement(0);
119: if (headClause instanceof TriplePattern) {
120: TriplePattern headpattern = (TriplePattern) headClause;
121: Node predicate = headpattern.getPredicate();
122: if (predicate.isVariable()) {
123: if (isAdd) {
124: goalMap.put(Node.ANY, rule);
125: } else {
126: goalMap.remove(Node.ANY, rule);
127: }
128: } else {
129: if (isAdd) {
130: goalMap.put(predicate, rule);
131: } else {
132: goalMap.remove(predicate, rule);
133: }
134: }
135: }
136: }
137:
138: /**
139: * Return a list of rules that match the given goal pattern
140: * @param goal the goal being matched
141: */
142: public List rulesFor(TriplePattern goal) {
143: List rules = new ArrayList();
144: if (goal.getPredicate().isVariable()) {
145: checkAll(goalMap.values().iterator(), goal, rules);
146: } else {
147: checkAll(goalMap.getAll(goal.getPredicate()), goal, rules);
148: checkAll(goalMap.getAll(Node.ANY), goal, rules);
149: }
150: return rules;
151: }
152:
153: /**
154: * Return an ordered list of all registered rules.
155: */
156: public List getAllRules() {
157: return allRules;
158: }
159:
160: /**
161: * Delete all the rules.
162: */
163: public void deleteAllRules() {
164: allRules.clear();
165: goalMap.clear();
166: ruleIndex.clear();
167: }
168:
169: /**
170: * Helper method to extract all matching clauses from an
171: * iterator over rules
172: */
173: private void checkAll(Iterator candidates, TriplePattern goal,
174: List matchingRules) {
175: while (candidates.hasNext()) {
176: Rule r = (Rule) candidates.next();
177: if (((TriplePattern) r.getHeadElement(0))
178: .compatibleWith(goal)) {
179: matchingRules.add(r);
180: }
181: }
182: }
183:
184: }
185:
186: /*
187: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
188: All rights reserved.
189:
190: Redistribution and use in source and binary forms, with or without
191: modification, are permitted provided that the following conditions
192: are met:
193:
194: 1. Redistributions of source code must retain the above copyright
195: notice, this list of conditions and the following disclaimer.
196:
197: 2. Redistributions in binary form must reproduce the above copyright
198: notice, this list of conditions and the following disclaimer in the
199: documentation and/or other materials provided with the distribution.
200:
201: 3. The name of the author may not be used to endorse or promote products
202: derived from this software without specific prior written permission.
203:
204: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
205: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
206: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
207: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
208: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
209: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
210: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
211: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
212: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
213: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
214: */
|