001 // #define PAIRWISEINTEQUAL PairwiseStringGreaterThan 002 003// ***** This file is automatically generated from SeqComparison.java.jpp 004 005package daikon.inv.binary.twoSequence; 006 007import daikon.*; 008import daikon.Quantify.QuantFlags; 009import daikon.derive.binary.*; 010import daikon.inv.*; 011import daikon.suppress.*; 012import java.util.*; 013import java.util.logging.Logger; 014import org.checkerframework.checker.interning.qual.Interned; 015import org.checkerframework.checker.lock.qual.GuardSatisfied; 016import org.checkerframework.checker.nullness.qual.Nullable; 017import org.checkerframework.dataflow.qual.Pure; 018import org.checkerframework.dataflow.qual.SideEffectFree; 019import org.plumelib.util.ArraysPlume; 020import org.plumelib.util.Intern; 021import typequals.prototype.qual.NonPrototype; 022import typequals.prototype.qual.Prototype; 023 024/** 025 * Represents invariants between two sequences of String values. If order matters for each 026 * variable (which it does by default), then the sequences are compared lexically. Prints as 027 * {@code x[] > y[] lexically}. 028 * 029 030 * <p>If the auxiliary information (e.g., order matters) doesn't match between two variables, then 031 * this invariant cannot apply to those variables. 032 */ 033public class SeqSeqStringGreaterThan extends TwoSequenceString 034 035{ 036 // We are Serializable, so we specify a version to allow changes to 037 // method signatures without breaking serialization. If you add or 038 // remove fields, you should change this number to the current date. 039 static final long serialVersionUID = 20030822L; 040 041 // Variables starting with dkconfig_ should only be set via the 042 // daikon.config.Configuration interface. 043 /** Boolean. True iff SeqSeqStringGreaterThan invariants should be considered. */ 044 public static boolean dkconfig_enabled = Invariant.invariantEnabledDefault; 045 046 /** Debugging logger. */ 047 static final Logger debug = Logger.getLogger("daikon.inv.binary.twoSequence.SeqSeqStringGreaterThan"); 048 049 static Comparator<String[]> comparator = ArraysPlume.StringArrayComparatorLexical.it; 050 051 boolean orderMatters; 052 053 protected SeqSeqStringGreaterThan(PptSlice ppt, boolean order) { 054 super(ppt); 055 orderMatters = order; 056 } 057 058 protected @Prototype SeqSeqStringGreaterThan(boolean order) { 059 super(); 060 orderMatters = order; 061 } 062 063 protected SeqSeqStringGreaterThan(SeqSeqStringLessThan seq_swap) { 064 super(seq_swap.ppt); 065 orderMatters = seq_swap.orderMatters; 066 } 067 068 private static @Prototype SeqSeqStringGreaterThan proto = new @Prototype SeqSeqStringGreaterThan(true); 069 070 /** Returns the prototype invariant for SeqSeqStringGreaterThan */ 071 public static @Prototype SeqSeqStringGreaterThan get_proto() { 072 return proto; 073 } 074 075 /** Returns whether or not this invariant is enabled. */ 076 @Override 077 public boolean enabled() { 078 return dkconfig_enabled; 079 } 080 081 /** Non-Equal SeqComparison is only valid on integral types. */ 082 @Override 083 public boolean instantiate_ok(VarInfo[] vis) { 084 085 if (!valid_types(vis)) { 086 return false; 087 } 088 089 VarInfo var1 = vis[0]; 090 VarInfo var2 = vis[1]; 091 ProglangType type1 = var1.type; 092 ProglangType type2 = var2.type; 093 094 // This intentonally checks dimensions(), not pseudoDimensions. 095 boolean only_eq = 096 !((type1.dimensions() == 1) 097 && type1.baseIsString() 098 && (type2.dimensions() == 1) 099 && type2.baseIsString()); 100 if (only_eq) { 101 return false; 102 } 103 104 // non equality comparisons don't make sense if the arrays aren't ordered 105 if (!var1.aux.hasOrder() || !var2.aux.hasOrder()) { 106 return false; 107 } 108 109 return true; 110 } 111 112 /** Instantiates the invariant on the specified slice. */ 113 @Override 114 protected SeqSeqStringGreaterThan instantiate_dyn(@Prototype SeqSeqStringGreaterThan this, PptSlice slice) { 115 boolean has_order = slice.var_infos[0].aux.hasOrder() && slice.var_infos[1].aux.hasOrder(); 116 return new SeqSeqStringGreaterThan(slice, has_order); 117 } 118 119 @Override 120 protected Invariant resurrect_done_swapped() { 121 122 return new SeqSeqStringLessThan(this); 123 } 124 125 @Override 126 public String repr(@GuardSatisfied SeqSeqStringGreaterThan this) { 127 return "SeqSeqStringGreaterThan" + varNames() + ": ,orderMatters=" + orderMatters 128 + ",enoughSamples=" + enoughSamples() 129 ; 130 } 131 132 @SideEffectFree 133 @Override 134 public String format_using(@GuardSatisfied SeqSeqStringGreaterThan this, OutputFormat format) { 135 // System.out.println("Calling SeqSeqStringGreaterThan.format for: " + repr()); 136 137 if (format == OutputFormat.SIMPLIFY) { 138 return format_simplify(); 139 } 140 141 if (format == OutputFormat.DAIKON) { 142 String name1 = var1().name_using(format); 143 String name2 = var2().name_using(format); 144 145 String lexically = (var1().aux.hasOrder() ? " (lexically)" : ""); 146 return name1 + " > " + name2 + lexically; 147 } 148 149 if (format == OutputFormat.CSHARPCONTRACT) { 150 151 if (var1().aux.hasOrder()) { 152 String name1 = var1().csharp_collection_string(); 153 String name2 = var2().csharp_collection_string(); 154 String dbc = "LlexGT".substring(1); 155 return name1 + "." + dbc + "(" + name2 + ")"; 156 } else { 157 return "\"SeqComparison.java.jpp: sequence comparison does not apply to unordered collections unimplemented\" != null)"; // interned 158 } 159 160 } 161 162 if (format.isJavaFamily()) { 163 String name1 = var1().name_using(format); 164 String name2 = var2().name_using(format); 165 166 return "daikon.Quant." 167 + (var1().aux.hasOrder() ? "lexGT" : "setEqual" ) 168 + "(" 169 + name1 170 + ", " 171 + name2 172 + ")"; 173 174 } 175 176 return format_unimplemented(format); 177 } 178 179 public String format_simplify(@GuardSatisfied SeqSeqStringGreaterThan this) { 180 if (Invariant.dkconfig_simplify_define_predicates) { 181 return format_simplify_defined(); 182 } else { 183 return format_simplify_explicit(); 184 } 185 } 186 187 private String format_simplify_defined(@GuardSatisfied SeqSeqStringGreaterThan this) { 188 String[] var1_name = var1().simplifyNameAndBounds(); 189 String[] var2_name = var2().simplifyNameAndBounds(); 190 if (var1_name == null || var2_name == null) { 191 return String.format("%s.format_simplify_defined(%s): var1_name=%s, var2_name=%s, for %s", 192 getClass().getSimpleName(), this, 193 Arrays.toString(var1_name), Arrays.toString(var2_name), format()); 194 } 195 return "(|lexical->| " 196 + var1_name[0] + " " + var1_name[1] + " " + var1_name[2] + " " 197 + var2_name[0] + " " + var2_name[1] + " " + var2_name[2] + ")"; 198 } 199 200 private String format_simplify_explicit(@GuardSatisfied SeqSeqStringGreaterThan this) { 201 202 String classname = this.getClass().toString().substring(6); 203 return "warning: method " + classname 204 + ".format_simplify_explicit() needs to be implemented: " + format(); 205 206 } 207 208 @Override 209 public InvariantStatus check_modified( 210 String @Interned [] v1, String @Interned [] v2, int count) { 211 /// This does not do the right thing; I really want to avoid comparisons 212 /// if one is missing, but not if one is zero-length. 213 // // Don't make comparisons with empty arrays. 214 // if ((v1.length == 0) || (v2.length == 0)) { 215 // return; 216 // } 217 218 int comparison = 0; 219 if (orderMatters) { 220 // Standard element wise comparison 221 comparison = comparator.compare(v1, v2); 222 } else { 223 // Do a double subset comparison 224 comparison = (ArraysPlume.isSubset(v1, v2) && ArraysPlume.isSubset( v2, v1)) ? 0 : -1; 225 } 226 227 if (!(comparison > 0) ) { 228 return InvariantStatus.FALSIFIED; 229 } 230 return InvariantStatus.NO_CHANGE; 231 } 232 233 @Override 234 public InvariantStatus add_modified(String @Interned [] v1, String @Interned [] v2, int count) { 235 if (logDetail()) { 236 log("add_modified (%s, %s)", Arrays.toString(v1), Arrays.toString(v2)); 237 } 238 return check_modified(v1, v2, count); 239 } 240 241 @Override 242 protected double computeConfidence() { 243 244 return 1 - Math.pow(.5, ppt.num_values()); 245 } 246 247 @Pure 248 @Override 249 public boolean isSameFormula(Invariant o) { 250 return true; 251 } 252 253 @Pure 254 @Override 255 public boolean isExclusiveFormula(Invariant o) { 256 return false; 257 } 258 259 /** 260 * Since this invariant can be a postProcessed equality, we have to handle isObvious especially to 261 * avoid circular isObvious relations. 262 */ 263 @Pure 264 @Override 265 public @Nullable DiscardInfo isObviousStatically_SomeInEquality() { 266 if (var1().equalitySet == var2().equalitySet) { 267 return isObviousStatically(this.ppt.var_infos); 268 } else { 269 return super.isObviousStatically_SomeInEquality(); 270 } 271 } 272 273 /** 274 * Since this invariant can be a postProcessed equality, we have to handle isObvious especially to 275 * avoid circular isObvious relations. 276 */ 277 @Pure 278 @Override 279 public @Nullable DiscardInfo isObviousDynamically_SomeInEquality() { 280 if (logOn()) { 281 log("Considering dynamically_someInEquality"); 282 } 283 if (var1().equalitySet == var2().equalitySet) { 284 return isObviousDynamically(this.ppt.var_infos); 285 } else { 286 return super.isObviousDynamically_SomeInEquality(); 287 } 288 } 289 290 @Pure 291 @Override 292 public @Nullable DiscardInfo isObviousStatically(VarInfo[] vis) { 293 294 return super.isObviousStatically(vis); 295 } 296 297 @Pure 298 @Override 299 public @Nullable DiscardInfo isObviousDynamically(VarInfo[] vis) { 300 DiscardInfo super_result = super.isObviousDynamically(vis); 301 if (super_result != null) { 302 return super_result; 303 } 304 assert ppt != null; 305 306 return null; 307 } 308 309 @Override 310 public void repCheck() { 311 super.repCheck(); 312 /* 313 This code is no longer needed now that the can_be_x's are gone 314 if (!(this.can_be_eq || this.can_be_lt || this.can_be_gt) 315 && ppt.num_samples() != 0) { 316 System.err.println(this.repr()); 317 System.err.println(this.ppt.num_samples()); 318 throw new Error(); 319 } 320 */ 321 } 322 323 @Pure 324 public boolean isEqual() { 325 326 return false; 327 } 328 329 // Look up a previously instantiated invariant. 330 public static @Nullable SeqSeqStringGreaterThan find(PptSlice ppt) { 331 assert ppt.arity() == 2; 332 for (Invariant inv : ppt.invs) { 333 if (inv instanceof SeqSeqStringGreaterThan) { 334 return (SeqSeqStringGreaterThan) inv; 335 } 336 } 337 return null; 338 } 339 340 /** Returns a list of non-instantiating suppressions for this invariant. */ 341 @Pure 342 @Override 343 public @Nullable NISuppressionSet get_ni_suppressions() { 344 return suppressions; 345 } 346 347 private static @Nullable NISuppressionSet suppressions = null; 348 349}