001: package org.ofbiz.rules.engine;
002:
003: /**
004: * <p><b>Title:</b> Fact
005: * <p><b>Description:</b> None
006: * <p>Copyright (c) 1999 Steven J. Metsker.
007: * <p>Copyright (c) 2001 The Open For Business Project - www.ofbiz.org
008: *
009: * <p>Permission is hereby granted, free of charge, to any person obtaining a
010: * copy of this software and associated documentation files (the "Software"),
011: * to deal in the Software without restriction, including without limitation
012: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
013: * and/or sell copies of the Software, and to permit persons to whom the
014: * Software is furnished to do so, subject to the following conditions:
015: *
016: * <p>The above copyright notice and this permission notice shall be included
017: * in all copies or substantial portions of the Software.
018: *
019: * <p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
020: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
021: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
022: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
023: * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
024: * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
025: * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
026: *
027: * <br>
028: * <p>A Fact is a Structure that contains only other Facts.
029: * <p>
030: * For example,
031: * <blockquote><pre>
032: * Fact s = new Fact(
033: * "starred",
034: * new Fact[]{
035: * new Fact("James Cagney"),
036: * new Fact("Yankee Doodle Dandy")});
037: * </pre></blockquote>
038: * The Fact class offers several convenience constructors. For
039: * example, you can create an identical fact with:
040: *
041: * <blockquote><pre>
042: * Fact s = new Fact(
043: * "starred", "James Cagney", "Yankee Doodle Dandy");
044: * </pre></blockquote>
045: * or with:
046: * <blockquote><pre>
047: * Fact s = new Fact(
048: * "starred",
049: * new Object[]{
050: * "James Cagney", "Yankee Doodle Dandy"});
051: * </pre></blockquote>
052: * Since they do not contain variables, Facts do not need to
053: * copy themselves when they provide a "copy" for a proof.
054: * They also avoid copying when then provide a dynamic
055: * axiom.
056: *
057: * @author Steven J. Metsker
058: * @version 1.0
059: */
060: public class Fact extends Structure implements Axiom, DynamicAxiom {
061:
062: /**
063: * With facts, there is nothing beyond the fact itself to
064: * prove; there is nothing to resolve.
065: */
066: protected static final DynamicRule resolvent = new DynamicRule(
067: null, null, new Structure[0]);
068:
069: /**
070: * Contructs a fact from the specified object.
071: *
072: * @param Object the functor for this fact
073: */
074: public Fact(Object functor) {
075: this (functor, new Fact[0]);
076: }
077:
078: /**
079: * Constructs a fact with the specified functor, and with
080: * terms that are atoms wrapped around the supplied
081: * objects.
082: *
083: * @param Object the functor of the structure
084: *
085: * @param Object[] the objects to convert into atoms
086: * and use as the terms of this fact
087: *
088: */
089: public Fact(Object functor, Object[] objects) {
090: super (functor, facts(objects));
091: }
092:
093: /**
094: * Constructs a fact with the specified functor and facts.
095: *
096: * @param Object the functor of the structure
097: *
098: * @param Term[] the terms of this fact, which can only
099: * be other facts
100: */
101: public Fact(Object functor, Fact[] terms) {
102: super (functor, terms);
103: }
104:
105: /**
106: * Although "public", this method is not for public use.
107: * <p>
108: * Without this constructor, or if this constructor were
109: * private,
110: *
111: * <blockquote><pre>
112: * new Fact(
113: * "starred",
114: * new Term[]{new Fact("Cagney", "Yankee Doodle Dandy")})
115: * </pre></blockquote>
116: *
117: * would match the signature on <code>Fact(Object, Object[])
118: * </code>, which is not what we want. This would wrap each
119: * fact in another fact.
120: * <p>
121: * Allowing this constructor gives the appearance of allowing
122: * Facts with any kind of terms, including variables, which
123: * are verboten.
124: *
125: * @exception RuntimeException Cannot construct a fact from
126: * generic terms;
127: * Use new Fact(functor, new Fact[]{...})
128: */
129: public Fact(Object functor, Term[] objects) {
130: super (functor);
131: throw new RuntimeException(
132: "Cannot construct a fact from generic terms;\n"
133: + "Use new Fact(functor, new Fact[]{...})");
134: }
135:
136: /**
137: * A convenience, equivalent to <code>new Fact(functor, new
138: * Object[]{o})</code>.
139: *
140: * @param Object the functor of the structure
141: *
142: * @param Object the object to convert to an atom
143: * and use as the term of this fact
144: *
145: */
146: public Fact(Object functor, Object o) {
147: this (functor, new Object[] { o });
148: }
149:
150: /**
151: * A convenience, equivalent to <code>new Fact(functor, new
152: * Object[]{o1, o2})</code>.
153: *
154: * @param Object the functor of the structure
155: *
156: * @param Object an object to convert to an atom
157: * and use as the first term of this fact
158: *
159: * @param Object an object to convert to an atom
160: * and use as the second term of this fact
161: *
162: */
163: public Fact(Object functor, Object o1, Object o2) {
164: this (functor, new Object[] { o1, o2 });
165: }
166:
167: /**
168: * Returns this fact.
169: *
170: * @return this fact
171: */
172: public Term copyForProof(AxiomSource ignored, Scope ignored2) {
173:
174: return this ;
175: }
176:
177: /**
178: * Returns this fact.
179: *
180: * @return this fact
181: */
182: public DynamicAxiom dynamicAxiom(AxiomSource ignored) {
183: return this ;
184: }
185:
186: /*
187: * Create an array of (atomic) facts from an array of
188: * objects.
189: */
190: protected static Fact[] facts(Object[] objects) {
191: Fact[] facts = new Fact[objects.length];
192:
193: for (int i = 0; i < objects.length; i++) {
194: facts[i] = new Atom(objects[i]);
195: }
196: return facts;
197: }
198:
199: /**
200: * Returns this fact.
201: *
202: * @return this fact
203: */
204: public Structure head() {
205: return this ;
206: }
207:
208: /**
209: * Returns an empty resolvent
210: *
211: * @return a dynamic rule with nothing in it
212: */
213: public DynamicRule resolvent() {
214: return resolvent;
215: }
216:
217: /**
218: * A speedier version of <code>unify(Structure s)</code>.
219: *
220: * @return either an empty Unification, indicating success,
221: * or null, indicating failure
222: */
223: public Unification unify(Fact f) {
224: if (!functorAndArityEquals(f)) {
225: return null;
226: }
227: for (int i = 0; i < terms.length; i++) {
228: Fact f1 = (Fact) terms[i];
229: Fact f2 = (Fact) f.terms[i];
230:
231: if (f1.unify(f2) == null) {
232: return null;
233: }
234: }
235: return Unification.empty;
236: }
237: }
|