KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > reasoner > rulesys > test > TestRETE


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

10 package com.hp.hpl.jena.reasoner.rulesys.test;
11
12 import java.util.*;
13
14 import com.hp.hpl.jena.graph.*;
15 import com.hp.hpl.jena.mem.GraphMem;
16 import com.hp.hpl.jena.reasoner.*;
17 import com.hp.hpl.jena.reasoner.rulesys.*;
18 import com.hp.hpl.jena.reasoner.rulesys.impl.*;
19 import com.hp.hpl.jena.reasoner.test.TestUtil;
20
21 import junit.framework.TestCase;
22 import junit.framework.TestSuite;
23
24 /**
25  *
26  * @author <a HREF="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
27  * @version $Revision: 1.10 $ on $Date: 2005/02/21 12:18:14 $
28  */

29 public class TestRETE extends TestCase {
30      
31     // Useful constants
32
Node_RuleVariable x = new Node_RuleVariable("x", 0);
33     Node_RuleVariable y = new Node_RuleVariable("y", 1);
34     Node_RuleVariable z = new Node_RuleVariable("z", 2);
35     Node p = Node.createURI("p");
36     Node q = Node.createURI("q");
37     Node a = Node.createURI("a");
38     Node b = Node.createURI("b");
39     Node c = Node.createURI("c");
40     Node d = Node.createURI("d");
41     Node e = Node.createURI("e");
42     Node r = Node.createURI("r");
43     Node s = Node.createURI("s");
44     Node n1 = Node.createURI("n1");
45     Node n2 = Node.createURI("n2");
46     Node n3 = Node.createURI("n3");
47     Node n4 = Node.createURI("n4");
48     Node res = Node.createURI("res");
49          
50     /**
51      * Boilerplate for junit
52      */

53     public TestRETE( String JavaDoc name ) {
54         super( name );
55     }
56     
57     /**
58      * Boilerplate for junit.
59      * This is its own test suite
60      */

61     public static TestSuite suite() {
62         return new TestSuite( TestRETE.class );
63 // TestSuite suite = new TestSuite();
64
// suite.addTest(new TestRETE( "foo" ));
65
// return suite;
66
}
67
68     /**
69      * Test clause compiler and clause filter implementation.
70      */

71     public void testClauseFilter() {
72         doTestClauseFilter( new TriplePattern(a, p, x),
73                             new Triple(a, p, b), new Node[]{b, null, null});
74         doTestClauseFilter( new TriplePattern(x, p, b),
75                             new Triple(a, p, b), new Node[]{a, null, null});
76         doTestClauseFilter( new TriplePattern(a, p, x), new Triple(b, p, a), null);
77         doTestClauseFilter( new TriplePattern(a, p, x), new Triple(a, q, a), null);
78         doTestClauseFilter( new TriplePattern(x, p, x),
79                             new Triple(a, p, a), new Node[]{a, null, null});
80         doTestClauseFilter( new TriplePattern(x, p, x), new Triple(a, p, b), null);
81         doTestClauseFilter(
82             new TriplePattern(a, p, Functor.makeFunctorNode("f", new Node[]{x, c})),
83             new Triple(a, p, a),
84             null);
85         doTestClauseFilter(
86             new TriplePattern(a, p, x),
87             new Triple(a, p, Functor.makeFunctorNode("f", new Node[]{b, c})),
88             new Node[]{Functor.makeFunctorNode("f", new Node[]{b, c}), null, null});
89         doTestClauseFilter(
90             new TriplePattern(a, p, Functor.makeFunctorNode("g", new Node[]{x, c})),
91             new Triple(a, p, Functor.makeFunctorNode("f", new Node[]{b, c})),
92             null);
93         doTestClauseFilter(
94             new TriplePattern(a, p, Functor.makeFunctorNode("f", new Node[]{x, c})),
95             new Triple(a, p, Functor.makeFunctorNode("f", new Node[]{b, c})),
96             new Node[] {b, null, null});
97         doTestClauseFilter(
98             new TriplePattern(x, p, Functor.makeFunctorNode("f", new Node[]{x, c})),
99             new Triple(a, p, Functor.makeFunctorNode("f", new Node[]{a, c})),
100             new Node[] {a, null, null});
101         doTestClauseFilter(
102             new TriplePattern(x, p, Functor.makeFunctorNode("f", new Node[]{x, c})),
103             new Triple(a, p, Functor.makeFunctorNode("f", new Node[]{b, c})),
104             null);
105     }
106
107     /**
108      * Helper for testing clause filters.
109      */

110     private void doTestClauseFilter(TriplePattern pattern, Triple test, Node[] expected) {
111         RETETestNode tnode = new RETETestNode();
112         RETEClauseFilter cf = RETEClauseFilter.compile(pattern, 3, new LinkedList());
113         cf.setContinuation(tnode);
114         cf.fire(test, true);
115         if (expected == null) {
116             assertTrue(tnode.firings == 0);
117         } else {
118             assertTrue(tnode.firings == 1);
119             assertTrue(tnode.isAdd);
120             assertEquals(new BindingVector(expected), tnode.env);
121         }
122     }
123     
124     /**
125      * Inner class usable as a dummy RETENode end point for testing.
126      */

127     protected static class RETETestNode implements RETESinkNode {
128         /** The environment passed in */
129         BindingVector env;
130         
131         /** The mode flag */
132         boolean isAdd;
133         
134         /** True if the fire has been called */
135         int firings = 0;
136
137         /**
138          * Propagate a token to this node.
139          * @param env a set of variable bindings for the rule being processed.
140          * @param isAdd distinguishes between add and remove operations.
141          */

142         public void fire(BindingVector env, boolean isAdd) {
143             firings++;
144             this.env = env;
145             this.isAdd = isAdd;
146         }
147         
148         /**
149          * Clone this node in the network across to a different context.
150          * @param netCopy a map from RETENodes to cloned instance so far.
151          * @param context the new context to which the network is being ported
152          */

153         public RETENode clone(Map netCopy, RETERuleContext context) {
154             // Dummy, not used in testing
155
return this;
156         }
157         
158     }
159       
160     /**
161      * Minimal rule tester to check basic pattern match.
162      */

163     public void testRuleMatcher() {
164         doRuleTest( "[r1: (?a p ?b), (?b q ?c) -> (?a, q, ?c)]" +
165                        "[r2: (?a p ?b), (?b p ?c) -> (?a, p, ?c)]" +
166                        "[r3: (?a p ?a), (n1 p ?c), (n1, p, ?a) -> (?a, p, ?c)]" +
167                        "[r4: (n4 ?p ?a) -> (n4, ?a, ?p)]",
168                     new Triple[] {
169                         new Triple(n1, p, n2),
170                         new Triple(n2, p, n3),
171                         new Triple(n2, q, n3),
172                         new Triple(n4, p, n4) },
173                     new Triple[] {
174                         new Triple(n1, p, n2),
175                         new Triple(n2, p, n3),
176                         new Triple(n2, q, n3),
177                         new Triple(n4, p, n4),
178                         new Triple(n1, p, n3),
179                         new Triple(n1, q, n3),
180                         new Triple(n4, n4, p),
181                     });
182                     
183         doRuleTest( "[testRule1: (n1 p ?a) -> (n2, p, ?a)]" +
184                         "[testRule2: (n1 q ?a) -> (n2, q, ?a)]" +
185                         "[testRule3: (n2 p ?a), (n2 q ?a) -> (res p ?a)]" +
186                         "[axiom1: -> (n1 p n3)]",
187                      new Triple[] {},
188                      new Triple[] {
189                          new Triple(n1, p, n3),
190                          new Triple(n2, p, n3)
191                      });
192         
193         doRuleTest( "[testRule1: (n1 p ?a) -> (n2, p, ?a)]" +
194                         "[testRule2: (n1 q ?a) -> (n2, q, ?a)]" +
195                         "[testRule3: (n2 p ?a), (n2 q ?a) -> (res p ?a)]" +
196                         "[axiom1: -> (n1 p n3)]",
197                      new Triple[] {
198                          new Triple(n1, q, n4),
199                          new Triple(n1, q, n3)
200                      },
201                      new Triple[] {
202                          new Triple(n1, p, n3),
203                          new Triple(n2, p, n3),
204                          new Triple(n1, q, n4),
205                          new Triple(n2, q, n4),
206                          new Triple(n1, q, n3),
207                          new Triple(n2, q, n3),
208                          new Triple(res, p, n3)
209                      });
210         doRuleTest( "[rule1: (?x p ?y), (?x q ?y) -> remove(0)]",
211                      new Triple[] {
212                          new Triple(n1, p, Util.makeIntNode(1)),
213                          new Triple(n1, p, Util.makeIntNode(2)),
214                          new Triple(n1, q, Util.makeIntNode(2))
215                      },
216                      new Triple[] {
217                          new Triple(n1, p, Util.makeIntNode(1)),
218                          new Triple(n1, q, Util.makeIntNode(2))
219                      });
220     }
221
222     /**
223      * Perform a rule test on the raw RETE engine. This requires some fiddling
224      * with dummy parent graphs.
225      */

226     private void doRuleTest(String JavaDoc rules, Triple[] adds, Triple[] expected) {
227         List ruleList = Rule.parseRules(rules);
228         BasicForwardRuleInfGraph infgraph = new BasicForwardRuleInfGraph(null, new ArrayList(), null, new GraphMem());
229 // infgraph.setTraceOn(true);
230
RETEEngine engine = new RETEEngine(infgraph, ruleList);
231         infgraph.prepare();
232         engine.init(true, new FGraph(new GraphMem()));
233         for (int i = 0; i < adds.length; i++) {
234             engine.addTriple(adds[i], true);
235         }
236         engine.runAll();
237         TestUtil.assertIteratorValues(this, infgraph.find(null, null, null), expected);
238     }
239     
240     /**
241      * Check that the rulestate cloning keeps two descendent graphs independent.
242      *
243      */

244     public void testRuleClone() {
245         String JavaDoc rules = "[testRule1: (a p ?x) (b p ?x) -> (n1 p ?x) ]" +
246                        "[testRule2: (?x q ?y) -> (?x p ?y)]";
247         List ruleList = Rule.parseRules(rules);
248         Graph schema = new GraphMem();
249         schema.add(new Triple(a, q, c));
250         schema.add(new Triple(a, q, d));
251
252         Graph data1 = new GraphMem();
253         data1.add(new Triple(b, q, c));
254         
255         Graph data2 = new GraphMem();
256         data2.add(new Triple(b, q, d));
257         
258         GenericRuleReasoner reasoner = new GenericRuleReasoner(ruleList);
259         reasoner.setMode(GenericRuleReasoner.FORWARD_RETE);
260         Reasoner boundReasoner = reasoner.bindSchema(schema);
261         InfGraph infgraph1 = boundReasoner.bind(data1);
262         InfGraph infgraph2 = boundReasoner.bind(data2);
263
264         TestUtil.assertIteratorValues(this, infgraph1.find(null, p, null),
265             new Triple[] {
266                 new Triple(a, p, c),
267                 new Triple(a, p, d),
268                 new Triple(b, p, c),
269                 new Triple(n1, p, c)
270             });
271
272         TestUtil.assertIteratorValues(this, infgraph2.find(null, p, null),
273             new Triple[] {
274                 new Triple(a, p, c),
275                 new Triple(a, p, d),
276                 new Triple(b, p, d),
277                 new Triple(n1, p, d)
278             });
279     }
280 }
281
282
283 /*
284     (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
285     All rights reserved.
286
287     Redistribution and use in source and binary forms, with or without
288     modification, are permitted provided that the following conditions
289     are met:
290
291     1. Redistributions of source code must retain the above copyright
292        notice, this list of conditions and the following disclaimer.
293
294     2. Redistributions in binary form must reproduce the above copyright
295        notice, this list of conditions and the following disclaimer in the
296        documentation and/or other materials provided with the distribution.
297
298     3. The name of the author may not be used to endorse or promote products
299        derived from this software without specific prior written permission.
300
301     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
302     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
303     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
304     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
305     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
306     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
307     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
308     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
309     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
310     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
311 */
Popular Tags