0001: /******************************************************************
0002: * File: TestBasicLP.java
0003: * Created by: Dave Reynolds
0004: * Created on: 22-Jul-2003
0005: *
0006: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
0007: * [See end of file]
0008: * $Id: TestBasicLP.java,v 1.18 2008/01/02 12:08:19 andy_seaborne Exp $
0009: *****************************************************************/package com.hp.hpl.jena.reasoner.rulesys.test;
0010:
0011: import java.util.*;
0012:
0013: import com.hp.hpl.jena.graph.*;
0014: import com.hp.hpl.jena.reasoner.*;
0015: import com.hp.hpl.jena.reasoner.rulesys.*;
0016: import com.hp.hpl.jena.reasoner.test.TestUtil;
0017: import com.hp.hpl.jena.util.iterator.ExtendedIterator;
0018: import com.hp.hpl.jena.vocabulary.*;
0019:
0020: import java.io.*;
0021:
0022: import junit.framework.TestCase;
0023: import junit.framework.TestSuite;
0024:
0025: /**
0026: * Early test cases for the LP version of the backward chaining system.
0027: * <p>
0028: * To be moved to a test directory once the code is working.
0029: * </p>
0030: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
0031: * @version $Revision: 1.18 $ on $Date: 2008/01/02 12:08:19 $
0032: */
0033: public class TestBasicLP extends TestCase {
0034:
0035: // Useful constants
0036: Node p = Node.createURI("p");
0037: Node q = Node.createURI("q");
0038: Node r = Node.createURI("r");
0039: Node s = Node.createURI("s");
0040: Node t = Node.createURI("t");
0041: Node u = Node.createURI("u");
0042: Node a = Node.createURI("a");
0043: Node b = Node.createURI("b");
0044: Node c = Node.createURI("c");
0045: Node d = Node.createURI("d");
0046: Node e = Node.createURI("e");
0047: Node C1 = Node.createURI("C1");
0048: Node C2 = Node.createURI("C2");
0049: Node C3 = Node.createURI("C3");
0050: Node C4 = Node.createURI("C4");
0051: Node D1 = Node.createURI("D1");
0052: Node D2 = Node.createURI("D2");
0053: Node D3 = Node.createURI("D3");
0054: Node sP = RDFS.Nodes.subPropertyOf;
0055: Node sC = RDFS.Nodes.subClassOf;
0056: Node ty = RDF.Nodes.type;
0057:
0058: /**
0059: * Boilerplate for junit
0060: */
0061: public TestBasicLP(String name) {
0062: super (name);
0063: }
0064:
0065: /**
0066: * Boilerplate for junit.
0067: * This is its own test suite
0068: */
0069: public static TestSuite suite() {
0070: // return new TestSuite( TestBasicLP.class );
0071:
0072: TestSuite suite = new TestSuite();
0073: suite.addTest(new TestBasicLP("testCME"));
0074: return suite;
0075: }
0076:
0077: /**
0078: * Return an inference graph working over the given rule set and raw data.
0079: * Can be overridden by subclasses of this test class.
0080: * @param rules the rule set to use
0081: * @param data the graph of triples to process
0082: */
0083: public InfGraph makeInfGraph(List rules, Graph data) {
0084: FBRuleReasoner reasoner = new FBRuleReasoner(rules);
0085: FBRuleInfGraph infgraph = (FBRuleInfGraph) reasoner.bind(data);
0086: // infgraph.setTraceOn(true);
0087: return infgraph;
0088: }
0089:
0090: /**
0091: * Return an inference graph working over the given rule set and raw data.
0092: * Can be overridden by subclasses of this test class.
0093: * @param rules the rule set to use
0094: * @param data the graph of triples to process
0095: * @param tabled an array of predicates that should be tabled
0096: */
0097: public InfGraph makeInfGraph(List rules, Graph data, Node[] tabled) {
0098: FBRuleReasoner reasoner = new FBRuleReasoner(rules);
0099: FBRuleInfGraph infgraph = (FBRuleInfGraph) reasoner.bind(data);
0100: for (int i = 0; i < tabled.length; i++) {
0101: infgraph.setTabled(tabled[i]);
0102: }
0103: return infgraph;
0104: }
0105:
0106: /**
0107: * Test basic rule operations - lookup, no matching rules
0108: */
0109: public void testBaseRules1() {
0110: doBasicTest("[r1: (?x r c) <- (?x p b)]", new Triple(Node.ANY,
0111: p, b), new Object[] { new Triple(a, p, b) });
0112: }
0113:
0114: /**
0115: * Test basic rule operations - simple chain rule
0116: */
0117: public void testBaseRules2() {
0118: doBasicTest("[r1: (?x r c) <- (?x p b)]", new Triple(Node.ANY,
0119: r, c), new Object[] { new Triple(a, r, c) });
0120: }
0121:
0122: /**
0123: * Test basic rule operations - chain rule with head unification
0124: */
0125: public void testBaseRules3() {
0126: doBasicTest("[r1: (?x r ?x) <- (?x p b)]", new Triple(Node.ANY,
0127: r, a), new Object[] { new Triple(a, r, a) });
0128: }
0129:
0130: /**
0131: * Test basic rule operations - rule with head unification, non-temp var
0132: */
0133: public void testBaseRules4() {
0134: doBasicTest("[r1: (?x r ?x) <- (?y p b), (?x p b)]",
0135: new Triple(Node.ANY, r, a), new Object[] { new Triple(
0136: a, r, a) });
0137: }
0138:
0139: /**
0140: * Test basic rule operations - simple cascade
0141: */
0142: public void testBaseRules5() {
0143: doBasicTest("[r1: (?x q ?y) <- (?x r ?y)(?y s ?x)]"
0144: + "[r2: (?x r ?y) <- (?x p ?y)]"
0145: + "[r3: (?x s ?y) <- (?y p ?x)]", new Triple(Node.ANY,
0146: q, Node.ANY), new Object[] { new Triple(a, q, b) });
0147: }
0148:
0149: /**
0150: * Test basic rule operations - chain rule which will fail at head time
0151: */
0152: public void testBaseRules6() {
0153: doBasicTest("[r1: (?x r ?x) <- (?x p b)]", new Triple(a, r, b),
0154: new Object[] {});
0155: }
0156:
0157: /**
0158: * Test basic rule operations - chain rule which will fail in search
0159: */
0160: public void testBaseRules7() {
0161: doBasicTest("[r1: (?x r ?y) <- (?x p c)]", new Triple(a, r, b),
0162: new Object[] {});
0163: }
0164:
0165: /**
0166: * Test basic rule operations - simple chain
0167: */
0168: public void testBaseRules8() {
0169: doBasicTest("[r1: (?x q ?y) <- (?x r ?y)]"
0170: + "[r2: (?x r ?y) <- (?x p ?y)]", new Triple(Node.ANY,
0171: q, Node.ANY), new Object[] { new Triple(a, q, b) });
0172: }
0173:
0174: /**
0175: * Test basic rule operations - simple chain
0176: */
0177: public void testBaseRules9() {
0178: doBasicTest("[r1: (?x q ?y) <- (?x r ?y)]"
0179: + "[r2: (?x r ?y) <- (?y p ?x)]", new Triple(Node.ANY,
0180: q, Node.ANY), new Object[] { new Triple(b, q, a) });
0181: }
0182:
0183: /**
0184: * Test backtracking - simple triple query.
0185: */
0186: public void testBacktrack1() {
0187: doTest("[r1: (?x r ?y) <- (?x p ?y)]", new Triple[] {
0188: new Triple(a, p, b), new Triple(a, p, c),
0189: new Triple(a, p, d) }, new Triple(a, p, Node.ANY),
0190: new Object[] { new Triple(a, p, b),
0191: new Triple(a, p, c), new Triple(a, p, d) });
0192: }
0193:
0194: /**
0195: * Test backtracking - chain to simple triple query.
0196: */
0197: public void testBacktrack2() {
0198: doTest("[r1: (?x r ?y) <- (?x p ?y)]", new Triple[] {
0199: new Triple(a, p, b), new Triple(a, p, c),
0200: new Triple(a, p, d) }, new Triple(a, r, Node.ANY),
0201: new Object[] { new Triple(a, r, b),
0202: new Triple(a, r, c), new Triple(a, r, d) });
0203: }
0204:
0205: /**
0206: * Test backtracking - simple choice point
0207: */
0208: public void testBacktrack3() {
0209: doTest("[r1: (?x r C1) <- (?x p b)]"
0210: + "[r2: (?x r C2) <- (?x p b)]"
0211: + "[r3: (?x r C3) <- (?x p b)]",
0212: new Triple[] { new Triple(a, p, b) }, new Triple(a, r,
0213: Node.ANY), new Object[] { new Triple(a, r, C1),
0214: new Triple(a, r, C2), new Triple(a, r, C3) });
0215: }
0216:
0217: /**
0218: * Test backtracking - nested choice point
0219: */
0220: public void testBacktrack4() {
0221: doTest("[r1: (?x r C1) <- (?x p b)]"
0222: + "[r2: (?x r C2) <- (?x p b)]"
0223: + "[r3: (?x r C3) <- (?x p b)]"
0224: + "[r4: (?x s ?z) <- (?x p ?w), (?x r ?y) (?y p ?z)]",
0225: new Triple[] { new Triple(a, p, b),
0226: new Triple(C1, p, D1), new Triple(C2, p, D2),
0227: new Triple(C3, p, D3) }, new Triple(a, s,
0228: Node.ANY), new Object[] { new Triple(a, s, D1),
0229: new Triple(a, s, D2), new Triple(a, s, D3) });
0230: }
0231:
0232: /**
0233: * Test backtracking - nested choice point with multiple triple matches
0234: */
0235: public void testBacktrack5() {
0236: doTest("[r1: (?x r C3) <- (C1 p ?x)]"
0237: + "[r2: (?x r C2) <- (C2 p ?x)]"
0238: + "[r4: (?x s ?y) <- (?x r ?y)]", new Triple[] {
0239: new Triple(C1, p, D1), new Triple(C1, p, a),
0240: new Triple(C2, p, D2), new Triple(C2, p, b) },
0241: new Triple(Node.ANY, s, Node.ANY), new Object[] {
0242: new Triple(D1, s, C3), new Triple(a, s, C3),
0243: new Triple(D2, s, C2), new Triple(b, s, C2) });
0244: }
0245:
0246: /**
0247: * Test backtracking - nested choice point with multiple triple matches, and
0248: * checking temp v. permanent variable usage
0249: */
0250: public void testBacktrack6() {
0251: doTest("[r1: (?x r C1) <- (?x p a)]"
0252: + "[r2: (?x r C2) <- (?x p b)]"
0253: + "[r3: (?x q C1) <- (?x p b)]"
0254: + "[r4: (?x q C2) <- (?x p a)]"
0255: + "[r5: (?x s ?y) <- (?x r ?y) (?x q ?y)]",
0256: new Triple[] { new Triple(D1, p, a),
0257: new Triple(D2, p, a), new Triple(D2, p, b),
0258: new Triple(D3, p, b) }, new Triple(Node.ANY, s,
0259: Node.ANY), new Object[] {
0260: new Triple(D2, s, C1), new Triple(D2, s, C2), });
0261: }
0262:
0263: /**
0264: * Test backtracking - nested choice point with simple triple matches
0265: */
0266: public void testBacktrack7() {
0267: doTest("[r1: (?x r C1) <- (?x p b)]"
0268: + "[r2: (?x r C2) <- (?x p b)]"
0269: + "[r3: (?x r C3) <- (?x p b)]"
0270: + "[r3: (?x r D1) <- (?x p b)]"
0271: + "[r4: (?x q C2) <- (?x p b)]"
0272: + "[r5: (?x q C3) <- (?x p b)]"
0273: + "[r5: (?x q D1) <- (?x p b)]"
0274: + "[r6: (?x t C1) <- (?x p b)]"
0275: + "[r7: (?x t C2) <- (?x p b)]"
0276: + "[r8: (?x t C3) <- (?x p b)]"
0277: + "[r9: (?x s ?y) <- (?x r ?y) (?x q ?y) (?x t ?y)]",
0278: new Triple[] { new Triple(a, p, b), }, new Triple(
0279: Node.ANY, s, Node.ANY), new Object[] {
0280: new Triple(a, s, C2), new Triple(a, s, C3), });
0281: }
0282:
0283: /**
0284: * Test backtracking - nested choice point with simple triple matches,
0285: * permanent vars but used just once in body
0286: */
0287: public void testBacktrack8() {
0288: doTest("[r1: (?x r C1) <- (?x p b)]"
0289: + "[r2: (?x r C2) <- (?x p b)]"
0290: + "[r3: (?x r C3) <- (?x p b)]"
0291: + "[r3: (?x r D1) <- (?x p b)]"
0292: + "[r4: (?x q C2) <- (?x p b)]"
0293: + "[r5: (?x q C3) <- (?x p b)]"
0294: + "[r5: (?x q D1) <- (?x p b)]"
0295: + "[r6: (?x t C1) <- (?x p b)]"
0296: + "[r7: (?x t C2) <- (?x p b)]"
0297: + "[r8: (?x t C3) <- (?x p b)]"
0298: + "[r9: (?x s ?y) <- (?w r C1) (?x q ?y) (?w t C1)]",
0299: new Triple[] { new Triple(a, p, b), }, new Triple(
0300: Node.ANY, s, Node.ANY), new Object[] {
0301: new Triple(a, s, D1), new Triple(a, s, C2),
0302: new Triple(a, s, C3), });
0303: }
0304:
0305: /**
0306: * Test backtracking - multiple triple matches
0307: */
0308: public void testBacktrack9() {
0309: doTest("[r1: (?x s ?y) <- (?x r ?y) (?x q ?y)]", new Triple[] {
0310: new Triple(a, r, D1), new Triple(a, r, D2),
0311: new Triple(a, r, D3), new Triple(b, r, D2),
0312: new Triple(a, q, D2), new Triple(b, q, D2),
0313: new Triple(b, q, D3), }, new Triple(Node.ANY, s,
0314: Node.ANY), new Object[] { new Triple(a, s, D2),
0315: new Triple(b, s, D2), });
0316: }
0317:
0318: /**
0319: * Test backtracking - multiple triple matches
0320: */
0321: public void testBacktrack10() {
0322: doTest(
0323: "[r1: (?x s ?y) <- (?x r ?y) (?x q ?z), equal(?y, ?z)(?x, p, ?y)]"
0324: + "[(a p D1) <- ]" + "[(a p D2) <- ]"
0325: + "[(b p D1) <- ]", new Triple[] {
0326: new Triple(a, r, D1), new Triple(a, r, D2),
0327: new Triple(a, r, D3), new Triple(b, r, D2),
0328: new Triple(a, q, D2), new Triple(b, q, D2),
0329: new Triple(b, q, D3), }, new Triple(Node.ANY,
0330: s, Node.ANY), new Object[] { new Triple(a, s,
0331: D2), });
0332: }
0333:
0334: /**
0335: * Test clause order is right
0336: */
0337: public void testClauseOrder() {
0338: List rules = Rule.parseRules("[r1: (?x r C1) <- (?x p b)]"
0339: + "[r1: (?x r C2) <- (?x p b)]"
0340: + "[r2: (?x r C3) <- (?x r C3) (?x p b)]");
0341: Graph data = Factory.createGraphMem();
0342: data.add(new Triple(a, p, b));
0343: InfGraph infgraph = makeInfGraph(rules, data);
0344: ExtendedIterator i = infgraph.find(Node.ANY, r, Node.ANY);
0345: assertTrue(i.hasNext());
0346: assertEquals(i.next(), new Triple(a, r, C1));
0347: i.close();
0348: }
0349:
0350: /**
0351: * Test axioms work.
0352: */
0353: public void testAxioms() {
0354: doTest(
0355: "[a1: -> (a r C1) ]" + "[a2: -> (a r C2) ]"
0356: + "[a3: (b r C1) <- ]"
0357: + "[r1: (?x s ?y) <- (?x r ?y)]",
0358: new Triple[] {}, new Triple(Node.ANY, s, Node.ANY),
0359: new Object[] { new Triple(a, s, C1),
0360: new Triple(a, s, C2), new Triple(b, s, C1), });
0361: }
0362:
0363: /**
0364: * Test nested invocation of rules with permanent vars
0365: */
0366: public void testNestedPvars() {
0367: doTest("[r1: (?x r ?y) <- (?x p ?z) (?z q ?y)]"
0368: + "[r1: (?y t ?x) <- (?x p ?z) (?z q ?y)]"
0369: + "[r3: (?x s ?y) <- (?x r ?y) (?y t ?x)]",
0370: new Triple[] { new Triple(a, p, C1),
0371: new Triple(a, p, C2), new Triple(a, p, C3),
0372: new Triple(C2, q, b), new Triple(C3, q, c),
0373: new Triple(D1, q, D2), }, new Triple(Node.ANY,
0374: s, Node.ANY), new Object[] {
0375: new Triple(a, s, b), new Triple(a, s, c), });
0376: }
0377:
0378: /**
0379: * Test simple invocation of a builtin
0380: */
0381: public void testBuiltin1() {
0382: doTest("[r1: (?x r ?y) <- (?x p ?v), sum(?v 2 ?y)]",
0383: new Triple[] { new Triple(a, p, Util.makeIntNode(3)),
0384: new Triple(b, p, Util.makeIntNode(4)) },
0385: new Triple(Node.ANY, r, Node.ANY), new Object[] {
0386: new Triple(a, r, Util.makeIntNode(5)),
0387: new Triple(b, r, Util.makeIntNode(6)), });
0388: }
0389:
0390: /**
0391: * Test simple invocation of a builtin
0392: */
0393: public void testBuiltin2() {
0394: doTest("[r1: (?x r C1) <- (?x p ?v), lessThan(?v 3)]",
0395: new Triple[] { new Triple(a, p, Util.makeIntNode(1)),
0396: new Triple(b, p, Util.makeIntNode(2)),
0397: new Triple(c, p, Util.makeIntNode(3)) },
0398: new Triple(Node.ANY, r, Node.ANY), new Object[] {
0399: new Triple(a, r, C1), new Triple(b, r, C1), });
0400: }
0401:
0402: /**
0403: * Test wildcard predicate usage - simple triple search.
0404: * Rules look odd because we have to hack around the recursive loops.
0405: */
0406: public void testWildPredicate1() {
0407: doTest(
0408: "[r1: (b r ?y) <- (a ?y ?v)]",
0409: new Triple[] { new Triple(a, p, C1),
0410: new Triple(a, q, C2), new Triple(a, q, C3), },
0411: new Triple(b, r, Node.ANY),
0412: new Object[] { new Triple(b, r, p), new Triple(b, r, q) });
0413: }
0414:
0415: /**
0416: * Test wildcard predicate usage - combind triple search and multiclause matching.
0417: * Rules look odd because we have to hack around the recursive loops.
0418: */
0419: public void testWildPredicate2() {
0420: doTest("[r1: (a r ?y) <- (b ?y ?v)]"
0421: + "[r2: (?x q ?y) <- (?x p ?y)]"
0422: + "[r3: (?x s C1) <- (?x p C1)]"
0423: + "[r4: (?x t C2) <- (?x p C2)]", new Triple[] {
0424: new Triple(b, p, C1), new Triple(b, q, C2),
0425: new Triple(b, q, C3), new Triple(a, p, C1),
0426: new Triple(a, p, C2), new Triple(c, p, C1), },
0427: new Triple(a, Node.ANY, Node.ANY), new Object[] {
0428: new Triple(a, r, p), new Triple(a, r, q),
0429: new Triple(a, q, C1), new Triple(a, q, C2),
0430: new Triple(a, s, C1), new Triple(a, t, C2),
0431: new Triple(a, p, C1), new Triple(a, p, C2),
0432: new Triple(a, r, s), });
0433: }
0434:
0435: /**
0436: * Test wildcard predicate usage - combined triple search and multiclause matching.
0437: * Rules look odd because we have to hack around the recursive loops.
0438: */
0439: public void testWildPredicate3() {
0440: String rules = "[r1: (a r ?y) <- (b ?y ?v)]"
0441: + "[r2: (?x q ?y) <- (?x p ?y)]"
0442: + "[r3: (?x s C1) <- (?x p C1)]"
0443: + "[r4: (?x t ?y) <- (?x ?y C1)]";
0444: Triple[] data = new Triple[] { new Triple(b, p, C1),
0445: new Triple(b, q, C2), new Triple(b, q, C3),
0446: new Triple(a, p, C1), new Triple(a, p, C2),
0447: new Triple(c, p, C1), };
0448: doTest(rules, data, new Triple(a, Node.ANY, C1), new Object[] {
0449: new Triple(a, q, C1), new Triple(a, s, C1),
0450: new Triple(a, p, C1), });
0451: doTest(rules, data, new Triple(a, t, Node.ANY), new Object[] {
0452: new Triple(a, t, q), new Triple(a, t, s),
0453: new Triple(a, t, p), });
0454: doTest(rules, data, new Triple(Node.ANY, t, q), new Object[] {
0455: new Triple(a, t, q), new Triple(b, t, q),
0456: new Triple(c, t, q) });
0457: }
0458:
0459: /**
0460: * Test wildcard predicate usage - wildcard in head as well
0461: */
0462: public void testWildPredicate4() {
0463: doTest("[r1: (a ?p ?x) <- (b ?p ?x)]", new Triple[] {
0464: new Triple(b, p, C1), new Triple(b, q, C2),
0465: new Triple(b, q, C3), new Triple(c, q, d), },
0466: new Triple(a, Node.ANY, Node.ANY), new Object[] {
0467: new Triple(a, p, C1), new Triple(a, q, C2),
0468: new Triple(a, q, C3), });
0469: }
0470:
0471: /**
0472: * Test functor usage.
0473: */
0474: public void testFunctors1() {
0475: String ruleSrc = "[r1: (?x s ?y) <- (?x p foo(?z, ?y))] ";
0476: Triple[] triples = new Triple[] {
0477: new Triple(a, p, Functor.makeFunctorNode("foo",
0478: new Node[] { C1, C2 })),
0479: new Triple(a, p, Functor.makeFunctorNode("bar",
0480: new Node[] { C1, D1 })),
0481: new Triple(b, p, Functor.makeFunctorNode("foo",
0482: new Node[] { C1, C2 })),
0483: new Triple(a, p, Functor.makeFunctorNode("foo",
0484: new Node[] { C1, C3 })), new Triple(a, p, D1), };
0485: doTest(ruleSrc, triples, new Triple(Node.ANY, s, Node.ANY),
0486: new Object[] { new Triple(a, s, C2),
0487: new Triple(b, s, C2), new Triple(a, s, C3) });
0488: }
0489:
0490: /**
0491: * Test functor usage.
0492: */
0493: public void testFunctors2() {
0494: String ruleSrc = "[r1: (?x r foo(?y,?z)) <- (?x p ?y), (?x q ?z)]"
0495: + "[r2: (?x s ?y) <- (?x r foo(?z, ?y))] ";
0496: Triple[] triples = new Triple[] { new Triple(a, p, C1),
0497: new Triple(a, p, C3), new Triple(a, q, C2),
0498: new Triple(b, p, D1), new Triple(b, q, D2),
0499: new Triple(b, q, D3), };
0500: doTest(ruleSrc, triples, new Triple(Node.ANY, s, Node.ANY),
0501: new Object[] { new Triple(a, s, C2),
0502: new Triple(b, s, D2), new Triple(b, s, D3) });
0503: }
0504:
0505: /**
0506: * Test functor usage.
0507: */
0508: public void testFunctors3() {
0509: String ruleSrc = "[r1: (?x r foo(p,?y)) <- (?x p ?y)]"
0510: + "[r2: (?x r foo(q,?y)) <- (?x q ?y)]"
0511: + "[r3: (?x r ?y) <- (?x t ?y)] "
0512: + "[r4: (?x s ?y) <- (?x r ?y), notFunctor(?y)] "
0513: + "[r5: (?x s ?y) <- (?x r foo(?y, ?z))] ";
0514: Triple[] triples = new Triple[] { new Triple(a, p, C1),
0515: new Triple(b, q, D1), new Triple(b, p, D2),
0516: new Triple(c, t, d) };
0517: doTest(ruleSrc, triples, new Triple(Node.ANY, s, Node.ANY),
0518: new Object[] { new Triple(a, s, p),
0519: new Triple(b, s, p), new Triple(b, s, q),
0520: new Triple(c, s, d) });
0521: }
0522:
0523: /**
0524: * Test tabled predicates. Simple chain call case.
0525: */
0526: public void testTabled1() {
0527: doTest("[r1: (?a q ?b) <- (?a p ?b)]"
0528: + "[r2: (?x r ?y) <- (?x q ?y)]", new Node[] { q },
0529: new Triple[] { new Triple(a, p, b),
0530: new Triple(b, p, c), }, new Triple(Node.ANY, r,
0531: Node.ANY), new Object[] { new Triple(a, r, b),
0532: new Triple(b, r, c) });
0533: }
0534:
0535: /**
0536: * Test tabled predicates. Simple transitive closure case.
0537: */
0538: public void testTabled2() {
0539: doTest("[r1: (?a p ?c) <- (?a p ?b)(?b p ?c)]",
0540: new Node[] { p }, new Triple[] { new Triple(a, p, b),
0541: new Triple(b, p, c), new Triple(b, p, d), },
0542: new Triple(Node.ANY, p, Node.ANY), new Object[] {
0543: new Triple(a, p, b), new Triple(b, p, c),
0544: new Triple(a, p, c), new Triple(b, p, d),
0545: new Triple(a, p, d), });
0546: }
0547:
0548: /**
0549: * Test tabled predicates. Simple transitive closure over normal predicates
0550: */
0551: public void testTabled3() {
0552: doTest("[r1: (?x p ?z) <- (?x p ?y), (?y p ?z)]"
0553: + "[r2: (?x p ?z) <- (?x e ?z), (?z q ?z)]",
0554: new Node[] { p }, new Triple[] { new Triple(a, e, b),
0555: new Triple(a, e, d), new Triple(b, e, c),
0556: new Triple(a, q, a), new Triple(b, q, b),
0557: new Triple(c, q, c), }, new Triple(a, p,
0558: Node.ANY), new Object[] { new Triple(a, p, b),
0559: // new Triple(b, p, c),
0560: new Triple(a, p, c) });
0561: }
0562:
0563: /**
0564: * Test tabled predicates. Co-routining example.
0565: */
0566: public void testTabled4() {
0567: doTest(
0568: "[r1: (?x a ?y) <- (?x c ?y)]"
0569: + "[r2: (?x a ?y) <- (?x b ?z), (?z c ?y)]"
0570: + "[r3: (?x b ?y) <- (?x d ?y)]"
0571: + "[r4: (?x b ?y) <- (?x a ?z) (?z c ?y)]",
0572: new Node[] { a, b },
0573: new Triple[] { new Triple(p, c, q),
0574: new Triple(q, c, r), new Triple(p, d, q),
0575: new Triple(q, d, r), },
0576: new Triple(p, a, Node.ANY),
0577: new Object[] { new Triple(p, a, q), new Triple(p, a, r) });
0578: }
0579:
0580: /**
0581: * Test tabled predicates. Simple transitive closure case.
0582: */
0583: public void testTabled5() {
0584: doTest("[r1: (?a p ?c) <- (?a p ?b)(?b p ?c)]"
0585: + "[r2: (?a r ?b) <- (?a q ?b)]", new Node[] { p },
0586: new Triple[] { new Triple(a, p, b),
0587: new Triple(b, p, c), new Triple(a, q, d),
0588: new Triple(c, q, d), }, new Triple(a, Node.ANY,
0589: Node.ANY), new Object[] { new Triple(a, p, b),
0590: new Triple(a, p, c), new Triple(a, q, d),
0591: new Triple(a, r, d), });
0592: }
0593:
0594: /**
0595: * Test tabled predicates. Simple transitive closure case, tabling set
0596: * by rule base.
0597: */
0598: public void testTabled6() {
0599: doTest("[-> table(p)] [r1: (?a p ?c) <- (?a p ?b)(?b p ?c)]",
0600: new Triple[] { new Triple(a, p, b),
0601: new Triple(b, p, c), new Triple(b, p, d), },
0602: new Triple(Node.ANY, p, Node.ANY), new Object[] {
0603: new Triple(a, p, b), new Triple(b, p, c),
0604: new Triple(a, p, c), new Triple(b, p, d),
0605: new Triple(a, p, d), });
0606: }
0607:
0608: /**
0609: * Test tabled calls with aliased local vars in the call.
0610: */
0611: public void testTabled7() {
0612: doTest("[r1: (?a q ?b) <- (?a p ?b)]"
0613: + "[r2: (?a q ?a) <- (?a s ?a)]"
0614: + "[r2: (?a r ?z) <- (?a q ?a)]", new Node[] {},
0615: new Triple[] { new Triple(a, p, b),
0616: new Triple(c, p, c), new Triple(a, p, a),
0617: new Triple(b, s, e), new Triple(d, s, d), },
0618: new Triple(Node.ANY, r, C1), new Object[] {
0619: new Triple(a, r, C1), new Triple(c, r, C1),
0620: new Triple(d, r, C1), });
0621: }
0622:
0623: /**
0624: * Test RDFS example.
0625: */
0626: public void testRDFS1() {
0627: doTest("[ (?a rdf:type C1) <- (?a rdf:type C2) ]"
0628: + "[ (?a rdf:type C2) <- (?a rdf:type C3) ]"
0629: + "[ (?a rdf:type C3) <- (?a rdf:type C4) ]",
0630: new Node[] { ty },
0631: new Triple[] { new Triple(a, ty, C1),
0632: new Triple(b, ty, C2), new Triple(c, ty, C3),
0633: new Triple(d, ty, C4), }, new Triple(Node.ANY,
0634: ty, C1), new Object[] { new Triple(a, ty, C1),
0635: new Triple(b, ty, C1), new Triple(c, ty, C1),
0636: new Triple(d, ty, C1), });
0637: }
0638:
0639: /**
0640: * Test RDFS example - branched version
0641: */
0642: public void testRDFS2() {
0643: doTest("[ (?a rdf:type C1) <- (?a rdf:type C2) ]"
0644: + "[ (?a rdf:type C1) <- (?a rdf:type C3) ]"
0645: + "[ (?a rdf:type C1) <- (?a rdf:type C4) ]",
0646: new Node[] { ty },
0647: new Triple[] { new Triple(a, ty, C1),
0648: new Triple(b, ty, C2), new Triple(c, ty, C3),
0649: new Triple(d, ty, C4), }, new Triple(Node.ANY,
0650: ty, C1), new Object[] { new Triple(a, ty, C1),
0651: new Triple(b, ty, C1), new Triple(c, ty, C1),
0652: new Triple(d, ty, C1), });
0653: }
0654:
0655: /**
0656: * A problem from the original backchainer tests - interaction
0657: * of tabling and functor expansion.
0658: */
0659: public void testProblem1() {
0660: doTest("[r1: (a q f(?x,?y)) <- (a s ?x), (a t ?y)]"
0661: + "[r2: (a p ?x) <- (a q ?x)]"
0662: + "[r3: (a r ?y) <- (a p f(?x, ?y))]",
0663: new Node[] { p }, new Triple[] { new Triple(a, s, b),
0664: new Triple(a, t, c) }, new Triple(a, r,
0665: Node.ANY), new Object[] { new Triple(a, r, c) });
0666:
0667: }
0668:
0669: /**
0670: * A problem from the original backchainer tests - tabled closure operation.
0671: */
0672: public void testProblem2() {
0673: String ruleSrc = "[rdfs8: (?a rdfs:subClassOf ?c) <- (?a rdfs:subClassOf ?b), (?b rdfs:subClassOf ?c)]"
0674: + "[rdfs7: (?a rdfs:subClassOf ?a) <- (?a rdf:type rdfs:Class)]";
0675: doTest(ruleSrc, new Node[] { ty, sC }, new Triple[] {
0676: new Triple(C1, sC, C2), new Triple(C2, sC, C3),
0677: new Triple(C1, ty, RDFS.Class.asNode()),
0678: new Triple(C2, ty, RDFS.Class.asNode()),
0679: new Triple(C3, ty, RDFS.Class.asNode()) }, new Triple(
0680: Node.ANY, sC, Node.ANY), new Object[] {
0681: new Triple(C1, sC, C2), new Triple(C1, sC, C3),
0682: new Triple(C1, sC, C1), new Triple(C2, sC, C3),
0683: new Triple(C2, sC, C2), new Triple(C3, sC, C3) });
0684: }
0685:
0686: /**
0687: * A problem from the original backchainer tests - bound/unbound primitives
0688: */
0689: public void testProblem3() {
0690: String rules = "[r1: (?x r ?y ) <- bound(?x), (?x p ?y) ]"
0691: + "[r2: (?x r ?y) <- unbound(?x), (?x q ?y)]";
0692: doTest(rules, new Triple[] { new Triple(a, p, b),
0693: new Triple(a, q, c) }, new Triple(a, r, Node.ANY),
0694: new Object[] { new Triple(a, r, b) });
0695: doTest(rules, new Triple[] { new Triple(a, p, b),
0696: new Triple(a, q, c) },
0697: new Triple(Node.ANY, r, Node.ANY),
0698: new Object[] { new Triple(a, r, c) });
0699: }
0700:
0701: /**
0702: * A problem from the original backchainer tests - head unification test
0703: */
0704: public void testProblem4() {
0705: String rules = "[r1: (c r ?x) <- (?x p ?x)]"
0706: + "[r2: (?x p ?y) <- (a q ?x), (b q ?y)]";
0707: doTest(rules, new Node[] { r, p }, new Triple[] {
0708: new Triple(a, q, a), new Triple(a, q, b),
0709: new Triple(a, q, c), new Triple(b, q, b),
0710: new Triple(b, q, d), }, new Triple(c, r, Node.ANY),
0711: new Object[] { new Triple(c, r, b) });
0712: }
0713:
0714: /**
0715: * A problem from the original backchainer tests - RDFS example which threw an NPE
0716: */
0717: public void testProblem5() {
0718: String ruleSrc = "[rdfs8: (?a rdfs:subClassOf ?c) <- (?a rdfs:subClassOf ?b), (?b rdfs:subClassOf ?c)]"
0719: + "[rdfs9: (?a rdf:type ?y) <- (?x rdfs:subClassOf ?y), (?a rdf:type ?x)]"
0720: + "[(rdf:type rdfs:range rdfs:Class) <-]"
0721: + "[rdfs3: (?y rdf:type ?c) <- (?x ?p ?y), (?p rdfs:range ?c)]"
0722: + "[rdfs7: (?a rdfs:subClassOf ?a) <- (?a rdf:type rdfs:Class)]";
0723: doTest(ruleSrc, new Node[] { ty, sC }, new Triple[] {
0724: new Triple(p, sP, q), new Triple(q, sP, r),
0725: new Triple(C1, sC, C2), new Triple(C2, sC, C3),
0726: new Triple(a, ty, C1) }, new Triple(a, ty, Node.ANY),
0727: new Object[] { new Triple(a, ty, C1),
0728: new Triple(a, ty, C2), new Triple(a, ty, C3) });
0729: }
0730:
0731: /**
0732: * A problem from the original backchainer tests - RDFS example which threw an NPE
0733: */
0734: public void testProblem6() {
0735: String ruleSrc = "[rdfs9: (?a rdf:type ?y) <- (?x rdfs:subClassOf ?y), (?a rdf:type ?x)]"
0736: + "[restriction2: (?C owl:equivalentClass all(?P, ?D)) <- (?C owl:onProperty ?P), (?C owl:allValuesFrom ?D)]"
0737: + "[rs2: (?X rdf:type all(?P,?C)) <- (?D owl:equivalentClass all(?P,?C)), (?X rdf:type ?D)]"
0738: + "[rp4: (?Y rdf:type ?C) <- (?X rdf:type all(?P, ?C)), (?X ?P ?Y)]";
0739: doTest(ruleSrc, new Node[] { ty, sC,
0740: OWL.equivalentClass.asNode() }, new Triple[] {
0741: new Triple(a, ty, r), new Triple(a, p, b),
0742: new Triple(r, sC, C1),
0743: new Triple(C1, OWL.onProperty.asNode(), p),
0744: new Triple(C1, OWL.allValuesFrom.asNode(), c) },
0745: new Triple(b, ty, c), new Object[] { new Triple(b, ty,
0746: c) });
0747: }
0748:
0749: /**
0750: * A problem from the original backchainer tests - incorrect additional deduction.
0751: * Was due to interpeter setup failing to clone input variables.
0752: */
0753: public void testProblem7() {
0754: String ruleSrc = "[rdfs8: (?a rdfs:subClassOf ?c) <- (?a rdfs:subClassOf ?b), (?b rdfs:subClassOf ?c)]"
0755: + "[rdfs9: (?a rdf:type ?y) <- (?x rdfs:subClassOf ?y), (?a rdf:type ?x)]"
0756: +
0757: // "[(rdf:type rdfs:range rdfs:Class) <-]" +
0758: // "[rdfs3: (?y rdf:type ?c) <- (?x ?p ?y), (?p rdfs:range ?c)]" +
0759: "[rdfs3: (?y rdf:type rdfs:Class) <- (?x rdf:type ?y)]"
0760: + "[rdfs7: (?a rdfs:subClassOf ?a) <- (?a rdf:type rdfs:Class)]";
0761: List rules = Rule.parseRules(ruleSrc);
0762: Node[] tabled = new Node[] { ty, sC };
0763: Triple[] triples = new Triple[] { new Triple(C1, sC, C2),
0764: new Triple(C2, sC, C3), new Triple(a, ty, C1) };
0765: Graph data = Factory.createGraphMem();
0766: for (int i = 0; i < triples.length; i++) {
0767: data.add(triples[i]);
0768: }
0769: InfGraph infgraph = makeInfGraph(rules, data, tabled);
0770: ExtendedIterator it = infgraph.find(a, ty, null);
0771: Triple result = (Triple) it.next();
0772: assertEquals(result.getSubject(), a);
0773: assertEquals(result.getPredicate(), ty);
0774: it.close();
0775: // Make sure if we start again we get the full listing.
0776: TestUtil.assertIteratorValues(this , infgraph.find(a, ty, null),
0777: new Object[] { new Triple(a, ty, C1),
0778: new Triple(a, ty, C2), new Triple(a, ty, C3) });
0779: }
0780:
0781: /**
0782: * A problem from the original backchainer tests - RDFS example which failed.
0783: * Was due to unsupported multi-head statement.
0784: */
0785: public void testProblem8() {
0786: String ruleSrc = "[rdfs9: (?a rdf:type ?y) <- bound(?y) (?x rdfs:subClassOf ?y) (?a rdf:type ?x)]"
0787: + "[restriction4: (?C owl:equivalentClass max(?P, ?X)) <- (?C rdf:type owl:Restriction), (?C owl:onProperty ?P), (?C owl:maxCardinality ?X)]"
0788: + "[restrictionProc11: (?X rdf:type max(?P, 1)) <- (?P rdf:type owl:FunctionalProperty), (?X rdf:type owl:Thing)]"
0789: + "[equivalentClass1: (?Q rdfs:subClassOf ?P) <- (?P owl:equivalentClass ?Q) ]"
0790: + "[equivalentClass1: (?P rdfs:subClassOf ?Q) <- (?P owl:equivalentClass ?Q) ]"
0791: + "[restrictionSubclass1: (?X rdf:type ?D) <- bound(?D) (?D owl:equivalentClass ?R), isFunctor(?R) (?X rdf:type ?R)]";
0792: doTest(ruleSrc, new Node[] { ty, sC,
0793: OWL.equivalentClass.asNode() }, new Triple[] {
0794: new Triple(a, ty, OWL.Thing.asNode()),
0795: new Triple(p, ty, OWL.FunctionalProperty.asNode()),
0796: new Triple(c, OWL.equivalentClass.asNode(), C1),
0797: new Triple(C1, ty, OWL.Restriction.asNode()),
0798: new Triple(C1, OWL.onProperty.asNode(), p),
0799: new Triple(C1, OWL.maxCardinality.asNode(), Util
0800: .makeIntNode(1)), }, new Triple(a, ty, c),
0801: new Object[] { new Triple(a, ty, c) });
0802: }
0803:
0804: /**
0805: * Test derivation machinery
0806: */
0807: public void testRuleDerivations() {
0808: String rules = "[testRule1: (C2, p, ?a) <- (C1 p ?a)]"
0809: + "[testRule2: (C2, q, ?a) <- (C1 q ?a)]"
0810: + "[testRule3: (a p ?a) <- (C2 p ?a), (C2 q ?a)]";
0811: List ruleList = Rule.parseRules(rules);
0812: Graph data = Factory.createGraphMem();
0813: data.add(new Triple(C1, p, C3));
0814: data.add(new Triple(C1, q, C4));
0815: data.add(new Triple(C1, q, C3));
0816: InfGraph infgraph = makeInfGraph(ruleList, data, new Node[] {
0817: p, q });
0818: infgraph.setDerivationLogging(true);
0819:
0820: TestUtil.assertIteratorValues(this , infgraph
0821: .find(a, null, null), new Triple[] { new Triple(a, p,
0822: C3) });
0823:
0824: Iterator derivs = infgraph.getDerivation(new Triple(a, p, C3));
0825: StringWriter outString = new StringWriter(250);
0826: PrintWriter out = new PrintWriter(outString);
0827: while (derivs.hasNext()) {
0828: Derivation d = (Derivation) derivs.next();
0829: d.printTrace(out, true);
0830: }
0831: out.flush();
0832:
0833: String testString = TestUtil
0834: .normalizeWhiteSpace("Rule testRule3 concluded (a p C3) <-\n"
0835: + " Rule testRule1 concluded (C2 p C3) <-\n"
0836: + " Fact (C1 p C3)\r\n"
0837: + " Rule testRule2 concluded (C2 q C3) <-\n"
0838: + " Fact (C1 q C3)\r\n");
0839: assertEquals(testString, TestUtil.normalizeWhiteSpace(outString
0840: .getBuffer().toString()));
0841: }
0842:
0843: /**
0844: * A suspect problem, originally derived from the OWL rules - risk of unbound variables escaping.
0845: * Not managed to isolate or reproduce the problem yet.
0846: */
0847: public void testProblem9() {
0848: String ruleSrc = "[test: (?x owl:sameAs ?x) <- (?x rdf:type owl:Thing) ]"
0849: + "[sameIndividualAs6: (?X rdf:type owl:Thing) <- (?X owl:sameAs ?Y) ]"
0850: + "[ans: (?x p C1) <- (?y owl:sameAs ?x)]";
0851: Node sI = OWL.sameAs.asNode();
0852: doTest(ruleSrc, new Node[] { ty, sI }, // Tabled predicates
0853: new Triple[] { // init data
0854: new Triple(a, ty, OWL.Thing.asNode()),
0855: new Triple(b, sI, c), }, new Triple(Node.ANY,
0856: p, Node.ANY), // query
0857: new Object[] { // result
0858: new Triple(a, p, C1), new Triple(b, p, C1),
0859: new Triple(c, p, C1), });
0860: // new Triple(Node.ANY, ty, Node.ANY), // query
0861: // new Object[] { // result
0862: // new Triple(a, ty, OWL.Thing.asNode()),
0863: // new Triple(b, ty, OWL.Thing.asNode())
0864: // } );
0865: }
0866:
0867: /**
0868: * Test 3-arg builtins such as arithmetic.
0869: */
0870: public void testArithBuiltins() {
0871: doBuiltinTest(
0872: "[(a,r,0) <- (a,p,?x), (a,q,?y), lessThan(?x,?y)]"
0873: + "[(a,r,1) <- (a,p,?x), (a,q,?y), ge(?x, ?y)]",
0874: Util.makeIntNode(2), Util.makeIntNode(3), Util
0875: .makeIntNode(0));
0876: doBuiltinTest(
0877: "[(a,r,0) <- (a,p,?x), (a,q,?y), lessThan(?x,?y)]"
0878: + "[(a,r,1) <- (a,p,?x), (a,q,?y), ge(?x, ?y)]",
0879: Util.makeIntNode(3), Util.makeIntNode(3), Util
0880: .makeIntNode(1));
0881: doBuiltinTest(
0882: "[(a,r,0) <- (a,p,?x), (a,q,?y), le(?x,?y)]"
0883: + "[(a,r,1) <- (a,p,?x), (a,q,?y), greaterThan(?x, ?y)]",
0884: Util.makeIntNode(3), Util.makeIntNode(3), Util
0885: .makeIntNode(0));
0886: doBuiltinTest(
0887: "[(a,r,?z) <- (a,p,?x), (a,q,?y), min(?x,?y,?z)]", Util
0888: .makeIntNode(2), Util.makeIntNode(3), Util
0889: .makeIntNode(2));
0890: doBuiltinTest(
0891: "[(a,r,?z) <- (a,p,?x), (a,q,?y), min(?x,?y,?z)]", Util
0892: .makeIntNode(4), Util.makeIntNode(3), Util
0893: .makeIntNode(3));
0894: doBuiltinTest(
0895: "[(a,r,?z) <- (a,p,?x), (a,q,?y), max(?x,?y,?z)]", Util
0896: .makeIntNode(2), Util.makeIntNode(3), Util
0897: .makeIntNode(3));
0898: doBuiltinTest(
0899: "[(a,r,?z) <- (a,p,?x), (a,q,?y), max(?x,?y,?z)]", Util
0900: .makeIntNode(4), Util.makeIntNode(3), Util
0901: .makeIntNode(4));
0902: }
0903:
0904: /**
0905: * Test the temporary list builtins
0906: */
0907: public void testListBuiltins() {
0908: String ruleSrc = "[(a r ?n) <- (a p ?l), listLength(?l, ?n)]"
0909: + "[(a s ?e) <- (a p ?l), listEntry(?l, 1, ?e)]";
0910: List rules = Rule.parseRules(ruleSrc);
0911: Graph data = Factory.createGraphMem();
0912: data.add(new Triple(a, p, Util.makeList(
0913: new Node[] { C1, C2, C3 }, data)));
0914: InfGraph infgraph = makeInfGraph(rules, data);
0915: TestUtil.assertIteratorValues(this , infgraph.find(new Triple(a,
0916: r, Node.ANY)), new Triple[] { new Triple(a, r, Util
0917: .makeIntNode(3)) });
0918: TestUtil.assertIteratorValues(this , infgraph.find(new Triple(a,
0919: s, Node.ANY)), new Triple[] { new Triple(a, s, C2) });
0920:
0921: rules = Rule
0922: .parseRules("[(a s b) <- (a p ?l), (a, q, ?j) listEqual(?l, ?j)]"
0923: + "[(a s c) <- (a p ?l), (a, q, ?j) listNotEqual(?l, ?j)]"
0924: + "[(a s d) <- (a p ?l), (a, r, ?j) listEqual(?l, ?j)]"
0925: + "[(a s e) <- (a p ?l), (a, r, ?j) listNotEqual(?l, ?j)]");
0926: data = Factory.createGraphMem();
0927: data.add(new Triple(a, p, Util.makeList(new Node[] { C1,
0928: Util.makeIntNode(3), C3 }, data)));
0929: data.add(new Triple(a, q, Util.makeList(new Node[] { C3, C1,
0930: Util.makeLongNode(3) }, data)));
0931: data.add(new Triple(a, r, Util.makeList(new Node[] { C3, C1,
0932: Util.makeLongNode(2) }, data)));
0933: infgraph = makeInfGraph(rules, data);
0934: TestUtil.assertIteratorValues(this , infgraph.find(new Triple(a,
0935: s, Node.ANY)), new Triple[] { new Triple(a, s, b),
0936: new Triple(a, s, e), });
0937:
0938: rules = Rule
0939: .parseRules("[(b r ?j) <- (a p ?l), (a, q, ?j) listContains(?l, ?j)]"
0940: + "[(b s ?j) <- (a p ?l), (a, q, ?j) listNotContains(?l, ?j)]");
0941: data = Factory.createGraphMem();
0942: data.add(new Triple(a, p, Util.makeList(new Node[] { C1,
0943: Util.makeIntNode(3), C3 }, data)));
0944: data.add(new Triple(a, q, C1));
0945: data.add(new Triple(a, q, Util.makeLongNode(3)));
0946: ;
0947: data.add(new Triple(a, q, C2));
0948: infgraph = makeInfGraph(rules, data);
0949: TestUtil.assertIteratorValues(this , infgraph.find(new Triple(b,
0950: Node.ANY, Node.ANY)), new Triple[] {
0951: new Triple(b, r, C1),
0952: new Triple(b, r, Util.makeIntNode(3)),
0953: new Triple(b, s, C2), });
0954: }
0955:
0956: /**
0957: * Test that we detect concurrent modification of LP graphs with
0958: * non-closed iterators.
0959: */
0960: public void testCME() {
0961: String ruleSrc = "(?a p 1) <- (?a p 0). (?a p 2) <- (?a p 0).";
0962: List rules = Rule.parseRules(ruleSrc);
0963: Graph data = Factory.createGraphMem();
0964: data.add(new Triple(a, p, Util.makeIntNode(0)));
0965: InfGraph infgraph = makeInfGraph(rules, data);
0966:
0967: // Check the base case works
0968: TestUtil.assertIteratorValues(this , infgraph.find(new Triple(a,
0969: p, Node.ANY)), new Triple[] {
0970: new Triple(a, p, Util.makeIntNode(0)),
0971: new Triple(a, p, Util.makeIntNode(1)),
0972: new Triple(a, p, Util.makeIntNode(2)), });
0973:
0974: // Now force a CME
0975: boolean ok = false;
0976: ExtendedIterator i = infgraph.find(new Triple(a, p, Node.ANY));
0977: try {
0978: i.next();
0979: infgraph.add(new Triple(a, p, Util.makeIntNode(4)));
0980: i.next();
0981: } catch (ConcurrentModificationException e) {
0982: ok = true;
0983: } finally {
0984: i.close();
0985: }
0986: assertTrue("Expect CME on unclosed iterators", ok);
0987: }
0988:
0989: /**
0990: * Generic test operation.
0991: * @param ruleSrc the source of the rules
0992: * @param triples a set of triples to insert in the graph before the query
0993: * @param query the TripleMatch to search for
0994: * @param results the array of expected results
0995: */
0996: private void doTest(String ruleSrc, Triple[] triples,
0997: TripleMatch query, Object[] results) {
0998: List rules = Rule.parseRules(ruleSrc);
0999: Graph data = Factory.createGraphMem();
1000: for (int i = 0; i < triples.length; i++) {
1001: data.add(triples[i]);
1002: }
1003: InfGraph infgraph = makeInfGraph(rules, data);
1004: TestUtil.assertIteratorValues(this , infgraph.find(query),
1005: results);
1006: }
1007:
1008: /**
1009: * Generic test operation.
1010: * @param ruleSrc the source of the rules
1011: * @param tabled the predicates that should be tabled
1012: * @param triples a set of triples to insert in the graph before the query
1013: * @param query the TripleMatch to search for
1014: * @param results the array of expected results
1015: */
1016: private void doTest(String ruleSrc, Node[] tabled,
1017: Triple[] triples, TripleMatch query, Object[] results) {
1018: List rules = Rule.parseRules(ruleSrc);
1019: Graph data = Factory.createGraphMem();
1020: for (int i = 0; i < triples.length; i++) {
1021: data.add(triples[i]);
1022: }
1023: InfGraph infgraph = makeInfGraph(rules, data, tabled);
1024: TestUtil.assertIteratorValues(this , infgraph.find(query),
1025: results);
1026:
1027: }
1028:
1029: /**
1030: * Generic base test operation on a graph with the single triple (a, p, b)
1031: * @param ruleSrc the source of the rules
1032: * @param query the TripleMatch to search for
1033: * @param results the array of expected results
1034: */
1035: private void doBasicTest(String ruleSrc, TripleMatch query,
1036: Object[] results) {
1037: doTest(ruleSrc, new Triple[] { new Triple(a, p, b) }, query,
1038: results);
1039: }
1040:
1041: /**
1042: * Generic test operation.
1043: * @param rule to test a simple builtin operation
1044: * @param param1 value to bind to first parameter by (a,p,_)
1045: * @param param2 value to bind to first parameter by (a,q,_)
1046: * @param result the expected result to be found by (a,r,_)
1047: */
1048: private void doBuiltinTest(String ruleSrc, Node param1,
1049: Node param2, Node result) {
1050: doTest(ruleSrc, new Triple[] { new Triple(a, p, param1),
1051: new Triple(a, q, param2) }, new Triple(a, r, Node.ANY),
1052: new Triple[] { new Triple(a, r, result) });
1053: }
1054:
1055: }
1056:
1057: /*
1058: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
1059: All rights reserved.
1060:
1061: Redistribution and use in source and binary forms, with or without
1062: modification, are permitted provided that the following conditions
1063: are met:
1064:
1065: 1. Redistributions of source code must retain the above copyright
1066: notice, this list of conditions and the following disclaimer.
1067:
1068: 2. Redistributions in binary form must reproduce the above copyright
1069: notice, this list of conditions and the following disclaimer in the
1070: documentation and/or other materials provided with the distribution.
1071:
1072: 3. The name of the author may not be used to endorse or promote products
1073: derived from this software without specific prior written permission.
1074:
1075: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1076: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1077: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1078: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1079: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1080: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1081: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1082: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1083: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1084: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1085: */
|