001: /*
002: * Copyright (C) 1999-2004 <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</a>
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018:
019: package test.org.mandarax.reference;
020:
021: import java.util.Iterator;
022: import org.mandarax.kernel.*;
023: import org.mandarax.lib.math.IntArithmetic;
024: import org.mandarax.reference.AbstractResolutionInferenceEngine;
025: import org.mandarax.util.LogicFactorySupport;
026:
027: /**
028: * Test recursion. Uses the factorial example.
029: * In particular, we test whether terms are simplified using semantic evaluation
030: * within the scope of a simple predicate.
031: * @author <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</A>
032: * @version 3.4 <7 March 05>
033: * @since 3.3
034: */
035: public class TestRecursion1 extends MandaraxTestCase {
036: private KnowledgeBase kb = null;
037: private InferenceEngine ie = null;
038: private Predicate p = null;
039:
040: /**
041: * Constructor.
042: * @param testName the name of the test
043: */
044: public TestRecursion1(String testName,
045: KnowledgeBase aKnowledgeBase,
046: InferenceEngine anInferenceEngine) {
047: super (testName);
048: kb = aKnowledgeBase;
049: ie = anInferenceEngine;
050: }
051:
052: /**
053: * Set up the test case.
054: */
055: public void setUp() throws Exception {
056: super .setUp();
057:
058: //BasicConfigurator.configure();
059: //Logger.getRoot().setLevel(Level.DEBUG);
060:
061: // init kb
062: // the order does matter, but problems can be avoided by setting the appropriate kb comparator,
063: // or by adding another prereq to the rule
064: LogicFactorySupport lfs = new LogicFactorySupport();
065: p = new SimplePredicate("factorial", new Class[] {
066: Integer.class, Integer.class });
067: // fact factorial(1,1)
068: Fact f = lfs.fact(p, new Integer(1), new Integer(1));
069: kb.add(f);
070: // rule if factorial(n-1,k) then factorial(n,n*k)
071: Rule r = lfs.rule(lfs.prereq(p, lfs.cplx(IntArithmetic.MINUS,
072: lfs.variable("n", Integer.class), new Integer(1)), lfs
073: .variable("k", Integer.class)), lfs.fact(p, lfs
074: .variable("n", Integer.class), lfs.cplx(
075: IntArithmetic.TIMES, lfs.variable("n", Integer.class),
076: lfs.variable("k", Integer.class))));
077: kb.add(r);
078:
079: LOG_TEST.debug("Setup test case " + this );
080: LOG_TEST.debug("kb contains:");
081: for (Iterator iter = kb.getClauseSets().iterator(); iter
082: .hasNext();) {
083: LOG_TEST.debug(iter.next().toString());
084: }
085: }
086:
087: /**
088: * Build a query for a certain number.
089: * @param i
090: * @return a query
091: */
092: private Query buildQuery(int i) {
093: LogicFactorySupport lfs = new LogicFactorySupport();
094: // query ? factorial(i,i)
095: Query q = lfs.query(lfs.fact(p, new Integer(i), lfs.variable(
096: "x", Integer.class)), "?factorial(" + i + ")");
097: LOG_TEST.debug("Query is : " + q.getFacts()[0]);
098: return q;
099: }
100:
101: /**
102: * Private test method.
103: * @param i a number
104: */
105: private void test(int i) throws Exception {
106: // this number of steps should be sufficient
107: if (ie instanceof AbstractResolutionInferenceEngine)
108: ((AbstractResolutionInferenceEngine) ie).setMaxSteps(100);
109:
110: Query q = buildQuery(i);
111: ResultSet rs = ie.query(q, kb, InferenceEngine.ONE,
112: InferenceEngine.BUBBLE_EXCEPTIONS);
113: rs.next();
114: int computed = ((Integer) rs.getResult(Integer.class, "x"))
115: .intValue();
116: int expected = factorial(i);
117: rs.close();
118: assertTrue(computed == expected);
119: }
120:
121: /**
122: * Compute the factorial for a certain number.
123: * @param i a number
124: * @return the factorial of this number
125: */
126: private int factorial(int i) {
127: if (i == 0)
128: return 1;
129: else
130: return i * factorial(i - 1);
131: }
132:
133: /**
134: * Test method.
135: */
136: public void test1() throws Exception {
137: test(1);
138: }
139:
140: /**
141: * Test method.
142: */
143: public void test2() throws Exception {
144: test(2);
145: }
146:
147: /**
148: * Test method.
149: */
150: public void test3() throws Exception {
151: test(3);
152: }
153:
154: /**
155: * Test method.
156: */
157: public void test4() throws Exception {
158: test(4);
159: }
160:
161: /**
162: * Test method.
163: */
164: public void test5() throws Exception {
165: test(5);
166: }
167:
168: /**
169: * Test method.
170: */
171: public void test6() throws Exception {
172: test(10);
173: }
174:
175: /**
176: * Test method.
177: */
178: public void test7() throws Exception {
179: test(30);
180: }
181: }
|