001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002 *
003 * Copyright 2000-2011, Michael Meyling <mime@qedeq.org>.
004 *
005 * "Hilbert II" is free software; you can redistribute
006 * it and/or modify it under the terms of the GNU General Public
007 * License as published by the Free Software Foundation; either
008 * version 2 of the License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU General Public License for more details.
014 */
015
016 package org.qedeq.kernel.bo.logic.model;
017
018 import org.qedeq.base.trace.Trace;
019 import org.qedeq.base.utility.StringUtility;
020
021 /**
022 * One predicate for our model.
023 *
024 * @author Michael Meyling
025 */
026 public abstract class Predicate {
027
028 /** This class. */
029 private static final Class CLASS = Predicate.class;
030
031 /** Minimum number of arguments this predicate has. */
032 private final int minimum;
033
034 /** Maximum number of arguments this predicate has. */
035 private final int maximum;
036
037 /** Display text. */
038 private final String display;
039
040 /** Description for this predicate. */
041 private final String description;
042
043 /**
044 * Constructor.
045 *
046 * @param minimum Minimum number of arguments this predicate has.
047 * @param maximum Maximum number of arguments this predicate has.
048 * @param display Show this to represent the predicate within outputs.
049 * @param description Description for this predicate.
050 */
051 public Predicate(final int minimum, final int maximum, final String display,
052 final String description) {
053 this.minimum = minimum;
054 this.maximum = maximum;
055 this.display = display;
056 this.description = description;
057 }
058
059 /**
060 * Construct negation of other predicate.
061 *
062 * @param predicate Negate this predicate.
063 * @return Negation of predicate.
064 */
065 public static Predicate not(final Predicate predicate) {
066 return new Predicate(predicate.getMinimumArgumentNumber(),
067 predicate.getMaximumArgumentNumber(), "!" + predicate.toString(),
068 "!" + predicate.getDescription()) {
069 public boolean calculate(final Entity[] entities) {
070 final String method = "not.calculate(Entity[])";
071 if (Trace.isDebugEnabled(CLASS)) {
072 Trace.param(CLASS, method, "toString", toString());
073 Trace.param(CLASS, method, "entities", StringUtility.toString(entities));
074 }
075 final boolean result = !predicate.calculate(entities);
076 Trace.param(CLASS, method, "result ", result);
077 return result;
078 }
079 };
080 }
081
082 /**
083 * Construct conjunction of two predicates.
084 *
085 * @param op1 First predicate.
086 * @param op2 Second predicate.
087 * @return Conjunction of two predicates.
088 */
089 public static Predicate and(final Predicate op1, final Predicate op2) {
090 if (op1.getMinimumArgumentNumber() > op2.getMaximumArgumentNumber()
091 || op1.getMaximumArgumentNumber() < op2.getMinimumArgumentNumber()) {
092 throw new IllegalArgumentException("Predicates can not be combined " + op1 + " and "
093 + op2);
094 }
095 return new Predicate(Math.max(op1.getMinimumArgumentNumber(),
096 op2.getMinimumArgumentNumber()), Math.min(op1.getMaximumArgumentNumber(),
097 op2.getMaximumArgumentNumber()), op1.toString() + " and " + op2.toString(),
098 op1.getDescription() + " and " + op2.getDescription()) {
099 public boolean calculate(final Entity[] entities) {
100 final String method = "and.calculate(Entity[])";
101 if (Trace.isDebugEnabled(CLASS)) {
102 Trace.param(CLASS, method, "toString", toString());
103 Trace.param(CLASS, method, "entities", StringUtility.toString(entities));
104 }
105 boolean result = op1.calculate(entities) && op2.calculate(entities);
106 Trace.param(CLASS, method, "result ", result);
107 return result;
108 }
109 };
110 }
111
112 /**
113 * Construct disjunction of two predicates.
114 *
115 * @param op1 First predicate.
116 * @param op2 Second predicate.
117 * @return Disjunction of two predicates.
118 */
119 public static Predicate or(final Predicate op1, final Predicate op2) {
120 if (op1.getMinimumArgumentNumber() > op2.getMaximumArgumentNumber()
121 || op1.getMaximumArgumentNumber() < op2.getMinimumArgumentNumber()) {
122 throw new IllegalArgumentException("Predicates can not be combined " + op1 + " and "
123 + op2);
124 }
125 return new Predicate(Math.max(op1.getMinimumArgumentNumber(),
126 op2.getMinimumArgumentNumber()), Math.min(op1.getMaximumArgumentNumber(),
127 op2.getMaximumArgumentNumber()), op1.toString() + " or " + op2.toString(),
128 op1.getDescription() + " or " + op2.getDescription()) {
129 public boolean calculate(final Entity[] entities) {
130 final String method = "or.calculate(Entity[])";
131 if (Trace.isDebugEnabled(CLASS)) {
132 Trace.param(CLASS, method, "toString", toString());
133 Trace.param(CLASS, method, "entities", StringUtility.toString(entities));
134 }
135 if (Trace.isDebugEnabled(CLASS)) {
136 Trace.param(CLASS, method, "toString", toString());
137 Trace.param(CLASS, method, "entities", StringUtility.toString(entities));
138 }
139 boolean result = op1.calculate(entities) || op2.calculate(entities);
140 Trace.param(CLASS, method, "result ", result);
141 return result;
142 }
143 };
144 }
145
146 /**
147 * Construct identifying predicate.
148 *
149 * @param entity Check if all entities are equal to this.
150 * @return Predicate to check for this entity.
151 */
152 public static Predicate isEntity(final Entity entity) {
153 return new Predicate(1, 99, "=" + entity, "= " + entity.getDescription()) {
154 public boolean calculate(final Entity[] entities) {
155 final String method = "isEntity.calculate(Entity[])";
156 if (Trace.isDebugEnabled(CLASS)) {
157 Trace.param(CLASS, method, "toString", toString());
158 Trace.param(CLASS, method, "entities", StringUtility.toString(entities));
159 }
160 if (Trace.isDebugEnabled(CLASS)) {
161 Trace.param(CLASS, method, "toString", toString());
162 Trace.param(CLASS, method, "entities", StringUtility.toString(entities));
163 }
164 boolean result = true;
165 for (int i = 0; i < entities.length; i++) {
166 result &= entity.getValue() == entities[i].getValue();
167 }
168 Trace.param(CLASS, method, "result ", result);
169 return result;
170 }
171 };
172 }
173
174 /**
175 * Get minimum number of arguments this predicate has.
176 *
177 * @return Minimum number of arguments for this predicate.
178 */
179 public int getMinimumArgumentNumber() {
180 return minimum;
181 }
182
183 /**
184 * Get maximum number of arguments this predicate has.
185 *
186 * @return Maximum umber of arguments for this predicate.
187 */
188 public int getMaximumArgumentNumber() {
189 return maximum;
190 }
191
192 /**
193 * Get display text.
194 *
195 * @return Representation of this predicate for textual output.
196 */
197 public String toString() {
198 return display;
199 }
200
201 /**
202 * Get description.
203 *
204 * @return Description of this predicate.
205 */
206 public String getDescription() {
207 return description;
208 }
209
210 /**
211 * Calculate truth value.
212 *
213 * @param entities Calculate predicate for this entities.
214 * @return Truth value.
215 */
216 public abstract boolean calculate(Entity[] entities);
217
218 }
|