001// ***** This file is automatically generated from SequencesJoin.java.jpp 002 003package daikon.derive.binary; 004 005import org.checkerframework.checker.lock.qual.GuardSatisfied; 006import org.checkerframework.dataflow.qual.Pure; 007import org.checkerframework.dataflow.qual.SideEffectFree; 008import daikon.*; 009import daikon.derive.*; 010import java.util.logging.Level; 011import java.util.logging.Logger; 012import org.plumelib.util.Intern; 013 014/** 015 * Derived variable representing the "join" of two sequences. That is, if the two sequences came 016 * from the same original data structure (like an array of multi-field objects) then we join the two 017 * sequences and generate a hashcode of the join value. This allows us to detect uniqueness and 018 * equality style invariants across the data structure rather than just one slice of it. Works for 019 * number and string arrays. 020 */ 021public final class SequencesJoinFloat extends BinaryDerivation { 022 static final long serialVersionUID = 20020122L; 023 024 /** Debug tracer. */ 025 public static final Logger debug = Logger.getLogger("daikon.derive.binary.SequencesJoinFloat"); 026 027 // Variables starting with dkconfig_ should only be set via the 028 // daikon.config.Configuration interface. 029 /** Boolean. True iff SequencesJoin derived variables should be generated. */ 030 public static boolean dkconfig_enabled = false; 031 032 @Override 033 public VarInfo var1(@GuardSatisfied SequencesJoinFloat this) { 034 return base1; 035 } 036 037 @Override 038 public VarInfo var2(@GuardSatisfied SequencesJoinFloat this) { 039 return base2; 040 } 041 042 /** 043 * Create a new SequencesJoin derivation. 044 * 045 * @param vi1 the first of the two variables this is based on 046 * @param vi2 the second of the two variables this is based on 047 */ 048 SequencesJoinFloat(VarInfo vi1, VarInfo vi2) { 049 super(vi1, vi2); 050 } 051 052 /** 053 * Returns a new sequence of hashcodes that is the join of the hashcodes of the component 054 * sequences. This is modified whenever either component sequence is modified. 055 * 056 * @param full_vt the value tuple of a program point to compute the derived value from 057 */ 058 @Override 059 public ValueAndModified computeValueAndModifiedImpl(ValueTuple full_vt) { 060 Object val1 = var1().getValue(full_vt); 061 Object val2 = var2().getValue(full_vt); 062 063 int length1 = -1; 064 int length2 = -2; // They must equal in the end 065 066 if (val1 == null) { 067 length1 = 0; 068 } 069 070 if (val2 == null) { 071 length2 = 0; 072 } 073 074 if (val1 instanceof double[]) { 075 length1 = ((double[]) val1).length; 076 } 077 078 if (val2 instanceof double[]) { 079 length2 = ((double[]) val2).length; 080 } 081 082 if (val1 instanceof double[]) { 083 length1 = ((double[]) val1).length; 084 } 085 086 if (val2 instanceof double[]) { 087 length2 = ((double[]) val2).length; 088 } 089 090 assert length1 == length2; 091 092 double[] result = new double[length1]; 093 094 for (int i = 0; i < length1; i++) { 095 Object e1 = null; 096 Object e2 = null; 097 if (val1 instanceof double[]) { 098 e1 = Double.valueOf(((double[]) val1)[i]); 099 } 100 if (val2 instanceof double[]) { 101 e2 = Double.valueOf(((double[]) val2)[i]); 102 } 103 if (val1 instanceof Object[]) { 104 e1 = ((Object[]) val1)[i]; 105 } 106 if (val2 instanceof Object[]) { 107 e2 = ((Object[]) val2)[i]; 108 } 109 if (e1 == null) { 110 e1 = Double.valueOf(0); 111 } 112 if (e2 == null) { 113 e2 = Double.valueOf(0); 114 } 115 // Loses top 8 bits, but we're just mixing two hashCodes. 116 result[i] = ((long) e1.hashCode() << 8L) + e2.hashCode(); 117 } 118 119 /* 120 Use this if you don't see no duplicates where you should 121 if (debug.isLoggable(Level.FINE)) { 122 debug.fine(var1().name.toString() + " " + var2().name.toString()); 123 if (val1 instanceof double[]) { 124 debug.fine(Arrays.toString((double[]) val1)); 125 } else { 126 debug.fine(Arrays.toString((Object[]) val1)); 127 } 128 if (val2 instanceof double[]) { 129 debug.fine(Arrays.toString((double[]) val2)); 130 } else { 131 debug.fine(Arrays.toString((Object[]) val2)); 132 } 133 debug.fine(Arrays.toString(result)); 134 135 } 136 */ 137 138 int mod = ValueTuple.UNMODIFIED; 139 int mod1 = var1().getModified(full_vt); 140 int mod2 = var2().getModified(full_vt); 141 142 if (mod1 == ValueTuple.MODIFIED) { 143 mod = ValueTuple.MODIFIED; 144 } 145 if (mod2 == ValueTuple.MODIFIED) { 146 mod = ValueTuple.MODIFIED; 147 } 148 if (mod1 == ValueTuple.MISSING_NONSENSICAL) { 149 mod = ValueTuple.MISSING_NONSENSICAL; 150 } 151 if (mod2 == ValueTuple.MISSING_NONSENSICAL) { 152 mod = ValueTuple.MISSING_NONSENSICAL; 153 } 154 /* 155 * v1\v2 Unm Mod Mis 156 * 157 * Unm Unm Mod Mis 158 * Mod Mod Mod Mis 159 * Mis Mis Mis Mis 160 */ 161 162 return new ValueAndModified(Intern.intern(result), mod); 163 } 164 165 @Override 166 protected VarInfo makeVarInfo() { 167 VarInfo var1 = var1(); 168 VarInfo var2 = var2(); 169 170 VarInfo vi = VarInfo.make_function("join", var1, var2); 171 172 // Set the declared type and file rep types 173 String newTypeName = "Join(" + var1.type.toString() + "," + var2.type.toString() + ")"; 174 vi.type = ProglangType.parse(newTypeName + "[]"); 175 if (debug.isLoggable(Level.FINE)) { 176 debug.fine("New decl type is " + vi.type.toString()); 177 } 178 vi.file_rep_type = ProglangType.HASHCODE_ARRAY; 179 180 // Generate a new comparability based on base comparabilities' indices 181 vi.comparability = 182 VarComparability.makeComparabilitySameIndices(newTypeName, var1.comparability); 183 184 return vi; 185 } 186 187 @SideEffectFree 188 @Override 189 public String toString(@GuardSatisfied SequencesJoinFloat this) { 190 return "[SequencesJoinFloat of " + var1().name() + " " + var2().name() + "]"; 191 } 192 193 @Pure 194 @Override 195 public boolean isSameFormula(Derivation other) { 196 return (other instanceof SequencesJoinFloat); 197 } 198 199 @SideEffectFree 200 @Override 201 public String esc_name(String index) { 202 return String.format("join[%s,%s]", var1().esc_name(), var2().esc_name()); 203 } 204}