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