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.reference;
019:
020: import java.lang.reflect.Method;
021: import java.util.Hashtable;
022: import java.util.Vector;
023:
024: import org.mandarax.kernel.Fact;
025: import org.mandarax.kernel.Function;
026: import org.mandarax.kernel.LogicFactory;
027: import org.mandarax.kernel.Query;
028: import org.mandarax.kernel.Rule;
029: import org.mandarax.kernel.Term;
030: import org.mandarax.kernel.meta.JFunction;
031: import org.mandarax.kernel.meta.JPredicate;
032:
033: /**
034: * Test class providing a domain model for the test cases.
035: * @author <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</A>
036: * @version 3.4 <7 March 05>
037: * @since 1.1
038: */
039: public class Person extends org.mandarax.kernel.LObject {
040:
041: private static Hashtable instances = new Hashtable();
042: private String name = null;
043: private static String[] varNames = { "x", "y", "z", "u", "v" };
044: private static String[] functionNames = { "father", "son" };
045: private static LogicFactory logicFactory = LogicFactory
046: .getDefaultFactory();
047:
048: /**
049: * Constructor.
050: */
051: public Person() {
052: super ();
053: }
054:
055: /**
056: * Constructor.
057: * @param n the name of the person
058: */
059: public Person(String n) {
060: super ();
061:
062: name = n;
063: }
064:
065: /**
066: * Indicates whether the object equals the receiver.
067: * @param obj the object to compare this object with
068: * @return true if the objects are equal, false otherwise
069: */
070: public boolean equals(Object obj) {
071: if (obj instanceof Person) {
072: Person p = (Person) obj;
073:
074: if (p.name == null) {
075: return name == null;
076: } else {
077: return p.name.equals(name);
078: }
079: }
080:
081: return false;
082: }
083:
084: /**
085: * Indicates whether the object does not equal the receiver.
086: * @param obj the object to compare this object with
087: * @return false if the objects are equal, true otherwise
088: */
089: public boolean equalsNot(Object obj) {
090: return !equals(obj);
091: }
092:
093: /**
094: * Get the father of this person.
095: * @return the instance representing the father of this object
096: */
097: public Person father() {
098: if (name.equals("Max")) {
099: return get("Jens");
100: }
101:
102: if (name.equals("Jens")) {
103: return get("Klaus");
104: }
105:
106: if (name.equals("Sabine")) {
107: return get("Klaus");
108: }
109:
110: if (name.equals("Klaus")) {
111: return get("Otto");
112: }
113:
114: if (name.equals("Lutz")) {
115: return get("Otto");
116: }
117:
118: if (name.equals("Frank")) {
119: return get("Lutz");
120: }
121:
122: if (name.equals("Ralf")) {
123: return get("Lutz");
124: }
125:
126: return null;
127: }
128:
129: /**
130: * Get the person with the name.
131: * @return an instance
132: * @param n a name
133: */
134: public static Person get(String n) {
135: Person p = (Person) instances.get(n);
136:
137: if (p == null) {
138: p = new Person(n);
139:
140: instances.put(n, p);
141: }
142:
143: return p;
144: }
145:
146: /**
147: * Build a complex term from a string.
148: * @return a complex term
149: * @param n the string representing the term
150: * @param functName the name of the function
151: */
152: static Term getComplexTerm(String n, String functName) {
153: try {
154: Method meth = Person.class.getMethod(functName,
155: new Class[0]);
156: Term innerTerm = getTerm(n.substring(
157: functName.length() + 1, n.length() - 1));
158: Term[] innerTerms = new Term[1];
159:
160: innerTerms[0] = innerTerm;
161:
162: Function funct = new JFunction(meth);
163:
164: return logicFactory.createComplexTerm(funct, innerTerms);
165: } catch (Throwable t) {
166: System.out.println("Error building complex term from " + n);
167: }
168:
169: return null;
170: }
171:
172: /**
173: * Get a constant with the provided name.
174: * @return a constant term
175: * @param n the name of the person that will be wrapped by the term
176: */
177: static Term getConstant(String n) {
178: return logicFactory.createConstantTerm(get(n));
179: }
180:
181: /**
182: * Get a fact.
183: * @return a fact
184: * @param predicate the string representation of the predicate
185: * @param name1 the string representation of the first term
186: * @param name2 the string representation of the second term
187: */
188: public static Fact getFact(String predicate, String name1,
189: String name2) {
190: try {
191: Term[] t = new Term[2];
192: t[0] = getTerm(name1);
193: t[1] = getTerm(name2);
194:
195: return logicFactory.createFact(new JPredicate(
196: getPredicate(predicate)), t);
197: } catch (Throwable t) {
198: return null;
199: }
200: }
201:
202: /**
203: * Get a query.
204: * @return a query
205: * @param predicate the string representation of the predicate
206: * @param name1 the string representation of the first term
207: * @param name2 the string representation of the second term
208: */
209: public static Query getQuery(String predicate, String name1,
210: String name2) {
211: Fact fact = getFact(predicate, name1, name2);
212: if (fact == null)
213: return null;
214: else
215: return logicFactory.createQuery(fact, "a query");
216: }
217:
218: /**
219: * Get the name.
220: * @return the name of the person
221: */
222: public String getName() {
223: return name;
224: }
225:
226: /**
227: * Get a type one method with one parameter.
228: * @return a java method
229: * @param name the string representation of the predicate
230: */
231: static Method getPredicate(String name) {
232: if (name.equals("equals")) {
233: return getPredicate(name, Object.class);
234: }
235:
236: if (name.equals("equalsNot")) {
237: return getPredicate(name, Object.class);
238: }
239:
240: return getPredicate(name, Person.class);
241: }
242:
243: /**
244: * Get a type one method with one parameter (of the type specified).
245: * @return a method
246: * @param name the string representation of the predicate
247: * @param parType the type of the parameter
248: */
249: static Method getPredicate(String name, Class parType) {
250: try {
251: Class[] par = new Class[1];
252:
253: par[0] = parType;
254:
255: return Person.class.getMethod(name, par);
256: } catch (Throwable t) {
257: System.out.println(t.getMessage());
258:
259: return null;
260: }
261: }
262:
263: /**
264: * Build a rule.
265: * @return a rule
266: * @param headPredicate the string representation of the head predicate
267: * @param headName1 the string representation of a term
268: * @param headName2 the string representation of a term
269: * @param bodyPredicate the string representation of the predicate of the first (and only) fact in the body
270: * @param bodyName1 the string representation of a term
271: * @param bodyName2 the string representation of a term
272: */
273: public static Rule getRule(String headPredicate, String headName1,
274: String headName2, String bodyPredicate, String bodyName1,
275: String bodyName2) {
276: Fact head = getFact(headPredicate, headName1, headName2);
277: Vector body = new Vector();
278:
279: body.addElement(getFact(bodyPredicate, bodyName1, bodyName2));
280:
281: return logicFactory.createRule(body, head);
282: }
283:
284: /**
285: * Build a rule.
286: * @return a rule
287: * @param headPredicate the string representation of the head predicate
288: * @param headName1 the string representation of a term
289: * @param headName2 the string representation of a term
290: * @param bodyPredicate1 the string representation of the predicate of the first fact in the body
291: * @param bodyName11 the string representation of a term
292: * @param bodyName12 the string representation of a term
293: * @param bodyPredicate2 the string representation of the predicate of the second fact in the body
294: * @param bodyName21 the string representation of a term
295: * @param bodyName22 the string representation of a term
296: */
297: public static Rule getRule(String headPredicate, String headName1,
298: String headName2, String bodyPredicate1, String bodyName11,
299: String bodyName12, String bodyPredicate2,
300: String bodyName21, String bodyName22) {
301: Fact head = getFact(headPredicate, headName1, headName2);
302: Vector body = new Vector();
303:
304: body
305: .addElement(getFact(bodyPredicate1, bodyName11,
306: bodyName12));
307: body
308: .addElement(getFact(bodyPredicate2, bodyName21,
309: bodyName22));
310:
311: return logicFactory.createRule(body, head);
312: }
313:
314: /**
315: * Build a rule.
316: * @return a rule
317: * @param headPredicate the string representation of the head predicate
318: * @param headName1 the string representation of a term
319: * @param headName2 the string representation of a term
320: * @param bodyPredicate1 the string representation of the predicate of the first fact in the body
321: * @param bodyName11 the string representation of a term
322: * @param bodyName12 the string representation of a term
323: * @param bodyPredicate2 the string representation of the predicate of the second fact in the body
324: * @param bodyName21 the string representation of a term
325: * @param bodyName22 the string representation of a term
326: * @param bodyPredicate3 the string representation of the predicate of the third fact in the body
327: * @param bodyName31 the string representation of a term
328: * @param bodyName32 the string representation of a term
329: */
330: public static Rule getRule(String headPredicate, String headName1,
331: String headName2, String bodyPredicate1, String bodyName11,
332: String bodyName12, String bodyPredicate2,
333: String bodyName21, String bodyName22,
334: String bodyPredicate3, String bodyName31, String bodyName32) {
335: Fact head = getFact(headPredicate, headName1, headName2);
336: Vector body = new Vector();
337:
338: body
339: .addElement(getFact(bodyPredicate1, bodyName11,
340: bodyName12));
341: body
342: .addElement(getFact(bodyPredicate2, bodyName21,
343: bodyName22));
344: body
345: .addElement(getFact(bodyPredicate3, bodyName31,
346: bodyName32));
347:
348: return logicFactory.createRule(body, head);
349: }
350:
351: /**
352: * Get the term with the name.
353: * We build a variable if the string is one of the registered variable names.
354: * We build a function if the string is one of the registered function names followed by
355: * a string in brackets. Otherwise we build a constant.
356: * @return a term
357: * @param n the string representation of a term
358: */
359: public static Term getTerm(String n) {
360:
361: // first check whether the string is a variable
362: for (int i = 0; i < varNames.length; i++) {
363: if (varNames[i].equals(n)) {
364: return getVariable(n);
365: }
366: }
367:
368: // next check whether the string is a function
369: for (int i = 0; i < functionNames.length; i++) {
370: if (n.startsWith(functionNames[i] + "(") && n.endsWith(")")) {
371: return getComplexTerm(n, functionNames[i]);
372: }
373: }
374:
375: // otherwise the string is interpreted as a constant name
376: return getConstant(n);
377: }
378:
379: /**
380: * Get a variable with the provided name.
381: * @return a variable term
382: * @param x the variable name
383: */
384: public static Term getVariable(String x) {
385: return logicFactory.createVariableTerm(x, Person.class);
386: }
387:
388: /**
389: * Get the hash code of the object.
390: * @return the hash value
391: */
392: public int hashCode() {
393: if (name == null) {
394: return 0;
395: } else {
396: return name.hashCode();
397: }
398: }
399:
400: /**
401: * Method used to build a test predicate .
402: * @see org.mandarax.kernel.meta.JPredicate
403: * @return true if p represents the brother of this instance
404: * @param p another person
405: */
406: public boolean isBrotherOf(Person p) {
407: return false;
408: }
409:
410: /**
411: * Method used to build a test predicate .
412: * @see org.mandarax.kernel.meta.JPredicate
413: * @param p another person
414: */
415: public boolean isFatherOf(Person p) {
416: return false;
417: }
418:
419: /**
420: * Method used to build a test predicate .
421: * @see org.mandarax.kernel.meta.JPredicate
422: * @param p another person
423: */
424: public boolean isGrandFatherOf(Person p) {
425: return false;
426: }
427:
428: /**
429: * Method used to build a test predicate .
430: * @see org.mandarax.kernel.meta.JPredicate
431: * @param p another person
432: */
433: public boolean isOncleOf(Person p) {
434: return false;
435: }
436:
437: /**
438: * Method used to build a test predicate .
439: * @see org.mandarax.kernel.meta.JPredicate
440: * @param p another person
441: */
442: public boolean isRelativeOf(Person p) {
443: return false;
444: }
445:
446: /**
447: * Method used to build a test predicate .
448: * @see org.mandarax.kernel.meta.JPredicate
449: * @param p another person
450: */
451: public boolean isSonOf(Person p) {
452: return false;
453: }
454:
455: /**
456: * Get the son of this person.
457: * @return the instance representing the son of this object
458: */
459: public Person son() {
460: if (name.equals("Jens")) {
461: return get("Max");
462: }
463:
464: if (name.equals("Klaus")) {
465: return get("Jens");
466: }
467:
468: if (name.equals("Otto")) {
469: return get("Klaus");
470: }
471:
472: return null;
473: }
474:
475: /**
476: * Convert the receiver to a string.
477: * @return the string representation of this object
478: */
479: public String toString() {
480: return name;
481: }
482: }
|