001: /******************************************************************
002: * File: TestBackchainer.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: TestBackchainer.java,v 1.38 2008/01/02 12:08:19 andy_seaborne Exp $
009: *****************************************************************/package com.hp.hpl.jena.reasoner.rulesys.test;
010:
011: import com.hp.hpl.jena.graph.*;
012: import com.hp.hpl.jena.reasoner.*;
013: import com.hp.hpl.jena.reasoner.rulesys.*;
014: import com.hp.hpl.jena.reasoner.rulesys.impl.*;
015: import com.hp.hpl.jena.reasoner.test.TestUtil;
016: import com.hp.hpl.jena.util.iterator.ExtendedIterator;
017: import com.hp.hpl.jena.vocabulary.OWL;
018: import com.hp.hpl.jena.vocabulary.RDFS;
019: import com.hp.hpl.jena.vocabulary.RDF;
020:
021: import java.io.IOException;
022: import java.util.*;
023:
024: import junit.framework.TestCase;
025: import junit.framework.TestSuite;
026:
027: /**
028: * Test harness for the backward chainer.
029: * Parameterizable in subclasses by overriding createReasoner.
030: * The original version was developed for the original backchaining interpeter.
031: * That has now been obsoleted at this is now used to double check the
032: * LP engine, though the bulk of such tests are really done by TestBasicLP.
033: *
034: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
035: * @version $Revision: 1.38 $ on $Date: 2008/01/02 12:08:19 $
036: */
037: public class TestBackchainer extends TestCase {
038:
039: // Maximum size of binding environment needed in the tests
040: private static final int MAX_VARS = 10;
041:
042: // Useful constants
043: protected Node p = Node.createURI("p");
044: protected Node q = Node.createURI("q");
045: protected Node r = Node.createURI("r");
046: protected Node s = Node.createURI("s");
047: protected Node t = Node.createURI("t");
048: protected Node a = Node.createURI("a");
049: protected Node b = Node.createURI("b");
050: protected Node c = Node.createURI("c");
051: protected Node d = Node.createURI("d");
052: protected Node C1 = Node.createURI("C1");
053: protected Node C2 = Node.createURI("C2");
054: protected Node C3 = Node.createURI("C3");
055: protected Node sP = RDFS.Nodes.subPropertyOf;
056: protected Node sC = RDFS.Nodes.subClassOf;
057: protected Node ty = RDF.Nodes.type;
058:
059: String testRules1 = "(?x ?q ?y) <- (?p rdfs:subPropertyOf ?q)(?x ?p ?y). "
060: + "(?a rdfs:subPropertyOf ?c) <- (?a rdfs:subPropertyOf ?b)(?b rdfs:subPropertyOf ?c). ";
061:
062: String testRuleAxioms = "[ -> (p rdfs:subPropertyOf q)]"
063: + "[ -> (q rdfs:subPropertyOf r) ]" + "[ -> (a p b) ]";
064:
065: Triple[] dataElts = new Triple[] { new Triple(p, sP, q),
066: new Triple(q, sP, r), new Triple(a, p, b) };
067:
068: /**
069: * Boilerplate for junit
070: */
071: public TestBackchainer(String name) {
072: super (name);
073: }
074:
075: /**
076: * Boilerplate for junit.
077: * This is its own test suite
078: */
079: public static TestSuite suite() {
080: return new TestSuite(TestBackchainer.class);
081: // TestSuite suite = new TestSuite();
082: // suite.addTest(new TestBackchainer( "testRDFSProblemsb" ));
083: // return suite;
084: }
085:
086: /**
087: * Override in subclasses to test other reasoners.
088: */
089: public Reasoner createReasoner(List rules) {
090: LPBackwardRuleReasoner reasoner = new LPBackwardRuleReasoner(
091: rules);
092: reasoner.tablePredicate(sP);
093: reasoner.tablePredicate(sC);
094: reasoner.tablePredicate(ty);
095: reasoner.tablePredicate(p);
096: reasoner.tablePredicate(a);
097: reasoner.tablePredicate(b);
098: return reasoner;
099: }
100:
101: /**
102: * Test parser modes to support backarrow notation are working
103: */
104: public void testParse() {
105: List rules = Rule.parseRules(testRules1);
106: assertEquals(
107: "BRule parsing",
108: "[ (?x ?q ?y) <- (?p rdfs:subPropertyOf ?q) (?x ?p ?y) ]",
109: rules.get(0).toString());
110: assertEquals(
111: "BRule parsing",
112: "[ (?a rdfs:subPropertyOf ?c) <- (?a rdfs:subPropertyOf ?b) (?b rdfs:subPropertyOf ?c) ]",
113: rules.get(1).toString());
114: }
115:
116: /**
117: * Test goal/head unify operation.
118: */
119: public void testUnify() {
120: Node_RuleVariable xg = new Node_RuleVariable("?x", 0);
121: Node_RuleVariable yg = new Node_RuleVariable("?y", 1);
122: Node_RuleVariable zg = new Node_RuleVariable("?z", 2);
123:
124: Node_RuleVariable xh = new Node_RuleVariable("?x", 0);
125: Node_RuleVariable yh = new Node_RuleVariable("?y", 1);
126: Node_RuleVariable zh = new Node_RuleVariable("?z", 2);
127:
128: TriplePattern g1 = new TriplePattern(xg, p, yg);
129: TriplePattern g2 = new TriplePattern(xg, p, xg);
130: TriplePattern g3 = new TriplePattern(a, p, xg);
131: TriplePattern g4 = new TriplePattern(a, p, b);
132:
133: TriplePattern h1 = new TriplePattern(xh, p, yh);
134: TriplePattern h2 = new TriplePattern(xh, p, xh);
135: TriplePattern h3 = new TriplePattern(a, p, xh);
136: TriplePattern h4 = new TriplePattern(a, p, b);
137: TriplePattern h5 = new TriplePattern(xh, p, a);
138:
139: doTestUnify(g1, h1, true, new Node[] { null, null });
140: doTestUnify(g1, h2, true, new Node[] { null, null });
141: doTestUnify(g1, h3, true, new Node[] { null, null });
142: doTestUnify(g1, h4, true, new Node[] { null, null });
143: doTestUnify(g1, h5, true, new Node[] { null, null });
144:
145: doTestUnify(g2, h1, true, new Node[] { null, xh });
146: doTestUnify(g2, h2, true, new Node[] { null, null });
147: doTestUnify(g2, h3, true, new Node[] { a, null });
148: doTestUnify(g2, h4, false, null);
149: doTestUnify(g2, h5, true, new Node[] { a, null });
150:
151: doTestUnify(g3, h1, true, new Node[] { a, null });
152: doTestUnify(g3, h2, true, new Node[] { a, null });
153: doTestUnify(g3, h3, true, new Node[] { null, null });
154: doTestUnify(g3, h4, true, new Node[] { null, null });
155: doTestUnify(g3, h5, true, new Node[] { a, null });
156:
157: doTestUnify(g4, h1, true, new Node[] { a, b });
158: doTestUnify(g4, h2, false, null);
159: doTestUnify(g4, h3, true, new Node[] { b });
160: doTestUnify(g4, h4, true, null);
161: doTestUnify(g4, h5, false, null);
162:
163: // Recursive case
164: doTestUnify(h1, h1, true, new Node[] { null, null });
165:
166: // Wildcard case
167: doTestUnify(new TriplePattern(null, null, null), h2, true,
168: new Node[] { null, null });
169:
170: // Test functor cases as well!
171: TriplePattern gf = new TriplePattern(xg, p, Functor
172: .makeFunctorNode("f", new Node[] { xg, b }));
173: TriplePattern hf1 = new TriplePattern(yh, p, Functor
174: .makeFunctorNode("f", new Node[] { zh, b }));
175: TriplePattern hf2 = new TriplePattern(yh, p, Functor
176: .makeFunctorNode("f", new Node[] { a, yh }));
177: TriplePattern hf3 = new TriplePattern(yh, p, Functor
178: .makeFunctorNode("f", new Node[] { b, yh }));
179: doTestUnify(gf, hf1, true, new Node[] { null, null, yh });
180: doTestUnify(gf, hf2, false, null);
181: doTestUnify(gf, hf3, true, new Node[] { null, b });
182:
183: // Check binding environment use
184: BindingVector env = BindingVector.unify(g2, h1, MAX_VARS);
185: env.bind(xh, c);
186: assertEquals(env.getBinding(yh), c);
187: env = BindingVector.unify(g2, h1, MAX_VARS);
188: env.bind(yh, c);
189: assertEquals(env.getBinding(xh), c);
190: }
191:
192: /**
193: * Helper for testUnify.
194: * @param goal goal triple pattern
195: * @param head head triple pattern
196: * @param succeed whether match should succeeed or fail
197: * @param env list list of expected environment bindings
198: *
199: */
200: private void doTestUnify(TriplePattern goal, TriplePattern head,
201: boolean succeed, Node[] env) {
202: BindingVector result = BindingVector
203: .unify(goal, head, MAX_VARS);
204: if (succeed) {
205: assertNotNull(result);
206: if (env != null) {
207: for (int i = 0; i < env.length; i++) {
208: Node n = result.getEnvironment()[i];
209: if (env[i] != null) {
210: assertEquals(env[i], n);
211: } else {
212: assertNull(n);
213: }
214: }
215: }
216: } else {
217: assertNull(result);
218: }
219: }
220:
221: /**
222: * Check that a reasoner over an empty rule set accesses
223: * the raw data successfully.
224: */
225: public void testListData() {
226: Graph data = Factory.createGraphMem();
227: for (int i = 0; i < dataElts.length; i++) {
228: data.add(dataElts[i]);
229: }
230: Graph schema = Factory.createGraphMem();
231: schema.add(new Triple(c, p, c));
232:
233: // Case of schema and data but no rule axioms
234: Reasoner reasoner = createReasoner(new ArrayList());
235: InfGraph infgraph = reasoner.bindSchema(schema).bind(data);
236: TestUtil.assertIteratorValues(this , infgraph.find(null, null,
237: null), new Object[] { new Triple(p, sP, q),
238: new Triple(q, sP, r), new Triple(a, p, b),
239: new Triple(c, p, c) });
240:
241: // Case of data and rule axioms but no schema
242: List rules = Rule.parseRules("-> (d p d).");
243: reasoner = createReasoner(rules);
244: infgraph = reasoner.bind(data);
245: TestUtil.assertIteratorValues(this , infgraph.find(null, null,
246: null), new Object[] { new Triple(p, sP, q),
247: new Triple(q, sP, r), new Triple(a, p, b),
248: new Triple(d, p, d) });
249:
250: // Case of data and rule axioms and schema
251: infgraph = reasoner.bindSchema(schema).bind(data);
252: TestUtil.assertIteratorValues(this , infgraph.find(null, null,
253: null), new Object[] { new Triple(p, sP, q),
254: new Triple(q, sP, r), new Triple(a, p, b),
255: new Triple(c, p, c), new Triple(d, p, d) });
256:
257: }
258:
259: /**
260: * Test basic rule operations - simple AND rule
261: */
262: public void testBaseRules1() {
263: List rules = Rule
264: .parseRules("[r1: (?a r ?c) <- (?a p ?b),(?b p ?c)]");
265: Graph data = Factory.createGraphMem();
266: data.add(new Triple(a, p, b));
267: data.add(new Triple(b, p, c));
268: data.add(new Triple(b, p, d));
269: Reasoner reasoner = createReasoner(rules);
270: InfGraph infgraph = reasoner.bind(data);
271: TestUtil.assertIteratorValues(this , infgraph
272: .find(null, r, null), new Object[] {
273: new Triple(a, r, c), new Triple(a, r, d) });
274: }
275:
276: /**
277: * Test basic rule operations - simple OR rule
278: */
279: public void testBaseRules2() {
280: List rules = Rule.parseRules("[r1: (?a r ?b) <- (?a p ?b)]"
281: + "[r2: (?a r ?b) <- (?a q ?b)]"
282: + "[r3: (?a r ?b) <- (?a s ?c), (?c s ?b)]");
283: Graph data = Factory.createGraphMem();
284: data.add(new Triple(a, p, b));
285: data.add(new Triple(b, q, c));
286: data.add(new Triple(a, s, b));
287: data.add(new Triple(b, s, d));
288: Reasoner reasoner = createReasoner(rules);
289: InfGraph infgraph = reasoner.bind(data);
290: TestUtil.assertIteratorValues(this , infgraph
291: .find(null, r, null), new Object[] {
292: new Triple(a, r, b), new Triple(b, r, c),
293: new Triple(a, r, d) });
294: }
295:
296: /**
297: * Test basic rule operations - simple OR rule with chaining
298: */
299: public void testBaseRules2b() {
300: List rules = Rule.parseRules("[r1: (?a r ?b) <- (?a p ?b)]"
301: + "[r2: (?a r ?b) <- (?a q ?b)]"
302: + "[r3: (?a r ?b) <- (?a t ?c), (?c t ?b)]"
303: + "[r4: (?a t ?b) <- (?a s ?b)]");
304: Graph data = Factory.createGraphMem();
305: data.add(new Triple(a, p, b));
306: data.add(new Triple(b, q, c));
307: data.add(new Triple(a, s, b));
308: data.add(new Triple(b, s, d));
309: Reasoner reasoner = createReasoner(rules);
310: InfGraph infgraph = reasoner.bind(data);
311: TestUtil.assertIteratorValues(this , infgraph
312: .find(null, r, null), new Object[] {
313: new Triple(a, r, b), new Triple(b, r, c),
314: new Triple(a, r, d) });
315: }
316:
317: /**
318: * Test basic rule operations - simple AND rule check with tabling.
319: */
320: public void testBaseRules3() {
321: List rules = Rule
322: .parseRules("[rule: (?a rdfs:subPropertyOf ?c) <- (?a rdfs:subPropertyOf ?b),(?b rdfs:subPropertyOf ?c)]");
323: Reasoner reasoner = createReasoner(rules);
324: Graph data = Factory.createGraphMem();
325: data.add(new Triple(p, sP, q));
326: data.add(new Triple(q, sP, r));
327: data.add(new Triple(p, sP, s));
328: data.add(new Triple(s, sP, t));
329: data.add(new Triple(a, p, b));
330: InfGraph infgraph = reasoner.bind(data);
331: TestUtil.assertIteratorValues(this , infgraph.find(null,
332: RDFS.subPropertyOf.asNode(), null), new Object[] {
333: new Triple(p, sP, q), new Triple(q, sP, r),
334: new Triple(p, sP, s), new Triple(s, sP, t),
335: new Triple(p, sP, t), new Triple(p, sP, r) });
336: }
337:
338: /**
339: * Test basic rule operations - simple AND rule check with tabling.
340: */
341: public void testBaseRules3b() {
342: List rules = Rule
343: .parseRules("[rule: (?a rdfs:subPropertyOf ?c) <- (?a rdfs:subPropertyOf ?b),(?b rdfs:subPropertyOf ?c)]");
344: Reasoner reasoner = createReasoner(rules);
345: Graph data = Factory.createGraphMem();
346: data.add(new Triple(p, sP, q));
347: data.add(new Triple(q, sP, r));
348: data.add(new Triple(r, sP, t));
349: data.add(new Triple(q, sP, s));
350: InfGraph infgraph = reasoner.bind(data);
351: TestUtil.assertIteratorValues(this , infgraph.find(null,
352: RDFS.subPropertyOf.asNode(), null), new Object[] {
353: new Triple(p, sP, q), new Triple(q, sP, r),
354: new Triple(r, sP, t), new Triple(q, sP, s),
355: new Triple(p, sP, s), new Triple(p, sP, r),
356: new Triple(p, sP, t), new Triple(q, sP, t),
357: new Triple(p, sP, r) });
358: }
359:
360: /**
361: * Test basic rule operations - simple AND/OR with tabling.
362: */
363: public void testBaseRules4() {
364: Graph data = Factory.createGraphMem();
365: data.add(new Triple(a, r, b));
366: data.add(new Triple(b, r, c));
367: data.add(new Triple(b, r, b));
368: data.add(new Triple(b, r, d));
369: List rules = Rule.parseRules("[r1: (?x p ?y) <- (?x r ?y)]"
370: + "[r2: (?x p ?z) <- (?x p ?y), (?y r ?z)]");
371: Reasoner reasoner = createReasoner(rules);
372: InfGraph infgraph = reasoner.bind(data);
373: TestUtil.assertIteratorValues(this , infgraph.find(a, p, null),
374: new Object[] { new Triple(a, p, b),
375: new Triple(a, p, d), new Triple(a, p, c) });
376: }
377:
378: /**
379: * Test basic rule operations - simple AND/OR with tabling.
380: */
381: public void testBaseRulesXSB1() {
382: Graph data = Factory.createGraphMem();
383: data.add(new Triple(p, c, q));
384: data.add(new Triple(q, c, r));
385: data.add(new Triple(p, d, q));
386: data.add(new Triple(q, d, r));
387: List rules = Rule.parseRules("[r1: (?x a ?y) <- (?x c ?y)]"
388: + "[r2: (?x a ?y) <- (?x b ?z), (?z c ?y)]"
389: + "[r3: (?x b ?y) <- (?x d ?y)]"
390: + "[r4: (?x b ?y) <- (?x a ?z), (?z d ?y)]");
391: Reasoner reasoner = createReasoner(rules);
392: InfGraph infgraph = reasoner.bind(data);
393: TestUtil
394: .assertIteratorValues(this , infgraph.find(p, a, null),
395: new Object[] { new Triple(p, a, q),
396: new Triple(p, a, r) });
397: }
398:
399: /**
400: * Test basic functor usage.
401: */
402: public void testFunctors1() {
403: Graph data = Factory.createGraphMem();
404: data.add(new Triple(a, p, b));
405: data.add(new Triple(a, q, c));
406: List rules = Rule
407: .parseRules("[r1: (?x r f(?y,?z)) <- (?x p ?y), (?x q ?z)]"
408: + "[r2: (?x s ?y) <- (?x r f(?y, ?z))]");
409: Reasoner reasoner = createReasoner(rules);
410: InfGraph infgraph = reasoner.bind(data);
411: TestUtil.assertIteratorValues(this , infgraph.find(a, s, null),
412: new Object[] { new Triple(a, s, b) });
413: }
414:
415: /**
416: * Test basic functor usage.
417: */
418: public void testFunctors2() {
419: Graph data = Factory.createGraphMem();
420: data.add(new Triple(a, p, b));
421: data.add(new Triple(a, q, c));
422: data.add(new Triple(a, t, d));
423: List rules = Rule
424: .parseRules("[r1: (?x r f(?y,?z)) <- (?x p ?y), (?x q ?z)]"
425: + "[r2: (?x s ?y) <- (?x r f(?y, ?z))]"
426: + "[r3: (?x r g(?y,?z)) <- (?x p ?y), (?x t ?z)]"
427: + "[r4: (?x s ?z) <- (?x r g(?y, ?z))]");
428: Reasoner reasoner = createReasoner(rules);
429: InfGraph infgraph = reasoner.bind(data);
430: TestUtil
431: .assertIteratorValues(this , infgraph.find(a, s, null),
432: new Object[] { new Triple(a, s, b),
433: new Triple(a, s, d) });
434: }
435:
436: /**
437: * Test basic functor usage.
438: */
439: public void testFunctors3() {
440: Graph data = Factory.createGraphMem();
441: data.add(new Triple(a, s, b));
442: data.add(new Triple(a, t, c));
443: List rules = Rule
444: .parseRules("[r1: (a q f(?x,?y)) <- (a s ?x), (a t ?y)]"
445: + "[r2: (a p ?x) <- (a q ?x)]"
446: + "[r3: (a r ?y) <- (a p f(?x, ?y))]");
447: Reasoner reasoner = createReasoner(rules);
448: InfGraph infgraph = reasoner.bind(data);
449: TestUtil.assertIteratorValues(this , infgraph.find(a, r, null),
450: new Object[] { new Triple(a, r, c) });
451: }
452:
453: /**
454: * Test basic builtin usage.
455: */
456: public void testBuiltin1() {
457: Graph data = Factory.createGraphMem();
458: List rules = Rule
459: .parseRules("[a1: -> (a p 2) ]"
460: + "[a2: -> (a q 3) ]"
461: + "[r1: (?x r ?s) <- (?x p ?y), (?x q ?z), sum(?y, ?z, ?s)]");
462: Reasoner reasoner = createReasoner(rules);
463: InfGraph infgraph = reasoner.bind(data);
464: TestUtil.assertIteratorValues(this , infgraph.find(a, r, null),
465: new Object[] { new Triple(a, r, Util.makeIntNode(5)) });
466: }
467:
468: /**
469: * Test basic builtin usage.
470: */
471: public void testBuiltin2() {
472: Graph data = Factory.createGraphMem();
473: data.add(new Triple(a, p, b));
474: data.add(new Triple(a, q, c));
475: List rules = Rule
476: .parseRules("[r1: (?x r ?y ) <- bound(?x), (?x p ?y) ]"
477: + "[r2: (?x r ?y) <- unbound(?x), (?x q ?y)]");
478: Reasoner reasoner = createReasoner(rules);
479: InfGraph infgraph = reasoner.bind(data);
480: TestUtil.assertIteratorValues(this , infgraph.find(a, r, null),
481: new Object[] { new Triple(a, r, b) });
482: TestUtil.assertIteratorValues(this , infgraph
483: .find(null, r, null),
484: new Object[] { new Triple(a, r, c) });
485: }
486:
487: /**
488: * Test basic builtin usage.
489: */
490: public void testBuiltin3() {
491: Graph data = Factory.createGraphMem();
492: List rules = Rule.parseRules("[r1: (a p b ) <- unbound(?x) ]");
493: Reasoner reasoner = createReasoner(rules);
494: InfGraph infgraph = reasoner.bind(data);
495: TestUtil.assertIteratorValues(this , infgraph
496: .find(a, null, null),
497: new Object[] { new Triple(a, p, b) });
498: }
499:
500: /**
501: * Test basic ground head patterns.
502: */
503: public void testGroundHead() {
504: Graph data = Factory.createGraphMem();
505: data.add(new Triple(a, r, b));
506: List rules = Rule.parseRules("[r1: (a p b ) <- (a r b) ]");
507: Reasoner reasoner = createReasoner(rules);
508: InfGraph infgraph = reasoner.bind(data);
509: TestUtil.assertIteratorValues(this , infgraph
510: .find(a, null, null), new Object[] {
511: new Triple(a, p, b), new Triple(a, r, b) });
512: }
513:
514: // /**
515: // * Test multiheaded rule.
516: // */
517: // public void testMutliHead() {
518: // Graph data = new GraphMem();
519: // data.add(new Triple(a, p, b));
520: // data.add(new Triple(b, r, c));
521: // List rules = Rule.parseRules(
522: // "[r1: (?x s ?z), (?z s ?x) <- (?x p ?y) (?y r ?z) ]"
523: // );
524: // Reasoner reasoner = createReasoner(rules);
525: // InfGraph infgraph = reasoner.bind(data);
526: // TestUtil.assertIteratorValues(this,
527: // infgraph.find(null, s, null),
528: // new Object[] {
529: // new Triple(a, s, c),
530: // new Triple(c, s, a)
531: // } );
532: // }
533:
534: /**
535: * Test rebind operation
536: */
537: public void testRebind() {
538: List rules = Rule
539: .parseRules("[r1: (?a r ?c) <- (?a p ?b),(?b p ?c)]");
540: Graph data = Factory.createGraphMem();
541: data.add(new Triple(a, p, b));
542: data.add(new Triple(b, p, c));
543: data.add(new Triple(b, p, d));
544: Reasoner reasoner = createReasoner(rules);
545: InfGraph infgraph = reasoner.bind(data);
546: TestUtil.assertIteratorValues(this , infgraph
547: .find(null, r, null), new Object[] {
548: new Triple(a, r, c), new Triple(a, r, d) });
549: Graph ndata = Factory.createGraphMem();
550: ndata.add(new Triple(a, p, d));
551: ndata.add(new Triple(d, p, b));
552: infgraph.rebind(ndata);
553: TestUtil.assertIteratorValues(this , infgraph
554: .find(null, r, null),
555: new Object[] { new Triple(a, r, b) });
556:
557: }
558:
559: /**
560: * Test troublesome rdfs rules
561: */
562: public void testRDFSProblemsb() {
563: Graph data = Factory.createGraphMem();
564: data.add(new Triple(C1, sC, C2));
565: data.add(new Triple(C2, sC, C3));
566: data.add(new Triple(C1, ty, RDFS.Class.asNode()));
567: data.add(new Triple(C2, ty, RDFS.Class.asNode()));
568: data.add(new Triple(C3, ty, RDFS.Class.asNode()));
569: List rules = Rule
570: .parseRules("[rdfs8: (?a rdfs:subClassOf ?b), (?b rdfs:subClassOf ?c) -> (?a rdfs:subClassOf ?c)]"
571: + "[rdfs7: (?a rdf:type rdfs:Class) -> (?a rdfs:subClassOf ?a)]");
572: Reasoner reasoner = createReasoner(rules);
573: InfGraph infgraph = reasoner.bind(data);
574: TestUtil.assertIteratorValues(this , infgraph.find(null, sC,
575: null), new Object[] { new Triple(C1, sC, C2),
576: new Triple(C1, sC, C3), new Triple(C1, sC, C1),
577: new Triple(C2, sC, C3), new Triple(C2, sC, C2),
578: new Triple(C3, sC, C3), });
579: }
580:
581: /**
582: * Test troublesome rdfs rules
583: */
584: public void testRDFSProblems() {
585: Graph data = Factory.createGraphMem();
586: data.add(new Triple(p, sP, q));
587: data.add(new Triple(q, sP, r));
588: data.add(new Triple(C1, sC, C2));
589: data.add(new Triple(C2, sC, C3));
590: data.add(new Triple(a, ty, C1));
591: List rules = Rule
592: .parseRules("[rdfs8: (?a rdfs:subClassOf ?b), (?b rdfs:subClassOf ?c) -> (?a rdfs:subClassOf ?c)]"
593: + "[rdfs9: (?x rdfs:subClassOf ?y), (?a rdf:type ?x) -> (?a rdf:type ?y)]"
594: +
595: // "[-> (rdf:type rdfs:range rdfs:Class)]" +
596: "[rdfs3: (?x ?p ?y), (?p rdfs:range ?c) -> (?y rdf:type ?c)]"
597: + "[rdfs7: (?a rdf:type rdfs:Class) -> (?a rdfs:subClassOf ?a)]");
598: Reasoner reasoner = createReasoner(rules);
599: InfGraph infgraph = reasoner.bind(data);
600: TestUtil.assertIteratorValues(this , infgraph.find(a, ty, null),
601: new Object[] { new Triple(a, ty, C1),
602: new Triple(a, ty, C2), new Triple(a, ty, C3) });
603: TestUtil.assertIteratorValues(this , infgraph.find(C1, sC, a),
604: new Object[] {});
605: }
606:
607: /**
608: * Test complex rule head unification
609: */
610: public void testHeadUnify() {
611: Graph data = Factory.createGraphMem();
612: data.add(new Triple(c, q, d));
613: List rules = Rule.parseRules("[r1: (c r ?x) <- (?x p f(?x b))]"
614: + "[r2: (?y p f(a ?y)) <- (c q ?y)]");
615: Reasoner reasoner = createReasoner(rules);
616: InfGraph infgraph = reasoner.bind(data);
617: TestUtil.assertIteratorValues(this , infgraph.find(c, r, null),
618: new Object[] {});
619:
620: data.add(new Triple(c, q, a));
621: rules = Rule.parseRules("[r1: (c r ?x) <- (?x p f(?x a))]"
622: + "[r2: (?y p f(a ?y)) <- (c q ?y)]");
623: reasoner = createReasoner(rules);
624: infgraph = reasoner.bind(data);
625: TestUtil.assertIteratorValues(this , infgraph.find(c, r, null),
626: new Object[] { new Triple(c, r, a) });
627:
628: data = Factory.createGraphMem();
629: data.add(new Triple(a, q, a));
630: data.add(new Triple(a, q, b));
631: data.add(new Triple(a, q, c));
632: data.add(new Triple(b, q, d));
633: data.add(new Triple(b, q, b));
634: rules = Rule.parseRules("[r1: (c r ?x) <- (?x p ?x)]"
635: + "[r2: (?x p ?y) <- (a q ?x), (b q ?y)]");
636: reasoner = createReasoner(rules);
637: infgraph = reasoner.bind(data);
638: TestUtil.assertIteratorValues(this , infgraph.find(c, r, null),
639: new Object[] { new Triple(c, r, b) });
640:
641: rules = Rule.parseRules("[r1: (c r ?x) <- (?x p ?x)]"
642: + "[r2: (a p ?x) <- (a q ?x)]");
643: reasoner = createReasoner(rules);
644: infgraph = reasoner.bind(data);
645: TestUtil.assertIteratorValues(this , infgraph.find(c, r, null),
646: new Object[] { new Triple(c, r, a) });
647: }
648:
649: /**
650: * Test restriction example
651: */
652: public void testRestriction1() {
653: Graph data = Factory.createGraphMem();
654: data.add(new Triple(a, ty, r));
655: data.add(new Triple(a, p, b));
656: data.add(new Triple(r, sC, C1));
657: data.add(new Triple(C1, OWL.onProperty.asNode(), p));
658: data.add(new Triple(C1, OWL.allValuesFrom.asNode(), c));
659: List rules = Rule
660: .parseRules("[rdfs9: (?x rdfs:subClassOf ?y) (?a rdf:type ?x) -> (?a rdf:type ?y)]"
661: + "[restriction2: (?C owl:onProperty ?P), (?C owl:allValuesFrom ?D) -> (?C owl:equivalentClass all(?P, ?D))]"
662: + "[rs2: (?D owl:equivalentClass all(?P,?C)), (?X rdf:type ?D) -> (?X rdf:type all(?P,?C))]"
663: + "[rp4: (?X rdf:type all(?P, ?C)), (?X ?P ?Y) -> (?Y rdf:type ?C)]");
664: Reasoner reasoner = createReasoner(rules);
665: InfGraph infgraph = reasoner.bind(data);
666: TestUtil.assertIteratorValues(this , infgraph.find(b, ty, c),
667: new Object[] { new Triple(b, ty, c) });
668: }
669:
670: /**
671: * Test restriction example. The rules are more than the minimum required
672: * to solve the query and they interact to given run away seaches if there
673: * is a problem.
674: */
675: public void testRestriction2() {
676: Graph data = Factory.createGraphMem();
677: data.add(new Triple(a, ty, OWL.Thing.asNode()));
678: data.add(new Triple(p, ty, OWL.FunctionalProperty.asNode()));
679: data.add(new Triple(c, OWL.equivalentClass.asNode(), C1));
680: data.add(new Triple(C1, ty, OWL.Restriction.asNode()));
681: data.add(new Triple(C1, OWL.onProperty.asNode(), p));
682: data.add(new Triple(C1, OWL.maxCardinality.asNode(), Util
683: .makeIntNode(1)));
684: List rules = Rule.parseRules(
685: // these ones are required for the inference.
686: "[rdfs9: bound(?y) (?x rdfs:subClassOf ?y) (?a rdf:type ?x) -> (?a rdf:type ?y)]"
687: + "[restriction4: (?C rdf:type owl:Restriction), (?C owl:onProperty ?P), (?C owl:maxCardinality ?X) -> (?C owl:equivalentClass max(?P, ?X))]"
688: + "[restrictionProc11: (?P rdf:type owl:FunctionalProperty), (?X rdf:type owl:Thing) -> (?X rdf:type max(?P, 1))]"
689: +
690: // "[equivalentClass1: (?P owl:equivalentClass ?Q) -> (?P rdfs:subClassOf ?Q), (?Q rdfs:subClassOf ?P) ]" +
691: "[equivalentClass1: (?P owl:equivalentClass ?Q) -> (?P rdfs:subClassOf ?Q) ]"
692: + "[equivalentClass1: (?P owl:equivalentClass ?Q) -> (?Q rdfs:subClassOf ?P) ]"
693: + "[restrictionSubclass1: bound(?D) (?D owl:equivalentClass ?R), isFunctor(?R) (?X rdf:type ?R)-> (?X rdf:type ?D)]"
694: +
695: // these ones are noise which can cause run aways or failures if there are bugs
696: "[rdfs8: unbound(?c) (?a rdfs:subClassOf ?b) (?b rdfs:subClassOf ?c) -> (?a rdfs:subClassOf ?c)]"
697: + "[rdfs8: bound(?c) (?b rdfs:subClassOf ?c) (?a rdfs:subClassOf ?b) -> (?a rdfs:subClassOf ?c)]"
698: + "[rdfs9: unbound(?y) (?a rdf:type ?x) (?x rdfs:subClassOf ?y) -> (?a rdf:type ?y)]"
699: + "[-> (rdf:type rdfs:range rdfs:Class)]"
700: + "[rdfs3: bound(?c) (?p rdfs:range ?c) (?x ?p ?y) -> (?y rdf:type ?c)]"
701: + "[rdfs7: (?a rdf:type rdfs:Class) -> (?a rdfs:subClassOf ?a)]"
702: + "[restrictionProc13: (owl:Thing rdfs:subClassOf all(?P, ?C)) -> (?P rdfs:range ?C)]"
703: + "[restrictionSubclass1: unbound(?D) (?X rdf:type ?R), isFunctor(?R) (?D owl:equivalentClass ?R) -> (?X rdf:type ?D)]"
704: + "[restrictionSubclass2: bound(?R), isFunctor(?R), (?D owl:equivalentClass ?R),(?X rdf:type ?D) -> (?X rdf:type ?R)]"
705: + "[restrictionSubclass2: unbound(?R), (?X rdf:type ?D), (?D owl:equivalentClass ?R) isFunctor(?R) -> (?X rdf:type ?R)]"
706: + "");
707: Reasoner reasoner = createReasoner(rules);
708: InfGraph infgraph = reasoner.bind(data);
709: TestUtil.assertIteratorValues(this , infgraph.find(a, ty, C1),
710: new Object[] { new Triple(a, ty, C1) });
711: TestUtil.assertIteratorValues(this , infgraph.find(a, ty, c),
712: new Object[] { new Triple(a, ty, c) });
713: }
714:
715: /**
716: * Test restriction example
717: */
718: public void testRestriction3() {
719: Graph data = Factory.createGraphMem();
720: data.add(new Triple(a, ty, r));
721: data.add(new Triple(r, sC, C1));
722: data.add(new Triple(C1, ty, OWL.Restriction.asNode()));
723: data.add(new Triple(C1, OWL.onProperty.asNode(), p));
724: data.add(new Triple(C1, OWL.allValuesFrom.asNode(), c));
725: List rules = Rule
726: .parseRules("[-> (rdfs:subClassOf rdfs:range rdfs:Class)]"
727: +
728: // "[-> (owl:Class rdfs:subClassOf rdfs:Class)]" +
729: "[rdfs3: bound(?c) (?p rdfs:range ?c) (?x ?p ?y) -> (?y rdf:type ?c)]"
730: + "[rdfs3: unbound(?c) (?x ?p ?y), (?p rdfs:range ?c) -> (?y rdf:type ?c)]"
731: + "[rdfs7: (?a rdf:type rdfs:Class) -> (?a rdfs:subClassOf ?a)]"
732: + "[rdfs8: (?a rdfs:subClassOf ?b) (?b rdfs:subClassOf ?c) -> (?a rdfs:subClassOf ?c)]"
733: + "[restrictionProc4b: bound(?Y) (?X ?P ?Y), notEqual(?P, rdf:type), (?X rdf:type all(?P, ?C)),-> (?Y rdf:type ?C)]"
734: + "[restrictionProc4b: unbound(?Y), (?X rdf:type all(?P, ?C)), (?X ?P ?Y), notEqual(?P, rdf:type),-> (?Y rdf:type ?C)]"
735: + "");
736: Reasoner reasoner = createReasoner(rules);
737: InfGraph infgraph = reasoner.bind(data);
738: TestUtil.assertIteratorValues(this , infgraph.find(null, ty, c),
739: new Object[] {});
740: }
741:
742: /**
743: * Test close and halt operation.
744: */
745: public void testClose() {
746: Graph data = Factory.createGraphMem();
747: data.add(new Triple(p, sP, q));
748: data.add(new Triple(q, sP, r));
749: data.add(new Triple(C1, sC, C2));
750: data.add(new Triple(C2, sC, C3));
751: data.add(new Triple(a, ty, C1));
752: data.add(new Triple(ty, RDFS.range.asNode(), RDFS.Class
753: .asNode()));
754: List rules = Rule
755: .parseRules("[rdfs8: (?a rdfs:subClassOf ?b), (?b rdfs:subClassOf ?c) -> (?a rdfs:subClassOf ?c)]"
756: + "[rdfs9: (?x rdfs:subClassOf ?y), (?a rdf:type ?x) -> (?a rdf:type ?y)]"
757: +
758: // "[-> (rdf:type rdfs:range rdfs:Class)]" +
759: "[rdfs3: (?x ?p ?y), (?p rdfs:range ?c) -> (?y rdf:type ?c)]"
760: + "[rdfs7: (?a rdf:type rdfs:Class) -> (?a rdfs:subClassOf ?a)]");
761: Reasoner reasoner = createReasoner(rules);
762: InfGraph infgraph = reasoner.bind(data);
763: // Get just one result
764: ExtendedIterator it = infgraph.find(a, ty, null);
765: Triple result = (Triple) it.next();
766: assertEquals(result.getSubject(), a);
767: assertEquals(result.getPredicate(), ty);
768: it.close();
769: // Make sure if we start again we get the full listing.
770: TestUtil.assertIteratorValues(this , infgraph.find(a, ty, null),
771: new Object[] { new Triple(a, ty, C1),
772: new Triple(a, ty, C2), new Triple(a, ty, C3) });
773: }
774:
775: /**
776: * Test problematic rdfs case
777: */
778: public void testBug1() throws IOException {
779: Graph data = Factory.createGraphMem();
780: Node p = Node
781: .createURI("http://www.hpl.hp.com/semweb/2003/eg#p");
782: Node r = Node
783: .createURI("http://www.hpl.hp.com/semweb/2003/eg#r");
784: Node C1 = Node
785: .createURI("http://www.hpl.hp.com/semweb/2003/eg#C1");
786: data.add(new Triple(a, p, b));
787: List rules = Rule
788: .parseRules(Util
789: .loadRuleParserFromResourceFile("testing/reasoners/bugs/rdfs-error1.brules"));
790: Reasoner reasoner = createReasoner(rules);
791: InfGraph infgraph = reasoner.bind(data);
792: TestUtil.assertIteratorValues(this , infgraph.find(b, ty, C1),
793: new Object[] { new Triple(b, ty, C1) });
794:
795: }
796:
797: }
798:
799: /*
800: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
801: All rights reserved.
802:
803: Redistribution and use in source and binary forms, with or without
804: modification, are permitted provided that the following conditions
805: are met:
806:
807: 1. Redistributions of source code must retain the above copyright
808: notice, this list of conditions and the following disclaimer.
809:
810: 2. Redistributions in binary form must reproduce the above copyright
811: notice, this list of conditions and the following disclaimer in the
812: documentation and/or other materials provided with the distribution.
813:
814: 3. The name of the author may not be used to endorse or promote products
815: derived from this software without specific prior written permission.
816:
817: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
818: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
819: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
820: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
821: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
822: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
823: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
824: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
825: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
826: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
827: */
|