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