001// ***** This file is automatically generated from Reverse.java.jpp
002
003package daikon.inv.binary.twoSequence;
004
005import daikon.*;
006import daikon.inv.*;
007import java.util.logging.Logger;
008import org.checkerframework.checker.interning.qual.Interned;
009import org.checkerframework.checker.lock.qual.GuardSatisfied;
010import org.checkerframework.dataflow.qual.Pure;
011import org.checkerframework.dataflow.qual.SideEffectFree;
012import org.plumelib.util.Intern;
013import typequals.prototype.qual.NonPrototype;
014import typequals.prototype.qual.Prototype;
015
016/**
017 * Represents two sequences of double where one is in the reverse order of the other. Prints as
018 * {@code x[] is the reverse of y[]}.
019 */
020public class ReverseFloat extends TwoSequenceFloat {
021  static final long serialVersionUID = 20030822L;
022
023  public static final Logger debug =
024    Logger.getLogger("daikon.inv.binary.twoSequence.ReverseFloat");
025
026  // Variables starting with dkconfig_ should only be set via the
027  // daikon.config.Configuration interface.
028  /** Boolean. True iff Reverse invariants should be considered. */
029  public static boolean dkconfig_enabled = Invariant.invariantEnabledDefault;
030
031  protected ReverseFloat(PptSlice ppt) {
032    super(ppt);
033  }
034
035  protected @Prototype ReverseFloat() {
036    super();
037  }
038
039  private static @Prototype ReverseFloat proto = new @Prototype ReverseFloat();
040
041  /** Returns the prototype invariant for ReverseFloat. */
042  public static @Prototype ReverseFloat get_proto() {
043    return proto;
044  }
045
046  @Override
047  public boolean enabled() {
048    return dkconfig_enabled;
049  }
050
051  /** Reverse only makes sense on ordered arrays. */
052  @Override
053  public boolean instantiate_ok(VarInfo[] vis) {
054
055    if (!valid_types(vis)) {
056      return false;
057    }
058
059    // Check to see that both arrays are ordered
060    if (!vis[0].aux.hasOrder() || !vis[1].aux.hasOrder()) {
061      return false;
062    }
063
064    return true;
065  }
066
067  @Override
068  public ReverseFloat instantiate_dyn(@Prototype ReverseFloat this, PptSlice slice) {
069    return new ReverseFloat(slice);
070  }
071
072  @Override
073  protected Invariant resurrect_done_swapped() {
074    // "reverse of" is symmetric
075    return this;
076  }
077
078  @Override
079  public String repr(@GuardSatisfied ReverseFloat this) {
080    return "ReverseFloat" + varNames() + ": falsified=" + falsified;
081  }
082
083  @SideEffectFree
084  @Override
085  public String format_using(@GuardSatisfied ReverseFloat this, OutputFormat format) {
086    if (format.isJavaFamily()) {
087      return format_java_family(format);
088    }
089
090    if (format == OutputFormat.DAIKON) {
091      return format_daikon();
092    }
093    if (format == OutputFormat.CSHARPCONTRACT) {
094      return format_csharp();
095    }
096    if (format == OutputFormat.SIMPLIFY) {
097      return format_simplify();
098    }
099
100    return format_unimplemented(format);
101  }
102
103  public String format_daikon(@GuardSatisfied ReverseFloat this) {
104    return var1().name() + " is the reverse of " + var2().name();
105  }
106
107  public String format_java_family(@GuardSatisfied ReverseFloat this, OutputFormat format) {
108          return "daikon.Quant.isReverse(" + var1().name_using(format)
109            + ", " + var2().name_using(format) + ")";
110  }
111
112  public String format_csharp(@GuardSatisfied ReverseFloat this) {
113    String[] split1 = var1().csharp_array_split();
114    String[] split2 = var2().csharp_array_split();
115    return "Contract.ForAll(0, " + split1[0] + ".Count(), i => " + split1[0] + "[i]"  + split1[1] + ".Equals(" + split2[0] + "[" +split1[0] + ".Count()-1-i]" + split2[1] +"))";
116  }
117
118  public String format_simplify(@GuardSatisfied ReverseFloat this) {
119    if (Invariant.dkconfig_simplify_define_predicates) {
120      return format_simplify_defined();
121    } else {
122      return format_simplify_explicit();
123    }
124  }
125
126  private String format_simplify_defined(@GuardSatisfied ReverseFloat this) {
127    VarInfo onevar = var1();
128    VarInfo othervar = var2();
129    String[] one_name = onevar.simplifyNameAndBounds();
130    String[] other_name = othervar.simplifyNameAndBounds();
131
132    if (one_name == null || other_name == null) {
133      return "format_simplify() can't handle one of these sequences: " + format();
134    }
135
136    return "(|is-reverse-of| "
137      + one_name[0] + " " + one_name[1] + " " + one_name[2] + " "
138      + other_name[0] + " " + other_name[1] + " " + other_name[2] + ")";
139  }
140
141  private String format_simplify_explicit(@GuardSatisfied ReverseFloat this) {
142    VarInfo onevar = var1();
143    VarInfo othervar = var2();
144    String[] one_name = onevar.simplifyNameAndBounds();
145    String[] other_name = othervar.simplifyNameAndBounds();
146
147    if (one_name == null || other_name == null) {
148      return "format_simplify() can't handle one of these sequences: " + format();
149    }
150
151    String index = VarInfo.get_simplify_free_index(onevar, othervar);
152
153    // (FORALL (a i j b ip jp)
154    //  (IFF (|is-reverse-of| a i j b ip jp)
155    //   (AND (EQ (- j i) (- jp ip))
156    //        (<= 0 i)
157    //        (< j (arrayLength a))
158    //        (<= 0 ip)
159    //        (< jp (arrayLength b))
160    //     (FORALL (x)
161    //        (IMPLIES
162    //            (AND (<= 0 x) (< x (- j i)))
163    //            (EQ (select (select elems a) (+ i x))
164    //                (select (select elems b) (- jp x))))))))
165
166    return "(AND (EQ (- " + one_name[2] + " " + one_name[1] + ") (- "
167      + other_name[2] + " " + other_name[1] + ")) (<= 0 " + one_name[1]
168      + ") (< " + one_name[2] + " (arrayLength " + one_name[0]
169      + ")) (<= 0 " + other_name[1] + ") (< " + other_name[2]
170      + " (arrayLength " + other_name[0] + ")) (FORALL (" + index
171      + ") (IMPLIES (AND (<= 0 " + index + ") (< " + index + " (- "
172      + one_name[2] + " " + one_name[1] + "))) (EQ (select (select elems "
173      + one_name[0] + ") (+ " + one_name[1] + " " + index
174      + ")) (select (select elems " + other_name[0] + ") (- " + other_name[2]
175      + " " + index + "))))))";
176  }
177
178  @Override
179  public InvariantStatus check_modified(double @Interned [] a1, double @Interned [] a2, int count) {
180    if (a1.length != a2.length) {
181      return InvariantStatus.FALSIFIED;
182    }
183    int len = a1.length;
184    for (int i = 0, j = len - 1; i < len; i++, j--) {
185      if (!Global.fuzzy.eq(a1[i], a2[j])) {
186        return InvariantStatus.FALSIFIED;
187      }
188    }
189    return InvariantStatus.NO_CHANGE;
190  }
191
192  @Override
193  public InvariantStatus add_modified(double @Interned [] a1, double @Interned [] a2, int count) {
194    return check_modified(a1, a2, count);
195  }
196
197  @Override
198  protected double computeConfidence() {
199    return Invariant.CONFIDENCE_JUSTIFIED;
200  }
201
202  @Pure
203  @Override
204  public boolean isSameFormula(Invariant other) {
205    assert other instanceof ReverseFloat;
206    return true;
207  }
208}