001// ***** This file is automatically generated from EltwiseIntComparisons.java.jpp 002 003package daikon.inv.unary.sequence; 004 005import daikon.*; 006import daikon.Quantify.QuantFlags; 007import daikon.derive.*; 008import daikon.derive.binary.*; 009import daikon.inv.*; 010import java.util.*; 011import org.checkerframework.checker.interning.qual.Interned; 012import org.checkerframework.checker.lock.qual.GuardSatisfied; 013import org.checkerframework.checker.nullness.qual.Nullable; 014import org.checkerframework.dataflow.qual.Pure; 015import org.checkerframework.dataflow.qual.SideEffectFree; 016import org.plumelib.util.Intern; 017import typequals.prototype.qual.NonPrototype; 018import typequals.prototype.qual.Prototype; 019 020 /** 021 * Represents the invariant ≤ between adjacent elements 022 * (x[i], x[i+1]) of a long sequence. Prints as 023 * {@code x[] sorted by <=}. 024 */ 025 026public class EltwiseIntLessEqual extends EltwiseIntComparison { 027 // We are Serializable, so we specify a version to allow changes to 028 // method signatures without breaking serialization. If you add or 029 // remove fields, you should change this number to the current date. 030 static final long serialVersionUID = 20030822L; 031 032 // Variables starting with dkconfig_ should only be set via the 033 // daikon.config.Configuration interface. 034 /** Boolean. True iff EltwiseIntComparison invariants should be considered. */ 035 public static boolean dkconfig_enabled = Invariant.invariantEnabledDefault; 036 037 static final boolean debugEltwiseIntComparison = false; 038 039 protected EltwiseIntLessEqual(PptSlice ppt) { 040 super(ppt); 041 } 042 043 protected @Prototype EltwiseIntLessEqual() { 044 super(); 045 } 046 047 private static @Prototype EltwiseIntLessEqual proto = new @Prototype EltwiseIntLessEqual(); 048 049 /** Returns the prototype invariant for EltwiseIntLessEqual */ 050 public static @Prototype EltwiseIntLessEqual get_proto() { 051 return proto; 052 } 053 054 /** returns whether or not this invariant is enabled */ 055 @Override 056 public boolean enabled() { 057 return dkconfig_enabled; 058 } 059 060 /** Non-equality EltwiseIntLessEqual invariants are only valid on integral types. */ 061 @Override 062 public boolean instantiate_ok(VarInfo[] vis) { 063 064 if (!valid_types(vis)) { 065 return false; 066 } 067 068 if (!vis[0].type.baseIsIntegral()) { 069 return false; 070 } 071 072 return true; 073 } 074 075 /** Instantiate the invariant on the specified slice. */ 076 @Override 077 protected EltwiseIntLessEqual instantiate_dyn(@Prototype EltwiseIntLessEqual this, PptSlice slice) { 078 return new EltwiseIntLessEqual(slice); 079 } 080 081 @SideEffectFree 082 @Override 083 public EltwiseIntLessEqual clone(@GuardSatisfied EltwiseIntLessEqual this) { 084 EltwiseIntLessEqual result = (EltwiseIntLessEqual) super.clone(); 085 return result; 086 } 087 088 @Override 089 public String repr(@GuardSatisfied EltwiseIntLessEqual this) { 090 return "EltwiseIntLessEqual" + varNames() + ": falsified=" + falsified; 091 } 092 093 @SideEffectFree 094 @Override 095 public String format_using(@GuardSatisfied EltwiseIntLessEqual this, OutputFormat format) { 096 if (format.isJavaFamily()) { 097 return format_java_family(format); 098 } 099 100 if (format == OutputFormat.DAIKON) { 101 return format_daikon(); 102 } 103 if (format == OutputFormat.ESCJAVA) { 104 return format_esc(); 105 } 106 if (format == OutputFormat.CSHARPCONTRACT) { 107 return format_csharp_contract(); 108 } 109 if (format == OutputFormat.SIMPLIFY) { 110 return format_simplify(); 111 } 112 113 return format_unimplemented(format); 114 } 115 116 public String format_daikon(@GuardSatisfied EltwiseIntLessEqual this) { 117 if (debugEltwiseIntComparison) { 118 System.out.println(repr()); 119 } 120 121 return var().name() + " sorted by <="; 122 } 123 124 public String format_esc(@GuardSatisfied EltwiseIntLessEqual this) { 125 String[] form = VarInfo.esc_quantify(false, var(), var()); 126 127 return form[0] + "((i+1 == j) ==> (" + form[1] + " <= " + form[2] + "))" + form[3]; 128 } 129 130 public String format_java_family(@GuardSatisfied EltwiseIntLessEqual this, OutputFormat format) { 131 return "daikon.Quant.eltwiseLTE(" + var().name_using(format) + ")"; 132 } 133 134 public String format_csharp_contract(@GuardSatisfied EltwiseIntLessEqual this) { 135 String[] split = var().csharp_array_split(); 136 return "Contract.ForAll(0, " + split[0] + ".Count()-1, i => " + split[0] + "[i]" + split[1] + " <= " + split[0] + "[i+1]" + split[1] + ")"; 137 } 138 139 public String format_simplify(@GuardSatisfied EltwiseIntLessEqual this) { 140 String[] form = VarInfo.simplify_quantify(QuantFlags.adjacent(), 141 var(), var()); 142 143 String comparator = "<="; 144 145 return form[0] + "(" + comparator + " " + form[1] + " " + form[2] + ")" 146 + form[3]; 147 } 148 149 @Override 150 @SuppressWarnings("UnnecessaryParentheses") // generated code, parentheses are sometimes needed 151 public InvariantStatus check_modified(long @Interned [] a, int count) { 152 for (int i = 1; i < a.length; i++) { 153 if (!((a[i - 1]) <= ( a[i]))) { 154 return InvariantStatus.FALSIFIED; 155 } 156 } 157 return InvariantStatus.NO_CHANGE; 158 } 159 160 @Override 161 public InvariantStatus add_modified(long @Interned [] a, int count) { 162 return check_modified(a, count); 163 } 164 165 // Perhaps check whether all the arrays of interest have length 0 or 1. 166 167 @Override 168 protected double computeConfidence() { 169 170 return 1 - Math.pow(.5, ppt.num_samples()); 171 } 172 173 @Pure 174 @Override 175 public boolean isExact() { 176 177 return false; 178 } 179 180 @Pure 181 @Override 182 public boolean isSameFormula(Invariant other) { 183 return (other instanceof EltwiseIntLessEqual); 184 } 185 186 // Not pretty... is there another way? 187 // Also, reasonably complicated, need to ensure exact correctness, not sure if the 188 // regression tests test this functionality 189 190 @Pure 191 @Override 192 public boolean isExclusiveFormula(Invariant other) { 193 // This whole approach is wrong in the case when the sequence can 194 // ever consist of only one element. For now, just forget 195 // it. -SMcC 196 if (true) { 197 return false; 198 } 199 200 if (other instanceof EltwiseIntComparison) { 201 202 return (other instanceof EltwiseIntGreaterThan) || (other instanceof EltwiseFloatGreaterThan); 203 } 204 return false; 205 } 206 207 // Look up a previously instantiated invariant. 208 public static @Nullable EltwiseIntLessEqual find(PptSlice ppt) { 209 assert ppt.arity() == 1; 210 for (Invariant inv : ppt.invs) { 211 if (inv instanceof EltwiseIntLessEqual) { 212 return (EltwiseIntLessEqual) inv; 213 } 214 } 215 return null; 216 } 217 218 // Copied from IntComparison. 219 // public boolean isExclusiveFormula(Invariant other) 220 // { 221 // if (other instanceof IntComparison) { 222 // return core.isExclusiveFormula(((IntComparison) other).core); 223 // } 224 // if (other instanceof IntNonEqual) { 225 // return isExact(); 226 // } 227 // return false; 228 // } 229 230 /** 231 * This function returns whether a sample has been seen by this Invariant that includes two or 232 * more entries in an array. For a 0 or 1 element array a, a[] sorted by any binary operation is 233 * "vacuously true" because no check is ever made since the binary operation requires two 234 * operands. Thus although invariants of this type are true regarding 0 or 1 length arrays, they 235 * are meaningless. This function is meant to be used in isObviousImplied() to prevent such 236 * meaningless invariants from being printed. 237 */ 238 @Override 239 public boolean hasSeenNonSingletonSample() { 240 ValueSet.ValueSetScalarArray vs = (ValueSet.ValueSetScalarArray) ppt.var_infos[0].get_value_set(); 241 return vs.nonsingleton_arr_cnt() > 0; 242 } 243 244 @Pure 245 @Override 246 public @Nullable DiscardInfo isObviousDynamically(VarInfo[] vis) { 247 DiscardInfo super_result = super.isObviousDynamically(vis); 248 if (super_result != null) { 249 return super_result; 250 } 251 252 if (!hasSeenNonSingletonSample()) { 253 return new DiscardInfo(this, DiscardCode.obvious, 254 "No samples sequences of size >=2 were seen. Vacuously true."); 255 } 256 257 EltOneOf eoo = EltOneOf.find(ppt); 258 if ((eoo != null) && eoo.enoughSamples() && (eoo.num_elts() == 1)) { 259 return new DiscardInfo(this, DiscardCode.obvious, "The sequence contains all equal values."); 260 } 261 262 { 263 // some relations imply others as follows: < -> <=, > -> >= 264 // == -> <=, >= 265 266 // This code lets through some implied invariants, here is how: 267 // In the ESC, JML, Java modes of output, the invariants are guarded 268 // before printing. This guarding makes some of the invariants that 269 // are searched for (example, NoDuplicates) unable to be found since it 270 // won't find something of the form (a -> NoDuplicates). This can 271 // cause cases to exist, for example, the invariants (a -> b[] sorted 272 // by !=), (a -> b[] has no duplicates) existing in the same ppt where 273 // one is obviously implied by the other. I am not sure currently of 274 // the best way with dealing with this, but I am going to allow these 275 // other invariants to exist for now because they are not wrong, just 276 // obvious. 277 278 for (Invariant inv : ppt.invs) { 279 280 if ((inv instanceof EltwiseIntLessThan) || (inv instanceof EltwiseFloatLessThan)) { 281 String discardString = "The invariant holds for < which implies <=."; 282 return new DiscardInfo(this, DiscardCode.obvious, discardString); 283 } else if ((inv instanceof EltwiseIntEqual) || (inv instanceof EltwiseFloatEqual)) { 284 String discardString = "The invariant holds for == which implies <=."; 285 return new DiscardInfo(this, DiscardCode.obvious, discardString); 286 } 287 288 } 289 290 } 291 292 // sorted by (any operation) for an entire sequence -> sorted by that same 293 // operation for a subsequence 294 295 // also, sorted by < for entire -> sorted by <= for subsequence 296 // sorted by > for entire -> sorted by >= for subsequence 297 298 Derivation deriv = vis[0].derived; 299 300 if ((deriv instanceof SequenceScalarSubsequence) || (deriv instanceof SequenceFloatSubsequence)) { 301 // Find the slice with the full sequence, check for an invariant of this type 302 PptSlice sliceToCheck; 303 304 if (deriv instanceof SequenceScalarSubsequence) { 305 sliceToCheck = ppt.parent.findSlice(((SequenceScalarSubsequence)deriv).seqvar()); 306 } else { 307 sliceToCheck = ppt.parent.findSlice(((SequenceFloatSubsequence)deriv).seqvar()); 308 } 309 310 if (sliceToCheck != null) { 311 for (Invariant inv : sliceToCheck.invs) { 312 313 if ((inv instanceof EltwiseIntLessThan) || (inv instanceof EltwiseFloatLessThan)) { 314 String discardString = "This is a subsequence of a sequence for which the < invariant holds."; 315 return new DiscardInfo(this, DiscardCode.obvious, discardString); 316 } 317 318 if (inv.getClass().equals(getClass())) { 319 String discardString = "This is a subsequence of a sequence for which the same invariant holds."; 320 return new DiscardInfo(this, DiscardCode.obvious, discardString); 321 } 322 } 323 } 324 } 325 326 return null; 327 } 328}