View Javadoc

1   /* This file is part of the project "Hilbert II" - http://www.qedeq.org" target="alexandria_uri">http://www.qedeq.org
2    *
3    * Copyright 2000-2014,  Michael Meyling <mime@qedeq.org>.
4    *
5    * "Hilbert II" is free software; you can redistribute
6    * it and/or modify it under the terms of the GNU General Public
7    * License as published by the Free Software Foundation; either
8    * version 2 of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU General Public License for more details.
14   */
15  
16  package org.qedeq.kernel.bo.logic.model;
17  
18  import org.qedeq.base.trace.Trace;
19  import org.qedeq.base.utility.StringUtility;
20  
21  /**
22   * One predicate for our model.
23   *
24   * @author  Michael Meyling
25   */
26  public abstract class Predicate {
27  
28      /** This class. */
29      private static final Class CLASS = Predicate.class;
30  
31      /** Minimum number of arguments this predicate has. */
32      private final int minimum;
33  
34      /** Maximum number of arguments this predicate has. */
35      private final int maximum;
36  
37      /** Display text. */
38      private final String display;
39  
40      /** Description for this predicate. */
41      private final String description;
42  
43      /**
44       * Constructor.
45       *
46       * @param   minimum         Minimum number of arguments this predicate has.
47       * @param   maximum         Maximum number of arguments this predicate has.
48       * @param   display         Show this to represent the predicate within outputs.
49       * @param   description     Description for this predicate.
50       */
51      public Predicate(final int minimum, final int maximum, final String display,
52              final String description) {
53          this.minimum = minimum;
54          this.maximum = maximum;
55          this.display = display;
56          this.description = description;
57      }
58  
59      /**
60       * Construct negation of other predicate.
61       *
62       * @param   predicate   Negate this predicate.
63       * @return  Negation of predicate.
64       */
65      public static Predicate not(final Predicate predicate) {
66          return new Predicate(predicate.getMinimumArgumentNumber(),
67              predicate.getMaximumArgumentNumber(), "!" + predicate.toString(),
68              "!" + predicate.getDescription()) {
69                  public boolean calculate(final Entity[] entities) {
70                      final String method = "not.calculate(Entity[])";
71                      if (Trace.isDebugEnabled(CLASS)) {
72                          Trace.param(CLASS, method, "toString", toString());
73                          Trace.param(CLASS, method, "entities", StringUtility.toString(entities));
74                      }
75                      final boolean result = !predicate.calculate(entities);
76                      Trace.param(CLASS, method, "result  ", result);
77                      return result;
78                  }
79          };
80      }
81  
82      /**
83       * Construct conjunction of two predicates.
84       *
85       * @param   op1     First predicate.
86       * @param   op2     Second predicate.
87       * @return  Conjunction of two predicates.
88       */
89      public static Predicate and(final Predicate op1, final Predicate op2) {
90          if (op1.getMinimumArgumentNumber() > op2.getMaximumArgumentNumber()
91                  || op1.getMaximumArgumentNumber() < op2.getMinimumArgumentNumber()) {
92              throw new IllegalArgumentException("Predicates can not be combined " + op1 + " and "
93                  + op2);
94          }
95          return new Predicate(Math.max(op1.getMinimumArgumentNumber(),
96                  op2.getMinimumArgumentNumber()), Math.min(op1.getMaximumArgumentNumber(),
97                  op2.getMaximumArgumentNumber()), op1.toString() + " and " + op2.toString(),
98                  op1.getDescription() + " and " + op2.getDescription()) {
99              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 }