001// ***** This file is automatically generated from NoDuplicates.java.jpp 002 003package daikon.inv.unary.sequence; 004 005import daikon.*; 006import daikon.Quantify.QuantFlags; 007import daikon.derive.binary.SequencesJoinFloat; 008import daikon.derive.binary.SequencesPredicate; 009import daikon.inv.*; 010import daikon.inv.binary.twoSequence.*; 011import daikon.inv.unary.scalar.*; 012import daikon.suppress.*; 013import java.util.*; 014import java.util.logging.*; 015import org.checkerframework.checker.interning.qual.Interned; 016import org.checkerframework.checker.lock.qual.GuardSatisfied; 017import org.checkerframework.checker.nullness.qual.Nullable; 018import org.checkerframework.dataflow.qual.Pure; 019import org.checkerframework.dataflow.qual.SideEffectFree; 020import org.plumelib.util.Intern; 021import typequals.prototype.qual.NonPrototype; 022import typequals.prototype.qual.Prototype; 023 024/** 025 * Represents sequences of double that contain no duplicate elements. Prints as 026 * {@code x[] contains no duplicates}. 027 */ 028 029public class NoDuplicatesFloat extends SingleFloatSequence { 030 static final long serialVersionUID = 20040204L; 031 032 // Variables starting with dkconfig_ should only be set via the 033 // daikon.config.Configuration interface. 034 /** Boolean. True iff NoDuplicates invariants should be considered. */ 035 public static boolean dkconfig_enabled = false; 036 037 /** Debug tracer. */ 038 public static final Logger debug = Logger.getLogger("daikon.inv.unary.sequence.NoDuplicatesFloat"); 039 040 protected NoDuplicatesFloat(PptSlice ppt) { 041 super(ppt); 042 } 043 044 protected @Prototype NoDuplicatesFloat() { 045 super(); 046 } 047 048 private static @Prototype NoDuplicatesFloat proto = new @Prototype NoDuplicatesFloat(); 049 050 /** Returns the prototype invariant for NoDuplicatesFloat */ 051 public static @Prototype NoDuplicatesFloat get_proto() { 052 return proto; 053 } 054 055 @Override 056 public boolean enabled() { 057 return dkconfig_enabled; 058 } 059 060 @Override 061 public NoDuplicatesFloat instantiate_dyn(@Prototype NoDuplicatesFloat this, PptSlice slice) { 062 return new NoDuplicatesFloat(slice); 063 } 064 065 @Override 066 public String repr(@GuardSatisfied NoDuplicatesFloat this) { 067 return "NoDuplicatesFloat" + varNames() + ": "; 068 } 069 070 @SideEffectFree 071 @Override 072 public String format_using(@GuardSatisfied NoDuplicatesFloat this, OutputFormat format) { 073 if (debug.isLoggable(Level.FINE)) { 074 debug.fine(repr()); 075 } 076 077 if (format == OutputFormat.DAIKON) { 078 return var().name() + " contains no duplicates"; 079 } 080 081 if (format == OutputFormat.SIMPLIFY) { 082 return format_simplify(); 083 } 084 085 if (format.isJavaFamily()) { 086 return format_java_family(format); 087 } 088 089 if (format == OutputFormat.CSHARPCONTRACT) { 090 return format_csharp_contract(); 091 } 092 093 return format_unimplemented(format); 094 } 095 096 public String format_simplify(@GuardSatisfied NoDuplicatesFloat this) { 097 String[] form = VarInfo.simplify_quantify(QuantFlags.distinct(), var(), 098 var()); 099 return form[0] + "(NEQ " + form[1] + " " + form[2] + ")" 100 + form[3]; 101 } 102 103 public String format_java_family(@GuardSatisfied NoDuplicatesFloat this, OutputFormat format) { 104 return "daikon.Quant.noDups(" + var().name_using(format) + ")"; 105 } 106 107 public String format_csharp_contract(@GuardSatisfied NoDuplicatesFloat this) { 108 String collection = var().csharp_collection_string(); 109 return collection + ".Distinct().Count() == " + collection + ".Count()"; 110 } 111 112 @Override 113 public InvariantStatus check_modified(double @Interned [] a, int count) { 114 // if (logDetail()) 115 // log ("sample " + Arrays.toString (a)); 116 for (int i = 1; i < a.length; i++) { 117 for (int j = 0; j < i; j++) { 118 if (Global.fuzzy.eq(a[i], a[j])) { 119 return InvariantStatus.FALSIFIED; 120 } 121 } 122 } 123 return InvariantStatus.NO_CHANGE; 124 } 125 126 @Override 127 public InvariantStatus add_modified(double @Interned [] a, int count) { 128 InvariantStatus status = check_modified(a, count); 129 if (debug.isLoggable(Level.FINE) && (status == InvariantStatus.FALSIFIED)) { 130 debug.fine("Destroying myself with: " + var().name()); 131 debug.fine(Arrays.toString(a)); 132 } 133 return status; 134 } 135 136 @Override 137 protected double computeConfidence() { 138 // num_no_dup_values() would be more appropriate 139 // return 1 - Math.pow(.9, ((PptSlice1) ppt).num_no_dup_values()); 140 return 1 - Math.pow(.9, ((PptSlice1) ppt).num_samples()); 141 } 142 143 @Pure 144 @Override 145 public @Nullable DiscardInfo isObviousStatically(VarInfo[] vis) { 146 if (!vis[0].aux.hasDuplicates()) { 147 return new DiscardInfo(this, DiscardCode.obvious, "Obvious statically"); 148 } 149 return super.isObviousStatically(vis); 150 } 151 152 /** 153 * Checks to see if this is obvious over the specified variables Implements the following checks: 154 * 155 * <pre> 156 * (A[] subsequence B[]) ^ (B[] has nodups) ⇒ A[] has nodups 157 * (A[] sorted by >) v (A[] sorted by <) ⇒ A[] has nodups 158 * </pre> 159 * 160 * JHP: The first check is not valid because we can't rely on transitive checks because of missing 161 * (if B[] is missing, A[] could have dups on those samples), 162 */ 163 @Pure 164 @Override 165 public @Nullable DiscardInfo isObviousDynamically(VarInfo[] vis) { 166 DiscardInfo super_result = super.isObviousDynamically(vis); 167 if (super_result != null) { 168 return super_result; 169 } 170 171 // If the maximum size of the array is <= 1, then this is 172 // obvious 173 ValueSet.ValueSetFloatArray vs = (ValueSet.ValueSetFloatArray) vis[0].get_value_set(); 174 if (vs.max_length() <= 1) { 175 return new DiscardInfo(this, DiscardCode.obvious, "Size of " + vis[0] 176 + " is <= " + vs.max_length()); 177 } 178 179 // For every other NoDuplicates at this program point, see if there is a 180 // subsequence relationship between that array and this one. 181 VarInfo v1 = vis[0]; 182 183 PptTopLevel parent = ppt.parent; 184 185 for (Iterator<Invariant> itor = parent.invariants_iterator(); itor.hasNext(); ) { 186 Invariant inv = itor.next(); 187 if ((inv instanceof NoDuplicatesFloat) && (inv != this) && inv.enoughSamples()) { 188 VarInfo v2 = inv.ppt.var_infos[0]; 189 if (SubSequenceFloat.isObviousSubSequenceDynamically(this, v1, v2)) { 190 // System.out.println("obvious: " + format() + " because of " + inv.format()); 191 log("Obvious- Obvious sub sequence with %s", inv.format()); 192 return new DiscardInfo(this, DiscardCode.obvious, "Invariant holds over a supersequence"); 193 } 194 } 195 } 196 197 // If the sequence is sorted by < or >, then there are obviously no duplicates 198 199 PptSlice slice = this.ppt.parent.findSlice_unordered(vis); 200 if (slice != null) { 201 for (Invariant inv : slice.invs) { 202 if ((inv instanceof EltwiseIntLessThan) 203 || (inv instanceof EltwiseFloatLessThan) 204 || (inv instanceof EltwiseIntGreaterThan) 205 || (inv instanceof EltwiseFloatGreaterThan)) { 206 return new DiscardInfo(this, DiscardCode.obvious, "Sequence is sorted: " + inv.format()); 207 } 208 } 209 } 210 211 return null; 212 } 213 214 @Pure 215 @Override 216 public boolean isSameFormula(Invariant other) { 217 assert other instanceof NoDuplicatesFloat; 218 return true; 219 } 220}