001// ***** This file is automatically generated from IntComparisons.java.jpp
002
003package daikon.inv.binary.twoString;
004
005import daikon.*;
006import daikon.derive.binary.*;
007import daikon.derive.unary.*;
008import daikon.inv.*;
009import daikon.inv.binary.twoScalar.*;
010import daikon.inv.binary.twoSequence.*;
011import daikon.inv.unary.scalar.*;
012import daikon.inv.unary.sequence.*;
013import daikon.inv.unary.string.*;
014import daikon.suppress.*;
015import java.util.*;
016import java.util.logging.Level;
017import java.util.logging.Logger;
018import org.checkerframework.checker.interning.qual.Interned;
019import org.checkerframework.checker.lock.qual.GuardSatisfied;
020import org.checkerframework.checker.nullness.qual.NonNull;
021import org.checkerframework.checker.nullness.qual.Nullable;
022import org.checkerframework.dataflow.qual.Pure;
023import org.checkerframework.dataflow.qual.SideEffectFree;
024import org.plumelib.util.Intern;
025import typequals.prototype.qual.NonPrototype;
026import typequals.prototype.qual.Prototype;
027
028/**
029 * Represents an invariant of > between two String scalars. Prints as {@code x > y}.
030 */
031public final class StringGreaterThan extends TwoString {
032
033  static final long serialVersionUID = 20030822L;
034
035  // Variables starting with dkconfig_ should only be set via the
036  // daikon.config.Configuration interface.
037  /** Boolean. True iff StringGreaterThan invariants should be considered. */
038  public static boolean dkconfig_enabled = Invariant.invariantEnabledDefault;
039
040  public static final Logger debug = Logger.getLogger("daikon.inv.binary.twoScalar.StringGreaterThan");
041
042  StringGreaterThan(PptSlice ppt) {
043    super(ppt);
044  }
045
046  @Prototype StringGreaterThan() {
047    super();
048  }
049
050  private static @Prototype StringGreaterThan proto = new @Prototype StringGreaterThan();
051
052  /** Returns the prototype invariant for StringGreaterThan. */
053  public static @Prototype StringGreaterThan get_proto() {
054    return proto;
055  }
056
057  @Override
058  public boolean enabled() {
059    return dkconfig_enabled;
060  }
061
062  /** Returns whether or not the specified var types are valid for StringGreaterThan. */
063  @Override
064  public boolean instantiate_ok(VarInfo[] vis) {
065
066    if (!valid_types(vis)) {
067      return false;
068    }
069
070        boolean result = !(vis[0].has_typeof() || vis[1].has_typeof());
071        // System.out.printf("StringGreaterThan.instantiate_ok(");
072        // for (VarInfo vi : vis) {
073        //   System.out.printf("%s ", vi.name());
074        // }
075        // System.out.printf(") => %s%n", result);
076        return result;
077  }
078
079  @Override
080  protected StringGreaterThan instantiate_dyn(@Prototype StringGreaterThan this, PptSlice slice) {
081
082    return new StringGreaterThan(slice);
083  }
084
085  @Override
086  protected Invariant resurrect_done_swapped() {
087
088      // we have no non-static member data, so we only need care about our type
089      // As of now, the constructor chain is side-effect free;
090      // let's hope it stays that way.
091      StringLessThan result = new StringLessThan(ppt);
092      return result;
093  }
094
095  /** Returns the class that corresponds to this class with its variable order swapped. */
096  public static Class<? extends Invariant> swap_class() {
097    return StringLessThan.class;
098  }
099
100  // JHP: this should be removed in favor of checks in PptTopLevel
101  // such as is_equal, is_lessequal, etc.
102  // Look up a previously instantiated StringGreaterThan relationship.
103  // Should this implementation be made more efficient?
104  public static @Nullable StringGreaterThan find(PptSlice ppt) {
105    assert ppt.arity() == 2;
106    for (Invariant inv : ppt.invs) {
107      if (inv instanceof StringGreaterThan) {
108        return (StringGreaterThan) inv;
109      }
110    }
111
112    // If the invariant is suppressed, create it
113    if ((suppressions != null) && suppressions.suppressed(ppt)) {
114      StringGreaterThan inv = proto.instantiate_dyn(ppt);
115      // System.out.printf("%s is suppressed in ppt %s%n", inv.format(), ppt.name());
116      return inv;
117    }
118
119    return null;
120  }
121
122  @Override
123  public String repr(@GuardSatisfied StringGreaterThan this) {
124    return "StringGreaterThan" + varNames();
125  }
126
127  @SideEffectFree
128  @Override
129  public String format_using(@GuardSatisfied StringGreaterThan this, OutputFormat format) {
130
131    String var1name = var1().name_using(format);
132    String var2name = var2().name_using(format);
133
134    if ((format == OutputFormat.DAIKON) || (format == OutputFormat.ESCJAVA)) {
135      String comparator = ">";
136      return var1name + " " + comparator + " " + var2name;
137    }
138
139    if (format == OutputFormat.CSHARPCONTRACT) {
140
141        return var1name + ".CompareTo(" + var2name +") > 0";
142    }
143
144    if (format.isJavaFamily()) {
145
146        return var1name + ".compareTo(" + var2name +") > 0";
147
148    }
149
150    if (format == OutputFormat.SIMPLIFY) {
151
152        String comparator = ">";
153
154      return "("
155          + comparator
156          + " "
157          + var1().simplifyFixup(var1name)
158          + " "
159          + var2().simplifyFixup(var2name)
160          + ")";
161    }
162
163    return format_unimplemented(format);
164  }
165
166  @Override
167  public InvariantStatus check_modified(@Interned String v1, @Interned String v2, int count) {
168    if (!((v1 != null) && ( v2 != null) && (v1.compareTo( v2) > 0))) {
169      return InvariantStatus.FALSIFIED;
170    }
171    return InvariantStatus.NO_CHANGE;
172  }
173
174  @Override
175  public InvariantStatus add_modified(@Interned String v1, @Interned String v2, int count) {
176    if (logDetail() || debug.isLoggable(Level.FINE)) {
177      log(
178          debug,
179          "add_modified (" + v1 + ", " + v2 + ",  ppt.num_values = " + ppt.num_values() + ")");
180    }
181    if ((logOn() || debug.isLoggable(Level.FINE))
182        && check_modified(v1, v2, count) == InvariantStatus.FALSIFIED)
183      log(debug, "destroy in add_modified (" + v1 + ", " + v2 + ",  " + count + ")");
184
185    return check_modified(v1, v2, count);
186  }
187
188  // This is very tricky, because whether two variables are equal should
189  // presumably be transitive, but it's not guaranteed to be so when using
190  // this method and not dropping out all variables whose values are ever
191  // missing.
192  @Override
193  protected double computeConfidence() {
194    // Should perhaps check number of samples and be unjustified if too few
195    // samples.
196
197      // // The reason for this multiplication is that there might be only a
198      // // very few possible values.  Example:  towers of hanoi has only 6
199      // // possible (pegA, pegB) pairs.
200      // return 1 - (Math.pow(.5, ppt.num_values())
201      //             * Math.pow(.99, ppt.num_mod_samples()));
202      return 1 - Math.pow(.5, ppt.num_samples());
203  }
204
205  @Pure
206  @Override
207  public boolean isExact() {
208
209      return false;
210  }
211
212  // // Temporary, for debugging
213  // public void destroy() {
214  //   if (debug.isLoggable(Level.FINE)) {
215  //     System.out.println("StringGreaterThan.destroy(" + ppt.name() + ")");
216  //     System.out.println(repr());
217  //     (new Error()).printStackTrace();
218  //   }
219  //   super.destroy();
220  // }
221
222  @Override
223  public InvariantStatus add(
224      @Interned Object v1, @Interned Object v2, int mod_index, int count) {
225    if (debug.isLoggable(Level.FINE)) {
226      debug.fine(
227          "StringGreaterThan"
228          + ppt.varNames()
229          + ".add("
230          + v1
231          + ","
232          + v2
233          + ", mod_index="
234          + mod_index
235          + "), count="
236          + count
237          + ")");
238    }
239    return super.add(v1, v2, mod_index, count);
240  }
241
242  @Pure
243  @Override
244  public boolean isSameFormula(Invariant other) {
245    return true;
246  }
247
248  @Pure
249  @Override
250  public boolean isExclusiveFormula(Invariant other) {
251
252    // Also ought to check against LinearBinary, etc.
253
254      if ((other instanceof StringLessThan)
255          || (other instanceof StringLessEqual)
256          || (other instanceof StringEqual))
257        return true;
258
259    return false;
260  }
261
262  @Override
263  public @Nullable DiscardInfo isObviousStatically(VarInfo[] vis) {
264    final VarInfo var1 = vis[0];
265    final VarInfo var2 = vis[1];
266
267    if (var1.aux.hasValue(VarInfoAux.MINIMUM_VALUE)
268        && var2.aux.hasValue(VarInfoAux.MAXIMUM_VALUE)) {
269      int maxB = var2.aux.getInt(VarInfoAux.MAXIMUM_VALUE),
270          minA = var1.aux.getInt(VarInfoAux.MINIMUM_VALUE);
271
272      if (minA > maxB) {
273        return new DiscardInfo(
274            this,
275            DiscardCode.obvious,
276            var1.name() + " DISCARD_OP " + var2.name() + " is already known");
277      }
278    }
279
280    return super.isObviousStatically(vis);
281  }
282
283  @Pure
284  @Override
285  public @Nullable DiscardInfo isObviousDynamically(VarInfo[] vis) {
286
287    // JHP: We might consider adding a check over bounds.   If
288    // x < c and y > c then we know that x < y.  Similarly for
289    // x > c and y < c.  We could also substitute oneof for
290    // one or both of the bound checks.
291
292    DiscardInfo super_result = super.isObviousDynamically(vis);
293    if (super_result != null) {
294      return super_result;
295    }
296
297    @SuppressWarnings("UnusedVariable") // generated code, variable is sometimes used
298    DiscardInfo di;
299
300    return null;
301  } // isObviousDynamically
302
303  /** NI suppressions, initialized in get_ni_suppressions() */
304  private static @Nullable NISuppressionSet suppressions = null;
305
306  /** Returns the non-instantiating suppressions for this invariant. */
307  @Pure
308  @Override
309  public @Nullable NISuppressionSet get_ni_suppressions() {
310    return null;
311  }
312
313}