KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > reasoner > rulesys > impl > RETETerminal


1 /******************************************************************
2  * File: RETETerminal.java
3  * Created by: Dave Reynolds
4  * Created on: 09-Jun-2003
5  *
6  * (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
7  * [See end of file]
8  * $Id: RETETerminal.java,v 1.12 2005/02/21 12:17:59 andy_seaborne Exp $
9  *****************************************************************/

10 package com.hp.hpl.jena.reasoner.rulesys.impl;
11
12 import com.hp.hpl.jena.reasoner.rulesys.*;
13 import com.hp.hpl.jena.reasoner.*;
14 import com.hp.hpl.jena.graph.*;
15 import java.util.*;
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18
19 /**
20  * The final node in a RETE graph. It runs the builtin guard clauses
21  * and then, if the token passes, executes the head operations.
22  *
23  * @author <a HREF="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
24  * @version $Revision: 1.12 $ on $Date: 2005/02/21 12:17:59 $
25  */

26 public class RETETerminal implements RETESinkNode {
27
28     /** Context containing the specific rule and parent graph */
29     protected RETERuleContext context;
30     
31     protected static Log logger = LogFactory.getLog(FRuleEngine.class);
32     
33     /**
34      * Constructor.
35      * @param rule the rule which this terminal should fire.
36      * @param engine the parent rule engine through which the deductions and recursive network can be reached.
37      * @param graph the wider encompasing infGraph needed to for the RuleContext
38      */

39     public RETETerminal(Rule rule, RETEEngine engine, ForwardRuleInfGraphI graph) {
40         context = new RETERuleContext(graph, engine);
41         context.rule = rule;
42     }
43     
44     /**
45      * Constructor. Used internally for cloning.
46      * @param rule the rule which this terminal should fire.
47      * @param engine the parent rule engine through which the deductions and recursive network can be reached.
48      * @param graph the wider encompasing infGraph needed to for the RuleContext
49      */

50     private RETETerminal(RETERuleContext context) {
51         this.context = context;
52     }
53     
54     /**
55      * Change the engine/graph to which this terminal should deliver its results.
56      */

57     public void setContext(RETEEngine engine, ForwardRuleInfGraphI graph) {
58         Rule rule = context.getRule();
59         context = new RETERuleContext(graph, engine);
60         context.setRule(rule);
61     }
62     
63     /**
64      * Propagate a token to this node.
65      * @param env a set of variable bindings for the rule being processed.
66      * @param isAdd distinguishes between add and remove operations.
67      */

68     public void fire(BindingVector env, boolean isAdd) {
69         Rule rule = context.getRule();
70         context.setEnv(env);
71         
72         // Check any non-pattern clauses
73
for (int i = 0; i < rule.bodyLength(); i++) {
74             Object JavaDoc clause = rule.getBodyElement(i);
75             if (clause instanceof Functor) {
76                 // Fire a built in
77
if (isAdd) {
78                     if (!((Functor)clause).evalAsBodyClause(context)) {
79                         // Failed guard so just discard and return
80
return;
81                     }
82                 } else {
83                     // Don't re-run side-effectful clause on a re-run
84
if (!((Functor)clause).safeEvalAsBodyClause(context)) {
85                         // Failed guard so just discard and return
86
return;
87                     }
88                 }
89             }
90         }
91         
92         // Now fire the rule
93
ForwardRuleInfGraphI infGraph = (ForwardRuleInfGraphI)context.getGraph();
94         if (infGraph.shouldTrace()) {
95             logger.info("Fired rule: " + rule.toShortString());
96         }
97         RETEEngine engine = context.getEngine();
98         engine.incRuleCount();
99         List matchList = null;
100         if (infGraph.shouldLogDerivations() && isAdd) {
101             // Create derivation record
102
matchList = new ArrayList(rule.bodyLength());
103             for (int i = 0; i < rule.bodyLength(); i++) {
104                 Object JavaDoc clause = rule.getBodyElement(i);
105                 if (clause instanceof TriplePattern) {
106                     matchList.add(env.instantiate((TriplePattern)clause));
107                 }
108             }
109         }
110         for (int i = 0; i < rule.headLength(); i++) {
111             Object JavaDoc hClause = rule.getHeadElement(i);
112             if (hClause instanceof TriplePattern) {
113                 Triple t = env.instantiate((TriplePattern) hClause);
114                 if (!t.getSubject().isLiteral()) {
115                     // Only add the result if it is legal at the RDF level.
116
// E.g. RDFS rules can create assertions about literals
117
// that we can't record in RDF
118
if (isAdd) {
119                         if ( ! context.contains(t) ) {
120                             engine.addTriple(t, true);
121                             if (infGraph.shouldLogDerivations()) {
122                                 infGraph.logDerivation(t, new RuleDerivation(rule, t, matchList, infGraph));
123                             }
124                         }
125                     } else {
126                         if ( context.contains(t)) {
127                             // Remove the generated triple
128
engine.deleteTriple(t, true);
129                         }
130                     }
131                 }
132             } else if (hClause instanceof Functor && isAdd) {
133                 Functor f = (Functor)hClause;
134                 Builtin imp = f.getImplementor();
135                 if (imp != null) {
136                     imp.headAction(f.getBoundArgs(env), f.getArgLength(), context);
137                 } else {
138                     throw new ReasonerException("Invoking undefined Functor " + f.getName() +" in " + rule.toShortString());
139                 }
140             } else if (hClause instanceof Rule) {
141                 Rule r = (Rule)hClause;
142                 if (r.isBackward()) {
143                     if (isAdd) {
144                         infGraph.addBRule(r.instantiate(env));
145                     } else {
146                         infGraph.deleteBRule(r.instantiate(env));
147                     }
148                 } else {
149                     throw new ReasonerException("Found non-backward subrule : " + r);
150                 }
151             }
152         }
153     }
154     
155     /**
156      * Clone this node in the network.
157      * @param netCopy a map from RETENode to cloned instance
158      * @param context the new context to which the network is being ported
159      */

160     public RETENode clone(Map netCopy, RETERuleContext contextIn) {
161         RETETerminal clone = (RETETerminal)netCopy.get(this);
162         if (clone == null) {
163             RETERuleContext newContext = new RETERuleContext((ForwardRuleInfGraphI)contextIn.getGraph(), contextIn.getEngine());
164             newContext.setRule(context.getRule());
165             clone = new RETETerminal(newContext);
166             netCopy.put(this, clone);
167         }
168         return clone;
169     }
170     
171 }
172
173
174 /*
175     (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
176     All rights reserved.
177
178     Redistribution and use in source and binary forms, with or without
179     modification, are permitted provided that the following conditions
180     are met:
181
182     1. Redistributions of source code must retain the above copyright
183        notice, this list of conditions and the following disclaimer.
184
185     2. Redistributions in binary form must reproduce the above copyright
186        notice, this list of conditions and the following disclaimer in the
187        documentation and/or other materials provided with the distribution.
188
189     3. The name of the author may not be used to endorse or promote products
190        derived from this software without specific prior written permission.
191
192     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
193     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
194     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
195     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
196     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
197     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
198     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
199     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
200     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
201     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
202 */
Popular Tags