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: package test.org.mandarax.performance;
019:
020: import java.io.PrintStream;
021:
022: import org.apache.log4j.Level;
023: import org.mandarax.kernel.Fact;
024: import org.mandarax.kernel.InferenceEngine;
025: import org.mandarax.kernel.InferenceException;
026: import org.mandarax.kernel.Predicate;
027: import org.mandarax.kernel.Query;
028: import org.mandarax.kernel.ResultSet;
029: import org.mandarax.kernel.SimplePredicate;
030: import org.mandarax.kernel.Term;
031: import org.mandarax.reference.AdvancedKnowledgeBase;
032: import org.mandarax.reference.ResolutionInferenceEngine;
033: import org.mandarax.util.LogicFactorySupport;
034:
035: /**
036: * Performance test based on a binary tree of a certain depth.
037: * The number of clauses in the kb is SUM(i=1..DEPTH)2^i + 2^N
038: * @author <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</A>
039: * @version 3.4 <7 March 05>
040: * @since 2.1
041: */
042: public class PerformanceTest1 implements PerformanceTest {
043: public static final String QUERY_VARIABLE = "query_var";
044: private int depth = 5;
045: private int numberOfResults = -1;
046: private long time = -1;
047: protected org.mandarax.kernel.KnowledgeBase kb = new AdvancedKnowledgeBase();
048: protected static LogicFactorySupport lfs = new LogicFactorySupport();
049: protected static Class[] STRUCTURE = { String.class };
050: protected static final Term VAR = lfs.variable("x", String.class);
051:
052: /**
053: * Constructor.
054: */
055: public PerformanceTest1() {
056: super ();
057: initialize();
058: }
059:
060: /**
061: * Constructor.
062: * @param depth the kb tree depth
063: */
064: public PerformanceTest1(int depth) {
065: super ();
066: this .depth = depth;
067: initialize();
068: }
069:
070: /**
071: * Run a performance test.
072: */
073: public static void main(String args[]) {
074: PerformanceTest1 test = new PerformanceTest1();
075: test.run(new ResolutionInferenceEngine(), true, true,
076: System.out);
077: }
078:
079: /**
080: * Initialize the knowledge base.
081: */
082: private void initialize() {
083: initialize(0, getRootPredicate());
084: System.out.println("Performance test initialized");
085: }
086:
087: /**
088: * Initialize the knowledge base on a certain hierarchy level.
089: * @param level the hierarchy level
090: * @param p a predicate
091: */
092: private void initialize(int level, Predicate p) {
093: if (level < depth) {
094: Predicate p1 = buildNextPredicate(p, true);
095: Predicate p2 = buildNextPredicate(p, true);
096: // left branch
097: kb.add(lfs.rule(lfs.prereq(p1, VAR), lfs.fact(p, VAR)));
098: initialize(level + 1, p1);
099: // right branch
100: kb.add(lfs.rule(lfs.prereq(p2, VAR), lfs.fact(p, VAR)));
101: initialize(level + 1, p2);
102: } else {
103: // terminate tree with fact
104: kb.add(lfs.fact(p, lfs.cons(p.getName().replace('p', 'c'),
105: String.class)));
106: }
107: }
108:
109: /**
110: * Get the next predicate.
111: * @param p the previous predicate
112: * @param boolean true for the first child node, false for the second one
113: * @return the next child predicate
114: */
115: private Predicate buildNextPredicate(Predicate p, boolean first) {
116: String name = p.getName() + (first ? "0" : "1");
117: return new SimplePredicate(name, STRUCTURE);
118: }
119:
120: /**
121: * Get the root predicate.
122: * @return the root predicate
123: */
124: private Predicate getRootPredicate() {
125: return new SimplePredicate("p", STRUCTURE);
126: }
127:
128: /**
129: * Run the test.
130: * Run the test.
131: * @param ie the inference engine to be tested
132: * @param one whether to return only one result, or all results
133: * @param logOn whether to log or not
134: * @param out print stream used to output a test summary
135: */
136: public synchronized void run(InferenceEngine ie, boolean one,
137: boolean logOn, PrintStream out) {
138:
139: Fact queryFact = lfs.fact(getRootPredicate(), lfs.variable(
140: QUERY_VARIABLE, String.class));
141: Query query = lfs.query(queryFact, "?");
142: if (ie instanceof ResolutionInferenceEngine)
143: ((ResolutionInferenceEngine) ie).setMaxSteps(100000);
144: // logs
145: if (logOn) {
146: org.apache.log4j.Category.getRoot().setLevel(Level.INFO);
147: } else {
148: org.apache.log4j.Category.getRoot().setLevel(Level.WARN);
149: }
150:
151: // query
152: try {
153: long before = System.currentTimeMillis();
154: ResultSet rs = ie.query(query, kb,
155: one ? InferenceEngine.ONE : InferenceEngine.ALL,
156: InferenceEngine.BUBBLE_EXCEPTIONS);
157: long after = System.currentTimeMillis();
158: // count results
159: int solutions = 0;
160: while (rs.next()) {
161: solutions = solutions + 1;
162: }
163: numberOfResults = solutions;
164:
165: // report
166: out.println("Inference engine performance test");
167: out.println("ie tested: " + ie);
168: out.println("kb tree depth: " + depth);
169: out.println("kb size: " + kb.getClauseSets().size());
170: out.println("results wanted: " + (one ? "one" : "all"));
171: out.println("logs on: " + logOn);
172: out.println("solutions found: " + solutions);
173: out.println("time (in millis): " + (after - before));
174: out.println();
175:
176: time = after - before;
177:
178: } catch (InferenceException x) {
179: x.printStackTrace();
180: time = -1;
181: }
182:
183: }
184:
185: /**
186: * Get the size of the knowledge base used.
187: * @return the kb size
188: */
189: public synchronized int getKBSize() {
190: return kb.getClauseSets().size();
191: }
192:
193: /**
194: * Release the test.
195: */
196: public synchronized void release() {
197: time = 0;
198: numberOfResults = -1;
199: }
200:
201: /**
202: * Get the time needed to run the test.
203: * @param a long value (the millis)
204: */
205: public synchronized long getTime() {
206: return time;
207: }
208:
209: /**
210: * Get the number of results computed.
211: * @param the number of results
212: */
213: public synchronized int getNumberOfResults() {
214: return numberOfResults;
215: }
216:
217: /**
218: * Get the tree depth (if kb is organized as tree, otherwise just return -1).
219: * @return the depth of the kb tree
220: */
221: public synchronized int getDepth() {
222: return depth;
223: }
224:
225: }
|