aboutsummaryrefslogtreecommitdiffstats
path: root/src/SMT_terms.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMT_terms.v')
-rw-r--r--src/SMT_terms.v1666
1 files changed, 1503 insertions, 163 deletions
diff --git a/src/SMT_terms.v b/src/SMT_terms.v
index 65c0d8f..c411c99 100644
--- a/src/SMT_terms.v
+++ b/src/SMT_terms.v
@@ -1,22 +1,20 @@
(**************************************************************************)
(* *)
(* SMTCoq *)
-(* Copyright (C) 2011 - 2016 *)
+(* Copyright (C) 2011 - 2019 *)
(* *)
-(* Michaël Armand *)
-(* Benjamin Grégoire *)
-(* Chantal Keller *)
-(* *)
-(* Inria - École Polytechnique - Université Paris-Sud *)
+(* See file "AUTHORS" for the list of authors *)
(* *)
(* This file is distributed under the terms of the CeCILL-C licence *)
(* *)
(**************************************************************************)
-Require Import Bool List Int63 PArray.
-Require Import Misc State.
-
+Require Import Bool Int63 PArray BinPos SMT_classes_instances.
+Require Import Misc State BVList. (* FArray Equalities DecidableTypeEx. *)
+Require FArray.
+Require List .
+Local Open Scope list_scope.
Local Open Scope array_scope.
Local Open Scope int63_scope.
@@ -40,7 +38,16 @@ Module Form.
| Fimp (_:fargs)
| Fxor (_:_lit) (_:_lit)
| Fiff (_:_lit) (_:_lit)
- | Fite (_:_lit) (_:_lit) (_:_lit).
+ | Fite (_:_lit) (_:_lit) (_:_lit)
+ (* Bit-blasting predicate (theory of bit vectors):
+ bbT a [l1;...;ln] means [l1;...;ln] is the bitwise representation of a
+ (in little endian)
+ WARNING: this is a slight infringement of stratification
+ *)
+ | FbbT (_:atom) (_:list _lit)
+ (* TODO: replace [list _lit] with [fargs] *)
+ .
+
Definition is_Ftrue h :=
match h with Ftrue => true | _ => false end.
@@ -49,13 +56,15 @@ Module Form.
match h with Ffalse => true | _ => false end.
Lemma is_Ftrue_correct : forall h, is_Ftrue h -> h = Ftrue.
- Proof. destruct h;trivial;discriminate. Qed.
+ Proof. destruct h; trivial;discriminate. Qed.
Lemma is_Ffalse_correct : forall h, is_Ffalse h -> h = Ffalse.
Proof. destruct h;trivial;discriminate. Qed.
+
Section Interp.
Variable interp_atom : atom -> bool.
+ Variable interp_bvatom : atom -> forall s, BITVECTOR_LIST.bitvector s.
Section Interp_form.
@@ -79,6 +88,10 @@ Module Form.
| Fite a b c =>
if Lit.interp interp_var a then Lit.interp interp_var b
else Lit.interp interp_var c
+ | FbbT a ls =>
+ let ils := List.map (Lit.interp interp_var) ls in
+ let n := N.of_nat (List.length ils) in
+ BITVECTOR_LIST.bv_eq (interp_bvatom a n) (BITVECTOR_LIST.of_bits ils)
end.
End Interp_form.
@@ -88,7 +101,7 @@ Module Form.
Variable t_form : PArray.array form.
Definition t_interp : PArray.array bool :=
- PArray.foldi_left (fun i t_b hf =>
+ PArray.foldi_left (fun i t_b hf =>
t_b.[i <- interp_aux (PArray.get t_b) hf])
(PArray.make (PArray.length t_form) true) t_form.
@@ -98,8 +111,9 @@ Module Form.
| Fnot2 _ l => Lit.blit l < i
| Fand args | For args | Fimp args =>
PArray.forallb (fun l => Lit.blit l < i) args
- | Fxor a b | Fiff a b => (Lit.blit a < i) && (Lit.blit b < i)
+ | Fxor a b | Fiff a b => (Lit.blit a < i) && (Lit.blit b < i)
| Fite a b c => (Lit.blit a < i) && (Lit.blit b < i) && (Lit.blit c < i)
+ | FbbT _ ls => List.forallb (fun l => Lit.blit l < i) ls
end.
Lemma lt_form_interp_form_aux :
@@ -112,16 +126,19 @@ Module Form.
try (apply afold_left_eq;unfold is_true in H0;
rewrite PArray.forallb_spec in H0;intros;
auto using Lit.interp_eq_compat).
- f_equal;auto using Lit.interp_eq_compat.
- apply afold_right_eq;unfold is_true in H0;
- rewrite PArray.forallb_spec in H0;intros;
- auto using Lit.interp_eq_compat.
- unfold is_true in H0;rewrite !andb_true_iff in H0;decompose [and] H0;
- rewrite !(Lit.interp_eq_compat f1 f2);auto.
- unfold is_true in H0;rewrite !andb_true_iff in H0;decompose [and] H0;
- rewrite !(Lit.interp_eq_compat f1 f2);auto.
- unfold is_true in H0;rewrite !andb_true_iff in H0;decompose [and] H0;
- rewrite !(Lit.interp_eq_compat f1 f2);auto.
+ - f_equal;auto using Lit.interp_eq_compat.
+ - apply afold_right_eq;unfold is_true in H0;
+ rewrite PArray.forallb_spec in H0;intros;
+ auto using Lit.interp_eq_compat.
+ - unfold is_true in H0;rewrite !andb_true_iff in H0;decompose [and] H0;
+ rewrite !(Lit.interp_eq_compat f1 f2);auto.
+ - unfold is_true in H0;rewrite !andb_true_iff in H0;decompose [and] H0;
+ rewrite !(Lit.interp_eq_compat f1 f2);auto.
+ - unfold is_true in H0;rewrite !andb_true_iff in H0;decompose [and] H0;
+ rewrite !(Lit.interp_eq_compat f1 f2);auto.
+ - replace (List.map (Lit.interp f2) l) with (List.map (Lit.interp f1) l); auto.
+ unfold is_true in H0. rewrite List.forallb_forall in H0.
+ apply List_map_ext_in. intros x Hx. apply Lit.interp_eq_compat; auto.
Qed.
Definition wf := PArray.forallbi lt_form t_form.
@@ -227,98 +244,160 @@ Module Form.
End Form.
-(* TODO Move this *)
-Record typ_eqb : Type := Typ_eqb {
- te_carrier : Type;
- te_eqb : te_carrier -> te_carrier -> bool;
- te_reflect : forall x y, reflect (x = y) (te_eqb x y)
-}.
-
-Section Typ_eqb_param.
-
- Variable A : Type.
- Variable r : { eq : A -> A -> bool & forall x y, reflect (x = y) (eq x y) }.
-
- Definition typ_eqb_of_typ_eqb_param : typ_eqb :=
- Typ_eqb A (projT1 r) (projT2 r).
-
-End Typ_eqb_param.
-
-(* Common used types into which we interpret *)
-
-(* Unit *)
-Section Unit_typ_eqb.
+Require OrderedTypeEx.
- Let carrier : Type := unit.
-
- Let eqb : carrier -> carrier -> bool :=
- fun _ _ => true.
-
- Lemma unit_reflect :
- forall x y, reflect (x = y) (eqb x y).
- Proof.
- unfold eqb; intros x y; case x; case y; simpl;
- constructor; reflexivity.
- Qed.
-
- Definition unit_typ_eqb :=
- Typ_eqb carrier eqb unit_reflect.
-
-End Unit_typ_eqb.
-(* End TODO *)
Module Typ.
+ Import FArray.
+
Notation index := int (only parsing).
Inductive type :=
+ | TFArray : type -> type -> type
| Tindex : index -> type
| TZ : type
| Tbool : type
- | Tpositive : type.
+ | Tpositive : type
+ | TBV : N -> type.
Definition ftype := (list type * type)%type.
Section Interp.
- Variable t_i : PArray.array typ_eqb.
+ Import OrderedTypeEx.
+
+ Variable t_i : PArray.array typ_compdec.
- Definition interp t :=
+ Fixpoint interp_compdec_aux (t:type) : {ty: Type & CompDec ty} :=
match t with
- | Tindex i => (t_i.[i]).(te_carrier)
- | TZ => Z
- | Tbool => bool
- | Tpositive => positive
+ | TFArray ti te =>
+ existT (fun ty : Type => CompDec ty)
+ (@farray (type_compdec (projT2 (interp_compdec_aux ti)))
+ (type_compdec (projT2 (interp_compdec_aux te)))
+ (@ord_of_compdec _ (projT2 (interp_compdec_aux ti)))
+ (@inh_of_compdec _ (projT2 (interp_compdec_aux te))))
+ (FArray_compdec
+ (type_compdec (projT2 (interp_compdec_aux ti)))
+ (type_compdec (projT2 (interp_compdec_aux te))))
+ | Tindex i =>
+ existT (fun ty : Type => CompDec ty)
+ (te_carrier (t_i .[ i])) (te_compdec (t_i .[ i]))
+ | TZ => existT (fun ty : Type => CompDec ty) Z Z_compdec
+ | Tbool => existT (fun ty : Type => CompDec ty) bool bool_compdec
+ | Tpositive => existT (fun ty : Type => CompDec ty) positive Positive_compdec
+ | TBV n => existT (fun ty : Type => CompDec ty) (BITVECTOR_LIST.bitvector n) (BV_compdec n)
end.
+ Definition interp_compdec (t:type) : CompDec (projT1 (interp_compdec_aux t)) :=
+ projT2 (interp_compdec_aux t).
+
+ Definition interp (t:type) : Type := type_compdec (interp_compdec t).
+
+
Definition interp_ftype (t:ftype) :=
- List.fold_right (fun dom codom =>interp dom -> codom)
+ List.fold_right (fun dom codom => interp dom -> codom)
(interp (snd t)) (fst t).
+
+ Definition dec_interp (t:type) : DecType (interp t).
+ destruct (interp_compdec t).
+ subst ty.
+ apply Decidable.
+ Defined.
+
+ Instance comp_interp (t:type) : Comparable (interp t).
+ destruct (interp_compdec t).
+ subst ty.
+ apply Comp.
+ Defined.
+
+ Instance ord_interp (t:type) : OrdType (interp t).
+ destruct (interp_compdec t).
+ subst ty.
+ apply Ordered.
+ Defined.
+
+
+ Definition inh_interp (t:type) : Inhabited (interp t).
+ unfold interp.
+ destruct (interp_compdec t).
+ apply Inh.
+ Defined.
+
+ Definition inhabitant_interp (t:type) : interp t := default_value.
+
+
+ Hint Resolve
+ dec_interp comp_interp ord_interp
+ inh_interp interp_compdec : typeclass_instances.
+
+
(* Boolean equality over interpretation of a btype *)
Section Interp_Equality.
+
Definition i_eqb (t:type) : interp t -> interp t -> bool :=
- match t with
- | Tindex i => (t_i.[i]).(te_eqb)
- | TZ => Z.eqb
- | Tbool => Bool.eqb
- | Tpositive => Peqb
- end.
+ eqb_of_compdec (interp_compdec t).
+
+
+ Lemma eqb_compdec_spec {t} (c : CompDec t) : forall x y,
+ eqb_of_compdec c x y = true <-> x = y.
+ intros.
+ destruct c.
+ destruct Eqb.
+ simpl.
+ auto.
+ Qed.
+
+ Lemma eqb_compdec_spec_false {t} (c : CompDec t) : forall x y,
+ eqb_of_compdec c x y = false <-> x <> y.
+ intros.
+ destruct c.
+ destruct Eqb.
+ simpl.
+ split. intros.
+ unfold not. intros.
+ apply eqb_spec in H0.
+ rewrite H in H0. now contradict H0.
+ intros. unfold not in H.
+ rewrite <- not_true_iff_false.
+ unfold not. intros.
+ apply eqb_spec in H0.
+ apply H in H0. now contradict H0.
+ Qed.
Lemma i_eqb_spec : forall t x y, i_eqb t x y <-> x = y.
Proof.
- destruct t;simpl;intros.
- symmetry;apply reflect_iff;apply te_reflect.
- apply Z.eqb_eq.
- apply Bool.eqb_true_iff.
- apply Peqb_eq.
+ intros.
+ unfold i_eqb.
+ apply eqb_compdec_spec.
+ Qed.
+
+ Lemma i_eqb_spec_false : forall t x y, i_eqb t x y = false <-> x <> y.
+ Proof.
+ intros.
+ unfold i_eqb.
+ apply eqb_compdec_spec_false.
Qed.
+ Lemma reflect_eqb_compdec {t} (c : CompDec t) : forall x y,
+ reflect (x = y) (eqb_of_compdec c x y).
+ intros.
+ destruct c.
+ destruct Eqb.
+ simpl in *.
+ apply iff_reflect.
+ symmetry; auto.
+ Qed.
+
+
Lemma reflect_i_eqb : forall t x y, reflect (x = y) (i_eqb t x y).
Proof.
- intros;apply iff_reflect;symmetry;apply i_eqb_spec.
+ intros.
+ unfold i_eqb.
+ apply reflect_eqb_compdec.
Qed.
Lemma i_eqb_sym : forall t x y, i_eqb t x y = i_eqb t y x.
@@ -328,6 +407,67 @@ Module Typ.
rewrite is_true_iff in *; now rewrite i_eqb_spec in *.
Qed.
+
+ (* Lemma i_eqb_compdec_tbv (c: CompDec): forall x y, TBV x y = BITVECTOR_LIST_FIXED.bv_eq x y. *)
+ (* Proof. *)
+
+ Definition i_eqb_eqb (t:type) : interp t -> interp t -> bool :=
+ match t with
+ | Tindex i => eqb_of_compdec (t_i.[i]).(te_compdec)
+ | TZ => Z.eqb (* Zeq_bool *)
+ | Tbool => Bool.eqb
+ | Tpositive => Peqb
+ | TBV n => (@BITVECTOR_LIST.bv_eq n)
+ | TFArray ti te => i_eqb (TFArray ti te)
+ end.
+
+
+ Lemma eqb_compdec_refl {t} (c : CompDec t) : forall x,
+ eqb_of_compdec c x x = true.
+ intros.
+ destruct c.
+ destruct Eqb.
+ simpl.
+ apply eqb_spec. auto.
+ Qed.
+
+ Lemma i_eqb_refl : forall t x, i_eqb t x x.
+ Proof.
+ intros.
+ unfold i_eqb.
+ apply eqb_compdec_refl.
+ Qed.
+
+
+ Lemma eqb_compdec_trans {t} (c : CompDec t) : forall x y z,
+ eqb_of_compdec c x y = true ->
+ eqb_of_compdec c y z = true ->
+ eqb_of_compdec c x z = true .
+ intros.
+ destruct c.
+ destruct Eqb.
+ simpl in *.
+ apply eqb_spec.
+ apply eqb_spec in H.
+ apply eqb_spec in H0.
+ subst; auto.
+ Qed.
+
+ Lemma i_eqb_trans : forall t x y z, i_eqb t x y -> i_eqb t y z -> i_eqb t x z.
+ Proof.
+ intros.
+ unfold i_eqb.
+ apply (eqb_compdec_trans _ x y z); auto.
+ Qed.
+
+
+ Lemma i_eqb_t : forall t x y, i_eqb t x y = i_eqb_eqb t x y.
+ Proof.
+ intros.
+ unfold i_eqb_eqb.
+ destruct t; simpl; auto; unfold i_eqb; simpl.
+ Qed.
+
End Interp_Equality.
End Interp.
@@ -355,34 +495,94 @@ Module Typ.
Notation idcast := (Cast (fun P x => x)).
(* La fonction cast calcule cast_result *)
- Definition cast (A B: type) : cast_result A B :=
+ Fixpoint positive_cast (n m : positive) {struct n} :
+ option (forall P, P n -> P m) :=
+ match n, m return option (forall P, P n -> P m) with
+ | xH, xH => Some (fun P x => x)
+ | xO p, xO q =>
+ match positive_cast p q with
+ | Some k => Some (fun P => k (fun y => P (xO y)))
+ | None => None
+ end
+ | xI p, xI q =>
+ match positive_cast p q with
+ | Some k => Some (fun P => k (fun y => P (xI y)))
+ | None => None
+ end
+ | _, _ => None
+ end.
+
+ Definition N_cast (n m : N) : option (forall P, P n -> P m) :=
+ match n, m return option (forall P, P n -> P m) with
+ | N0, N0 => Some (fun P x => x)
+ | Npos p, Npos q =>
+ match positive_cast p q with
+ | Some k => Some (fun P => k (fun y => P (Npos y)))
+ | None => None
+ end
+ | _, _ => None
+ end.
+
+
+ (* TODO *)
+
+ Fixpoint cast (A B: type) : cast_result A B :=
match A as C, B as D return cast_result C D with
| Tindex i, Tindex j =>
- match cast i j with
+ match Int63Op.cast i j with
| Some k => Cast (fun P => k (fun y => P (Tindex y)))
| None => NoCast
end
| TZ, TZ => idcast
| Tbool, Tbool => idcast
| Tpositive, Tpositive => idcast
+ | TBV n, TBV m =>
+ match N_cast n m with
+ | Some k => Cast (fun P => k (fun y => P (TBV y)))
+ | None => NoCast
+ end
+ | TFArray k1 e1, TFArray k2 e2 =>
+ match cast k1 k2, cast e1 e2 with
+ | Cast kk, Cast ke =>
+ let ka P :=
+ let Pb d := P (TFArray d e1) in
+ let Pc d := P (TFArray k2 d) in
+ fun x => ke Pc (kk Pb x)
+ in Cast ka
+ | _, _ => NoCast
+ end
| _, _ => NoCast
end.
- Lemma cast_refl:
- forall A, cast A A = Cast (fun P (H : P A) => H).
+ Lemma positive_cast_refl:
+ forall p, positive_cast p p = Some (fun P (H : P p) => H).
+ Proof. induction p as [p IHp|p IHp| ]; simpl; try rewrite IHp; auto. Qed.
+
+ Lemma N_cast_refl:
+ forall n, N_cast n n = Some (fun P (H : P n) => H).
+ Proof. intros [ |p]; simpl; try rewrite positive_cast_refl; auto. Qed.
+
+ Fixpoint cast_refl A:
+ cast A A = Cast (fun P (H : P A) => H).
Proof.
- intros A0;destruct A0;simpl;trivial.
- rewrite cast_refl;trivial.
+ destruct A;simpl;trivial.
+ do 2 rewrite cast_refl. easy.
+ rewrite Int63Properties.cast_refl;trivial.
+ rewrite N_cast_refl;trivial.
Qed.
+
(* Remark : I use this definition because eqb will not be used only in the interpretation *)
- Definition eqb (A B: type) : bool :=
+ Fixpoint eqb (A B: type) : bool :=
match A, B with
| Tindex i, Tindex j => i == j
| TZ, TZ => true
| Tbool, Tbool => true
| Tpositive, Tpositive => true
- | _, _ => false
+ | TBV n, TBV m => N.eqb n m
+ | TFArray k1 e1, TFArray k2 e2 =>
+ eqb k1 k2 && eqb e1 e2
+ | _,_ => false
end.
@@ -398,10 +598,43 @@ Module Typ.
Lemma not_is_true_eq_false : forall b:bool, ~ b <-> b = false.
Proof. exact not_true_iff_false. Qed.
- Lemma cast_diff: forall A B, eqb A B = false -> cast A B = NoCast.
+ Lemma positive_cast_diff: forall p q, p <> q -> positive_cast p q = None.
+ Proof.
+ induction p as [p IHp|p IHp| ]; intros [q|q| ]; auto; intro Heq.
+ - simpl. rewrite IHp; auto.
+ intro H. apply Heq. rewrite H. reflexivity.
+ - simpl. rewrite IHp; auto.
+ intro H. apply Heq. rewrite H. reflexivity.
+ - elim Heq. reflexivity.
+ Qed.
+
+ Lemma N_cast_diff: forall n m, n <> m -> N_cast n m = None.
Proof.
- intros A0 B0;destruct A0; destruct B0;simpl;trivial;try discriminate.
- intros Heq;rewrite (cast_diff _ _ Heq);trivial.
+ intros [ |n] [ |m]; auto; intro Heq.
+ - elim Heq; reflexivity.
+ - simpl. rewrite positive_cast_diff; auto.
+ intro H. apply Heq. rewrite H. reflexivity.
+ Qed.
+
+ Fixpoint cast_diff A B: eqb A B = false -> cast A B = NoCast.
+ Proof.
+ destruct A; destruct B;simpl;trivial;try discriminate.
+ intros.
+ rewrite andb_false_iff in H.
+ destruct H; apply cast_diff in H; rewrite H; auto.
+ case (cast A1 B1); auto.
+ intros H. rewrite (Int63Properties.cast_diff _ _ H);trivial.
+ rewrite N.eqb_neq. intro Heq. now rewrite N_cast_diff.
+ Qed.
+
+ Lemma cast_eqb A B k: cast A B = Cast k -> eqb A B = true.
+ Proof.
+ intros.
+ apply not_false_iff_true.
+ unfold not.
+ intro.
+ apply cast_diff in H0.
+ rewrite H in H0. inversion H0.
Qed.
Lemma neq_cast : forall A B,
@@ -410,22 +643,65 @@ Module Typ.
intros C D;case_eq (eqb C D);trivial;apply cast_diff.
Qed.
- Lemma reflect_eqb : forall x y, reflect (x = y) (eqb x y).
+ Fixpoint reflect_eqb x y: reflect (x = y) (eqb x y).
Proof.
- intros x y;destruct x;destruct y;simpl;try constructor;trivial;try discriminate.
- apply iff_reflect;rewrite eqb_spec;split;intros H;[inversion H | subst];trivial.
+ destruct x;destruct y;simpl;try constructor;trivial;try discriminate.
+ apply iff_reflect.
+ split.
+ intro H. inversion H. subst.
+ rewrite andb_true_iff.
+ split;
+ [specialize (reflect_eqb y1 y1) | specialize (reflect_eqb y2 y2)];
+ apply reflect_iff in reflect_eqb; apply reflect_eqb; auto.
+ intros.
+ rewrite andb_true_iff in H; destruct H.
+ apply (reflect_iff _ _ (reflect_eqb x1 y1)) in H.
+ apply (reflect_iff _ _ (reflect_eqb x2 y2)) in H0.
+ subst; auto.
+ apply iff_reflect;rewrite Int63Properties.eqb_spec;split;intros H;[inversion H | subst]; trivial.
+ apply iff_reflect. rewrite N.eqb_eq. split;intros H;[inversion H | subst]; trivial.
Qed.
Lemma eqb_spec : forall x y, eqb x y <-> x = y.
Proof.
- intros;symmetry;apply reflect_iff;apply reflect_eqb.
+ intros.
+ symmetry.
+ apply reflect_iff.
+ apply reflect_eqb.
Qed.
Lemma eqb_refl : forall x, eqb x x.
Proof. intros; rewrite eqb_spec; auto. Qed.
+
+ Lemma cast_eq A B k: cast A B = Cast k -> A = B.
+ Proof.
+ intros. apply eqb_spec. apply (cast_eqb _ _ k). auto.
+ Qed.
+
+ Lemma nocast_refl A B: cast A B = NoCast -> cast B A = NoCast.
+ Proof.
+ intros.
+ apply cast_diff.
+ rewrite neq_cast in H.
+ case_eq (eqb A B). intro.
+ rewrite H0 in H.
+ apply eqb_spec in H0.
+ rewrite H0 in H.
+ rewrite cast_refl in H.
+ now contradict H.
+ intro.
+ apply not_true_iff_false.
+ unfold not.
+ intro.
+ apply eqb_spec in H1.
+ rewrite H1 in H0. rewrite eqb_refl in H0. now contradict H0.
+ Qed.
+
+
End Cast.
+
End Typ.
Arguments Typ.Cast {_} {_} _.
@@ -471,20 +747,28 @@ Proof.
Qed.
(* End move *)
+
Module Atom.
Notation func := int (only parsing).
-
- Inductive cop : Type :=
+
+ Inductive cop : Type :=
| CO_xH
- | CO_Z0.
+ | CO_Z0
+ | CO_BV (_: list bool) (_ :N).
Inductive unop : Type :=
| UO_xO
| UO_xI
- | UO_Zpos
+ | UO_Zpos
| UO_Zneg
- | UO_Zopp.
+ | UO_Zopp
+ | UO_BVbitOf (_: N) (_: nat)
+ | UO_BVnot (_: N)
+ | UO_BVneg (_: N)
+ | UO_BVextr (i: N) (n0: N) (n1: N) (* TODO n1 first arg *)
+ | UO_BVzextn (n: N) (i: N)
+ | UO_BVsextn (n: N) (i: N).
Inductive binop : Type :=
| BO_Zplus
@@ -494,17 +778,35 @@ Module Atom.
| BO_Zle
| BO_Zge
| BO_Zgt
- | BO_eq (_ : Typ.type).
+ | BO_eq (_ : Typ.type)
+ | BO_BVand (_: N)
+ | BO_BVor (_: N)
+ | BO_BVxor (_: N)
+ | BO_BVadd (_: N)
+ | BO_BVsubst (_: N)
+ | BO_BVmult (_: N)
+ | BO_BVult (_: N)
+ | BO_BVslt (_: N)
+ | BO_BVconcat (_: N) (_: N)
+ | BO_BVshl (_: N)
+ | BO_BVshr (_: N)
+ | BO_select (_ : Typ.type) (_ : Typ.type)
+ | BO_diffarray (_ : Typ.type) (_ : Typ.type)
+ .
Inductive nop : Type :=
| NO_distinct (_ : Typ.type).
+ Inductive terop : Type :=
+ | TO_store (_ : Typ.type) (_ : Typ.type).
+
Notation hatom := int (only parsing).
-
+
Inductive atom : Type :=
| Acop (_: cop)
| Auop (_ : unop) (_:hatom)
| Abop (_ : binop) (_:hatom) (_:hatom)
+ | Atop (_ : terop) (_:hatom) (_:hatom) (_:hatom)
| Anop (_ : nop) (_: list hatom)
| Aapp (_:func) (_: list hatom).
@@ -514,18 +816,25 @@ Module Atom.
(** Equality *)
Definition cop_eqb o o' :=
match o, o' with
- | CO_xH, CO_xH
+ | CO_xH, CO_xH
| CO_Z0, CO_Z0 => true
+ | CO_BV bv s, CO_BV bv' s' => N.eqb s s' && RAWBITVECTOR_LIST.beq_list bv bv'
| _,_ => false
end.
Definition uop_eqb o o' :=
match o, o' with
- | UO_xO, UO_xO
+ | UO_xO, UO_xO
| UO_xI, UO_xI
- | UO_Zpos, UO_Zpos
+ | UO_Zpos, UO_Zpos
| UO_Zneg, UO_Zneg
| UO_Zopp, UO_Zopp => true
+ | UO_BVbitOf s1 n, UO_BVbitOf s2 m => Nat_eqb n m && N.eqb s1 s2
+ | UO_BVnot s1, UO_BVnot s2 => N.eqb s1 s2
+ | UO_BVneg s1, UO_BVneg s2 => N.eqb s1 s2
+ | UO_BVextr i0 n00 n01, UO_BVextr i1 n10 n11 => N.eqb i0 i1 && N.eqb n00 n10 && N.eqb n01 n11
+ | UO_BVzextn s1 i1, UO_BVzextn s2 i2 => N.eqb s1 s2 && N.eqb i1 i2
+ | UO_BVsextn s1 i1, UO_BVsextn s2 i2 => N.eqb s1 s2 && N.eqb i1 i2
| _,_ => false
end.
@@ -539,9 +848,27 @@ Module Atom.
| BO_Zge, BO_Zge
| BO_Zgt, BO_Zgt => true
| BO_eq t, BO_eq t' => Typ.eqb t t'
+ | BO_BVand s1, BO_BVand s2 => N.eqb s1 s2
+ | BO_BVor s1, BO_BVor s2
+ | BO_BVxor s1, BO_BVxor s2
+ | BO_BVadd s1, BO_BVadd s2
+ | BO_BVsubst s1, BO_BVsubst s2
+ | BO_BVmult s1, BO_BVmult s2 => N.eqb s1 s2
+ | BO_BVult s1, BO_BVult s2 => N.eqb s1 s2
+ | BO_BVslt s1, BO_BVslt s2 => N.eqb s1 s2
+ | BO_BVconcat s1 s2, BO_BVconcat s3 s4 => N.eqb s1 s3 && N.eqb s2 s4
+ | BO_BVshl s1, BO_BVshl s2 => N.eqb s1 s2
+ | BO_BVshr s1, BO_BVshr s2 => N.eqb s1 s2
+ | BO_select ti te, BO_select ti' te'
+ | BO_diffarray ti te, BO_diffarray ti' te' => Typ.eqb ti ti' && Typ.eqb te te'
| _,_ => false
end.
+ Definition top_eqb o o' :=
+ match o, o' with
+ | TO_store ti te, TO_store ti' te' => Typ.eqb ti ti' && Typ.eqb te te'
+ end.
+
Definition nop_eqb o o' :=
match o, o' with
| NO_distinct t, NO_distinct t' => Typ.eqb t t'
@@ -553,6 +880,8 @@ Module Atom.
| Auop o t, Auop o' t' => uop_eqb o o' && (t == t')
| Abop o t1 t2, Abop o' t1' t2' => bop_eqb o o' && (t1 == t1') && (t2 == t2')
| Anop o t, Anop o' t' => nop_eqb o o' && list_beq Int63Native.eqb t t'
+ | Atop o t1 t2 t3, Atop o' t1' t2' t3' =>
+ top_eqb o o' && (t1 == t1') && (t2 == t2') && (t3 == t3')
| Aapp a la, Aapp b lb => (a == b) && list_beq Int63Native.eqb la lb
| _, _ => false
end.
@@ -565,19 +894,109 @@ Module Atom.
Lemma reflect_cop_eqb : forall o1 o2, reflect (o1 = o2) (cop_eqb o1 o2).
Proof.
- destruct o1;destruct o2;simpl;constructor;trivial;discriminate.
+ destruct o1; destruct o2; simpl; try (constructor; trivial; discriminate).
+ apply iff_reflect. split. intro.
+ inversion H. rewrite andb_true_iff. split.
+ rewrite N.eqb_refl; auto. apply RAWBITVECTOR_LIST.List_eq_refl; auto.
+ intros. rewrite andb_true_iff in H. destruct H as (Ha, Hb).
+ apply N.eqb_eq in Ha. rewrite RAWBITVECTOR_LIST.List_eq in Hb.
+ now rewrite Ha, Hb.
Qed.
Lemma reflect_uop_eqb : forall o1 o2, reflect (o1 = o2) (uop_eqb o1 o2).
Proof.
- destruct o1;destruct o2;simpl;constructor;trivial;discriminate.
+ intros [ | | | | | s1 n1 | s1 | s1 | s1 | s1 | s1 ] [ | | | | |s2 n2 | s2 | s2 | s2 | s2 | s2 ];simpl; try constructor;trivial; try discriminate.
+ - apply iff_reflect. case_eq (Nat_eqb n1 n2).
+ + case_eq ((s1 =? s2)%N).
+ * rewrite N.eqb_eq, beq_nat_true_iff.
+ intros -> ->. split; reflexivity.
+ * rewrite N.eqb_neq, beq_nat_true_iff.
+ intros H1 ->; split; try discriminate.
+ intro H. inversion H. elim H1. auto.
+ + split; auto.
+ * rewrite beq_nat_false_iff in H. intros. contradict H0.
+ intro H'. apply H. inversion H'. reflexivity.
+ * intros. contradict H0. easy.
+ - apply iff_reflect. rewrite N.eqb_eq. split; intro H.
+ + now inversion H.
+ + now rewrite H.
+ - apply iff_reflect. rewrite N.eqb_eq. split; intro H.
+ + now inversion H.
+ + now rewrite H.
+ - intros. apply iff_reflect. split. intro H.
+ inversion H.
+ rewrite !andb_true_iff; split.
+ split; now rewrite N.eqb_eq.
+ now rewrite N.eqb_eq.
+ intros. rewrite !andb_true_iff in H.
+ destruct H as ((Ha, Hb), Hc).
+ rewrite N.eqb_eq in Ha, Hb, Hc.
+ subst.
+ reflexivity.
+ - intros. apply iff_reflect. split; intros.
+ + rewrite !andb_true_iff. inversion H.
+ split; try split; try now rewrite N.eqb_eq.
+ + rewrite !andb_true_iff in H.
+ destruct H as (Ha, Hb).
+ rewrite N.eqb_eq in Ha, Hb.
+ now subst.
+ - intros. apply iff_reflect. split; intros.
+ + rewrite !andb_true_iff. inversion H.
+ split; try split; try now rewrite N.eqb_eq.
+ + rewrite !andb_true_iff in H.
+ destruct H as (Ha, Hb).
+ rewrite N.eqb_eq in Ha, Hb.
+ now subst.
Qed.
-
+
+
Lemma reflect_bop_eqb : forall o1 o2, reflect (o1 = o2) (bop_eqb o1 o2).
Proof.
- destruct o1;destruct o2;simpl;try (constructor;trivial;discriminate).
- preflect (Typ.reflect_eqb t t0).
- constructor;subst;trivial.
+ intros [ | | | | | | | A1|s1|s1 |s1 | s1 | s1 | s1 | s1 | s1 | s1 | s1 | s1 | I1 E1 | I1 E1 ]
+ [ | | | | | | | A2|s2|s2| s2 | s2 | s2 | s2 | s2 | s2 | s2 | s2 | s2 |I2 E2 | I2 E2 ];
+ simpl;try (constructor;trivial;discriminate).
+ - preflect (Typ.reflect_eqb A1 A2).
+ constructor;subst;trivial.
+ - preflect (N.eqb_spec s1 s2).
+ constructor;subst;trivial.
+ - preflect (N.eqb_spec s1 s2).
+ constructor;subst;trivial.
+ - preflect (N.eqb_spec s1 s2).
+ constructor;subst;trivial.
+ - preflect (N.eqb_spec s1 s2).
+ constructor;subst;trivial.
+ - preflect (N.eqb_spec s1 s2).
+ constructor;subst;trivial.
+ - preflect (N.eqb_spec s1 s2).
+ constructor;subst;trivial.
+ - preflect (N.eqb_spec s1 s2).
+ constructor;subst;trivial.
+ - preflect (N.eqb_spec s1 s2).
+ constructor;subst;trivial.
+ - intros.
+ preflect (N.eqb_spec s1 s2).
+ preflect (N.eqb_spec n n0).
+ constructor;subst;trivial.
+
+ - preflect (N.eqb_spec s1 s2).
+ constructor;subst;trivial.
+ - preflect (N.eqb_spec s1 s2).
+ constructor;subst;trivial.
+
+ - preflect (Typ.reflect_eqb I1 I2).
+ preflect (Typ.reflect_eqb E1 E2).
+ constructor;subst;trivial.
+ - preflect (Typ.reflect_eqb I1 I2).
+ preflect (Typ.reflect_eqb E1 E2).
+ constructor;subst;trivial.
+Qed.
+
+ Lemma reflect_top_eqb : forall o1 o2, reflect (o1 = o2) (top_eqb o1 o2).
+ Proof.
+ intros [ I1 E1 ] [ I2 E2 ]. simpl.
+ preflect (Typ.reflect_eqb I1 I2).
+ preflect (Typ.reflect_eqb E1 E2).
+ constructor;subst;trivial.
Qed.
Lemma reflect_nop_eqb : forall o1 o2, reflect (o1 = o2) (nop_eqb o1 o2).
@@ -594,32 +1013,40 @@ Module Atom.
preflect (reflect_uop_eqb u u0); preflect (Int63Properties.reflect_eqb i i0);
constructor;subst;trivial.
(* Binary operators *)
- preflect (reflect_bop_eqb b b0);
+ preflect (reflect_bop_eqb b b0);
preflect (Int63Properties.reflect_eqb i i1);
preflect (Int63Properties.reflect_eqb i0 i2);
constructor;subst;trivial.
+ (* Ternary operators *)
+ preflect (reflect_top_eqb t t0).
+ preflect (Int63Properties.reflect_eqb i i2).
+ preflect (Int63Properties.reflect_eqb i0 i3).
+ preflect (Int63Properties.reflect_eqb i1 i4).
+ constructor;subst;trivial.
(* N-ary operators *)
- preflect (reflect_nop_eqb n n0); preflect (reflect_list_beq _ _ Int63Properties.reflect_eqb l l0); constructor; subst; reflexivity.
+ preflect (reflect_nop_eqb n n0);
+ preflect (reflect_list_beq _ _ Int63Properties.reflect_eqb l l0);
+ constructor; subst; reflexivity.
(* Application *)
preflect (Int63Properties.reflect_eqb i i0);
preflect (reflect_list_beq _ _ Int63Properties.reflect_eqb l l0);
constructor;subst;trivial.
Qed.
-
+
Lemma eqb_spec : forall t1 t2, eqb t1 t2 <-> t1 = t2.
Proof.
- intros;symmetry;apply reflect_iff;apply reflect_eqb.
+ intros;symmetry; apply reflect_iff; apply reflect_eqb.
Qed.
-
+
(** Typing and interpretation *)
-
+
Record val (t:Type) (I:t -> Type) := Val {
v_type : t;
v_val : I v_type
}.
Section Typing_Interp.
- Variable t_i : PArray.array typ_eqb.
+ Variable t_i : PArray.array typ_compdec.
Local Notation interp_t := (Typ.interp t_i).
Local Notation interp_ft := (Typ.interp_ftype t_i).
@@ -646,38 +1073,63 @@ Module Atom.
simpl in H1; rewrite Typ.cast_refl in H1; auto.
Qed.
- (* Interprétation d'une fonction*)
+ (* Interpretation of a function*)
Variable t_func : PArray.array tval.
(** Type checking of atom assuming an type for hatom *)
Section Typ_Aux.
Variable get_type : hatom -> Typ.type.
- Definition typ_cop o :=
+ Definition typ_cop o :=
match o with
- | CO_xH => Typ.Tpositive
+ | CO_xH => Typ.Tpositive
| CO_Z0 => Typ.TZ
+ | CO_BV _ s => Typ.TBV s
end.
Definition typ_uop o :=
match o with
- | UO_xO => (Typ.Tpositive,Typ.Tpositive)
- | UO_xI => (Typ.Tpositive,Typ.Tpositive)
+ | UO_xO => (Typ.Tpositive,Typ.Tpositive)
+ | UO_xI => (Typ.Tpositive,Typ.Tpositive)
| UO_Zpos => (Typ.Tpositive, Typ.TZ)
| UO_Zneg => (Typ.Tpositive, Typ.TZ)
| UO_Zopp => (Typ.TZ, Typ.TZ)
+ | UO_BVbitOf s _ => (Typ.TBV s, Typ.Tbool)
+ | UO_BVnot s => (Typ.TBV s, Typ.TBV s)
+ | UO_BVneg s => (Typ.TBV s, Typ.TBV s)
+ | UO_BVextr i n0 n1 => (Typ.TBV n1, Typ.TBV n0)
+ | UO_BVzextn s i => (Typ.TBV s, Typ.TBV (i + s))
+ | UO_BVsextn s i => (Typ.TBV s, Typ.TBV (i + s))
end.
- Definition typ_bop o :=
+ Definition typ_bop o :=
match o with
- | BO_Zplus => ((Typ.TZ,Typ.TZ), Typ.TZ)
- | BO_Zminus => ((Typ.TZ,Typ.TZ), Typ.TZ)
- | BO_Zmult => ((Typ.TZ,Typ.TZ), Typ.TZ)
- | BO_Zlt => ((Typ.TZ,Typ.TZ), Typ.Tbool)
- | BO_Zle => ((Typ.TZ,Typ.TZ), Typ.Tbool)
- | BO_Zge => ((Typ.TZ,Typ.TZ), Typ.Tbool)
+ | BO_Zplus => ((Typ.TZ,Typ.TZ), Typ.TZ)
+ | BO_Zminus => ((Typ.TZ,Typ.TZ), Typ.TZ)
+ | BO_Zmult => ((Typ.TZ,Typ.TZ), Typ.TZ)
+ | BO_Zlt => ((Typ.TZ,Typ.TZ), Typ.Tbool)
+ | BO_Zle => ((Typ.TZ,Typ.TZ), Typ.Tbool)
+ | BO_Zge => ((Typ.TZ,Typ.TZ), Typ.Tbool)
| BO_Zgt => ((Typ.TZ,Typ.TZ), Typ.Tbool)
| BO_eq t => ((t,t),Typ.Tbool)
+ | BO_BVand s => ((Typ.TBV s,Typ.TBV s), (Typ.TBV s))
+ | BO_BVor s => ((Typ.TBV s,Typ.TBV s), Typ.TBV s)
+ | BO_BVxor s => ((Typ.TBV s,Typ.TBV s), Typ.TBV s)
+ | BO_BVadd s => ((Typ.TBV s,Typ.TBV s), Typ.TBV s)
+ | BO_BVsubst s => ((Typ.TBV s,Typ.TBV s), Typ.TBV s)
+ | BO_BVmult s => ((Typ.TBV s,Typ.TBV s), Typ.TBV s)
+ | BO_BVult s => ((Typ.TBV s,Typ.TBV s), Typ.Tbool)
+ | BO_BVconcat s1 s2 => ((Typ.TBV s1,Typ.TBV s2), (Typ.TBV (s1 + s2)))
+ | BO_BVslt s => ((Typ.TBV s,Typ.TBV s), Typ.Tbool)
+ | BO_BVshl s => ((Typ.TBV s,Typ.TBV s), Typ.TBV s)
+ | BO_BVshr s => ((Typ.TBV s,Typ.TBV s), Typ.TBV s)
+ | BO_select ti te => ((Typ.TFArray ti te, ti), te)
+ | BO_diffarray ti te => ((Typ.TFArray ti te, Typ.TFArray ti te), ti)
+ end.
+
+ Definition typ_top o :=
+ match o with
+ | TO_store ti te => ((Typ.TFArray ti te, ti, te), Typ.TFArray ti te)
end.
Definition typ_nop o :=
@@ -692,16 +1144,21 @@ Module Atom.
| _, _ => false
end.
- Definition check_aux (a:atom) (t:Typ.type) : bool :=
+ Definition check_aux (a:atom) (t:Typ.type) : bool :=
match a with
- | Acop o => Typ.eqb (typ_cop o) t
+ | Acop o => Typ.eqb (typ_cop o) t
| Auop o a =>
let (ta,t') := typ_uop o in
Typ.eqb t' t && Typ.eqb (get_type a) ta
| Abop o a1 a2 =>
let (ta,t') := typ_bop o in
let (ta1,ta2) := ta in
- Typ.eqb t' t && Typ.eqb (get_type a1) ta1 && Typ.eqb (get_type a2) ta2
+ Typ.eqb t' t && Typ.eqb (get_type a1) ta1 && Typ.eqb (get_type a2) ta2
+ | Atop o a1 a2 a3 =>
+ let (ta, t') := typ_top o in
+ let '(ta1, ta2, ta3) := ta in
+ Typ.eqb t' t && Typ.eqb (get_type a1) ta1 &&
+ Typ.eqb (get_type a2) ta2 && Typ.eqb (get_type a3) ta3
| Anop o a =>
let (ta,t') := typ_nop o in
(Typ.eqb t' t) && (List.forallb (fun t1 => Typ.eqb (get_type t1) ta) a)
@@ -715,7 +1172,7 @@ Module Atom.
Lemma unicity : forall a t1 t2,
check_aux a t1 -> check_aux a t2 -> t1 = t2.
Proof.
- destruct a;simpl.
+ destruct a;simpl.
(* Constants *)
intros t1 t2;rewrite !Typ.eqb_spec;intros;subst;trivial.
(* Unary operators *)
@@ -729,8 +1186,20 @@ Module Atom.
intros [[H1 _] _] [[H2 _] _]; change (is_true (Typ.eqb (snd (typ_bop b)) t1)) in H1.
change (is_true (Typ.eqb (snd (typ_bop b)) t2)) in H2.
rewrite Typ.eqb_spec in H1, H2;subst;trivial.
+ (* Ternary operators *)
+ unfold is_true. intros.
+ destruct typ_top. destruct p. destruct p.
+ rewrite !andb_true_iff in H, H0.
+ destruct H as (((Ha, Hb), Hc), Hd).
+ destruct H0 as (((H0a, H0b), H0c), H0d).
+ apply Typ.eqb_spec in Ha.
+ apply Typ.eqb_spec in H0a. now subst.
(* N-ary operators *)
- intros t1 t2; destruct (typ_nop n) as [ta t']; unfold is_true; rewrite !andb_true_iff; change (is_true (Typ.eqb t' t1) /\ is_true (List.forallb (fun t3 : int => Typ.eqb (get_type t3) ta) l) -> is_true (Typ.eqb t' t2) /\ is_true (List.forallb (fun t3 : int => Typ.eqb (get_type t3) ta) l) -> t1 = t2); rewrite !Typ.eqb_spec; intros [H1 _] [H2 _]; subst; auto.
+ intros t1 t2; destruct (typ_nop n) as [ta t'];
+ unfold is_true; rewrite !andb_true_iff;
+ change (is_true (Typ.eqb t' t1) /\ is_true
+ (List.forallb (fun t3 : int => Typ.eqb (get_type t3) ta) l) -> is_true (Typ.eqb t' t2) /\ is_true (List.forallb
+ (fun t3 : int => Typ.eqb (get_type t3) ta) l) -> t1 = t2); rewrite !Typ.eqb_spec; intros [H1 _] [H2 _]; subst; auto.
(* Application *)
intros t1 t2;destruct (v_type Typ.ftype interp_ft (t_func.[ i])).
unfold is_true;rewrite !andb_true_iff;intros [_ H1] [_ H2].
@@ -759,21 +1228,222 @@ Module Atom.
Lemma check_aux_dec : forall a,
{exists T, check_aux a T} + {forall T, check_aux a T = false}.
Proof.
- intros [op|op h|op h1 h2|op ha|f args]; simpl.
+ intros [op|op h|op h1 h2|op ha i i0|f args | i e ]; simpl.
(* Constants *)
left; destruct op; simpl.
exists Typ.Tpositive; auto.
exists Typ.TZ; auto.
+ exists (Typ.TBV n); now rewrite N.eqb_refl.
(* Unary operators *)
- destruct op; simpl; try (case (Typ.eqb (get_type h) Typ.Tpositive); [left; exists Typ.Tpositive|right; intro; rewrite andb_false_r]; reflexivity); try (case (Typ.eqb (get_type h) Typ.Tpositive); [left; exists Typ.TZ|right; intro; rewrite andb_false_r]; reflexivity); case (Typ.eqb (get_type h) Typ.TZ); [left; exists Typ.TZ|right; intro; rewrite andb_false_r]; reflexivity.
+ destruct op; simpl;
+ (case (Typ.eqb (get_type h) Typ.Tpositive)).
+ left; exists Typ.Tpositive; easy.
+ right; intros; rewrite andb_false_r; easy.
+ left; exists Typ.Tpositive; easy.
+ right; intros; rewrite andb_false_r; easy.
+
+ left; exists Typ.TZ; easy.
+ right; intros; rewrite andb_false_r; easy.
+ left; exists Typ.TZ; easy.
+ right; intros; rewrite andb_false_r; easy.
+
+
+ (case (Typ.eqb (get_type h) Typ.TZ)).
+ left. exists Typ.TZ. easy.
+ right. intros. rewrite andb_false_r. easy.
+
+ (case (Typ.eqb (get_type h) Typ.TZ)).
+ left. exists Typ.TZ. easy.
+ right. intros. rewrite andb_false_r. easy.
+
+ (case (Typ.eqb (get_type h) (Typ.TBV n))).
+ left. exists Typ.Tbool. easy.
+ right. intros. rewrite andb_false_r. easy.
+
+ (case (Typ.eqb (get_type h) (Typ.TBV n))).
+ left. exists Typ.Tbool. easy.
+ right. intros. rewrite andb_false_r. easy.
+
+ (case (Typ.eqb (get_type h) (Typ.TBV n))).
+ left. exists (Typ.TBV n). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+
+ (case (Typ.eqb (get_type h) (Typ.TBV n))).
+ left. exists (Typ.TBV n). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+
+ (case (Typ.eqb (get_type h) (Typ.TBV n))).
+ left. exists (Typ.TBV n). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+
+ (case (Typ.eqb (get_type h) (Typ.TBV n))).
+ left. exists (Typ.TBV n). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+
+ (case (Typ.eqb (get_type h) (Typ.TBV n1))).
+ left. exists (Typ.TBV n0). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+
+ (case (Typ.eqb (get_type h) (Typ.TBV n1))).
+ left. exists (Typ.TBV n0). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+
+ (case (Typ.eqb (get_type h) (Typ.TBV n))).
+ left. exists (Typ.TBV (i + n)). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+
+ (case (Typ.eqb (get_type h) (Typ.TBV n))).
+ left. exists (Typ.TBV (i + n)). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+
+ (case (Typ.eqb (get_type h) (Typ.TBV n))).
+ left. exists (Typ.TBV (i + n)). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+
+ (case (Typ.eqb (get_type h) (Typ.TBV n))).
+ left. exists (Typ.TBV (i + n)). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+
(* Binary operators *)
- destruct op; simpl; try (case (Typ.eqb (get_type h1) Typ.TZ); [case (Typ.eqb (get_type h2) Typ.TZ); [left; exists Typ.TZ|right; intro; rewrite andb_false_r]|right; intro; rewrite andb_false_r]; reflexivity); try (case (Typ.eqb (get_type h1) Typ.TZ); [case (Typ.eqb (get_type h2) Typ.TZ); [left; exists Typ.Tbool|right; intro; rewrite andb_false_r]|right; intro; rewrite andb_false_r]; reflexivity); case (Typ.eqb (get_type h1) t); [case (Typ.eqb (get_type h2) t); [left; exists Typ.Tbool|right; intro; rewrite andb_false_r]|right; intro; rewrite andb_false_r]; reflexivity.
+ destruct op; simpl.
+ (case (Typ.eqb (get_type h1) Typ.TZ)); (case (Typ.eqb (get_type h2) Typ.TZ)).
+ left. exists Typ.TZ. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (case (Typ.eqb (get_type h1) Typ.TZ)); (case (Typ.eqb (get_type h2) Typ.TZ)).
+ left. exists Typ.TZ. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _ )).
+ left. exists Typ.TZ. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists Typ.Tbool. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists Typ.Tbool. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists Typ.Tbool. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists Typ.Tbool. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists Typ.Tbool. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists (Typ.TBV n). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (*additional case for BO_BVor*)
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists (Typ.TBV n). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (*additional case for BO_BVxor*)
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists (Typ.TBV n). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (*additional case for BO_BVadd*)
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists (Typ.TBV n). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (*additional case for BO_BVsubst*)
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists (Typ.TBV n). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (*additional case for BO_BVmult*)
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists (Typ.TBV n). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (*additional case for BO_BVult*)
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists (Typ.Tbool). easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (*additional case for BO_BVslt*)
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists (Typ.Tbool). easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (*additional case for BO_BVconcat*)
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists (Typ.TBV (n + n0)). rewrite N.eqb_refl. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (*additional case for BO_BVshl*)
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists (Typ.TBV n). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ (*additional case for BO_BVshr*)
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists (Typ.TBV n). now rewrite N.eqb_refl; easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+
+
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists t0. rewrite Typ.eqb_refl. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+
+
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _)).
+ left. exists t. rewrite Typ.eqb_refl. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+
+ (* Ternary operators *)
+ revert i i0; destruct op; simpl. intros h1 h2.
+ (case (Typ.eqb (get_type h1) _)); (case (Typ.eqb (get_type h2) _));
+ (case (Typ.eqb (get_type ha) _)).
+ left. exists (Typ.TFArray t t0). rewrite !Typ.eqb_refl. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
+ right. intros. rewrite andb_false_r. easy.
(* N-ary operators *)
- destruct op as [ty]; simpl; case (List.forallb (fun t1 : int => Typ.eqb (get_type t1) ty) ha).
+ destruct f as [ty]; simpl; case (List.forallb (fun t1 : int => Typ.eqb (get_type t1) ty) args).
left; exists Typ.Tbool; auto.
right; intro T; rewrite andb_false_r; auto.
(* Application *)
- case (v_type Typ.ftype interp_ft (t_func .[ f])); intros; apply check_args_dec.
+ case (v_type Typ.ftype interp_ft (t_func .[ i])); intros; apply check_args_dec.
Qed.
End Typ_Aux.
@@ -799,6 +1469,16 @@ Module Atom.
| _, _ => bvtrue
end.
+ Definition apply_terop (t1 t2 t3 r : Typ.type)
+ (op : interp_t t1 -> interp_t t2 -> interp_t t3 -> interp_t r) (tv1 tv2 tv3: bval) :=
+ let (t1', v1) := tv1 in
+ let (t2', v2) := tv2 in
+ let (t3', v3) := tv3 in
+ match Typ.cast t1' t1, Typ.cast t2' t2, Typ.cast t3' t3 with
+ | Typ.Cast k1, Typ.Cast k2, Typ.Cast k3 => Bval r (op (k1 _ v1) (k2 _ v2) (k3 _ v3))
+ | _, _, _ => bvtrue
+ end.
+
Fixpoint apply_func
targs tr (f:interp_ft (targs,tr)) (lv:list bval) : bval :=
match targs as targs0 return interp_ft (targs0,tr) -> bval with
@@ -824,19 +1504,30 @@ Module Atom.
match o with
| CO_xH => Bval Typ.Tpositive xH
| CO_Z0 => Bval Typ.TZ Z0
+ | CO_BV bv s => Bval (Typ.TBV s) (BITVECTOR_LIST._of_bits bv s)
end.
- Definition interp_uop o :=
+ Definition interp_uop o :=
match o with
| UO_xO => apply_unop Typ.Tpositive Typ.Tpositive xO
| UO_xI => apply_unop Typ.Tpositive Typ.Tpositive xI
| UO_Zpos => apply_unop Typ.Tpositive Typ.TZ Zpos
| UO_Zneg => apply_unop Typ.Tpositive Typ.TZ Zneg
| UO_Zopp => apply_unop Typ.TZ Typ.TZ Zopp
+ | UO_BVbitOf s n => apply_unop (Typ.TBV s) Typ.Tbool (BITVECTOR_LIST.bitOf n)
+ | UO_BVnot s => apply_unop (Typ.TBV s) (Typ.TBV s) (@BITVECTOR_LIST.bv_not s)
+ | UO_BVneg s => apply_unop (Typ.TBV s) (Typ.TBV s) (@BITVECTOR_LIST.bv_neg s)
+ | UO_BVextr i n0 n1 =>
+ apply_unop (Typ.TBV n1) (Typ.TBV n0) (@BITVECTOR_LIST.bv_extr i n0 n1)
+ | UO_BVzextn s i =>
+ apply_unop (Typ.TBV s) (Typ.TBV (i + s)) (@BITVECTOR_LIST.bv_zextn s i)
+ | UO_BVsextn s i =>
+ apply_unop (Typ.TBV s) (Typ.TBV (i + s)) (@BITVECTOR_LIST.bv_sextn s i)
end.
+
Definition interp_bop o :=
- match o with
+ match o with
| BO_Zplus => apply_binop Typ.TZ Typ.TZ Typ.TZ Zplus
| BO_Zminus => apply_binop Typ.TZ Typ.TZ Typ.TZ Zminus
| BO_Zmult => apply_binop Typ.TZ Typ.TZ Typ.TZ Zmult
@@ -845,6 +1536,37 @@ Module Atom.
| BO_Zge => apply_binop Typ.TZ Typ.TZ Typ.Tbool Zge_bool
| BO_Zgt => apply_binop Typ.TZ Typ.TZ Typ.Tbool Zgt_bool
| BO_eq t => apply_binop t t Typ.Tbool (Typ.i_eqb t_i t)
+ | BO_BVand s =>
+ apply_binop (Typ.TBV s) (Typ.TBV s) (Typ.TBV s) (@BITVECTOR_LIST.bv_and s)
+ | BO_BVor s =>
+ apply_binop (Typ.TBV s) (Typ.TBV s) (Typ.TBV s) (@BITVECTOR_LIST.bv_or s)
+ | BO_BVxor s =>
+ apply_binop (Typ.TBV s) (Typ.TBV s) (Typ.TBV s) (@BITVECTOR_LIST.bv_xor s)
+ | BO_BVadd s =>
+ apply_binop (Typ.TBV s) (Typ.TBV s) (Typ.TBV s) (@BITVECTOR_LIST.bv_add s)
+ | BO_BVsubst s =>
+ apply_binop (Typ.TBV s) (Typ.TBV s) (Typ.TBV s) (@BITVECTOR_LIST.bv_subt s)
+ | BO_BVmult s =>
+ apply_binop (Typ.TBV s) (Typ.TBV s) (Typ.TBV s) (@BITVECTOR_LIST.bv_mult s)
+ | BO_BVult s =>
+ apply_binop (Typ.TBV s) (Typ.TBV s) Typ.Tbool (@BITVECTOR_LIST.bv_ult s)
+ | BO_BVslt s =>
+ apply_binop (Typ.TBV s) (Typ.TBV s) Typ.Tbool (@BITVECTOR_LIST.bv_slt s)
+ | BO_BVconcat s1 s2 =>
+ apply_binop (Typ.TBV s1) (Typ.TBV s2) (Typ.TBV (s1 + s2)) (@BITVECTOR_LIST.bv_concat s1 s2)
+ | BO_BVshl s =>
+ apply_binop (Typ.TBV s) (Typ.TBV s) (Typ.TBV s) (@BITVECTOR_LIST.bv_shl s)
+ | BO_BVshr s =>
+ apply_binop (Typ.TBV s) (Typ.TBV s) (Typ.TBV s) (@BITVECTOR_LIST.bv_shr s)
+ | BO_select ti te => apply_binop (Typ.TFArray ti te) ti te FArray.select
+ | BO_diffarray ti te =>
+ apply_binop (Typ.TFArray ti te) (Typ.TFArray ti te) ti FArray.diff
+ end.
+
+ Definition interp_top o :=
+ match o with
+ | TO_store ti te =>
+ apply_terop (Typ.TFArray ti te) ti te (Typ.TFArray ti te) FArray.store
end.
Fixpoint compute_interp ty acc l :=
@@ -884,8 +1606,8 @@ Module Atom.
Lemma compute_interp_spec : forall ty l acc,
match compute_interp ty acc l with
- | Some l' => forall i j, In2 i j l' <-> (In2 i j acc \/ (In j acc /\ exists a, In a l /\ interp_hatom a = Bval ty i) \/ (exists a b, In2 b a l /\ interp_hatom a = Bval ty i /\ interp_hatom b = Bval ty j))
- | None => exists a, In a l /\ let (ta,_) := interp_hatom a in ta <> ty
+ | Some l' => forall i j, In2 i j l' <-> (In2 i j acc \/ (List.In j acc /\ exists a, List.In a l /\ interp_hatom a = Bval ty i) \/ (exists a b, In2 b a l /\ interp_hatom a = Bval ty i /\ interp_hatom b = Bval ty j))
+ | None => exists a, List.In a l /\ let (ta,_) := interp_hatom a in ta <> ty
end.
Proof.
intro ty; induction l as [ |a q IHq]; simpl.
@@ -932,7 +1654,7 @@ Module Atom.
Lemma compute_interp_spec_rev : forall ty l,
match compute_interp ty nil l with
| Some l' => forall i j, In2 j i (rev l') <-> (exists a b, In2 b a l /\ interp_hatom a = Bval ty i /\ interp_hatom b = Bval ty j)
- | None => exists a, In a l /\ let (ta,_) := interp_hatom a in ta <> ty
+ | None => exists a, List.In a l /\ let (ta,_) := interp_hatom a in ta <> ty
end.
Proof.
intros ty l; generalize (compute_interp_spec ty l nil); case (compute_interp ty nil l); auto; intros l' H i j; rewrite In2_rev, (H i j); split; auto; intros [H1|[[H1 _]|H1]]; auto; inversion H1.
@@ -943,6 +1665,7 @@ Module Atom.
| Acop o => interp_cop o
| Auop o a => interp_uop o (interp_hatom a)
| Abop o a1 a2 => interp_bop o (interp_hatom a1) (interp_hatom a2)
+ | Atop o a1 a2 a3 => interp_top o (interp_hatom a1) (interp_hatom a2) (interp_hatom a3)
| Anop (NO_distinct t) a =>
match compute_interp t nil a with
| Some l => Bval Typ.Tbool (distinct (Typ.i_eqb t_i t) (rev l))
@@ -961,6 +1684,14 @@ Module Atom.
| _ => true
end.
+ Definition interp_bv (v:bval) (s:N) : BITVECTOR_LIST.bitvector s :=
+ let (t,v) := v in
+ match Typ.cast t (Typ.TBV s) with
+ | Typ.Cast k => k _ v
+ | _ => BITVECTOR_LIST.zeros s
+ end.
+
+
(* If an atom is well-typed, it has an interpretation *)
@@ -987,20 +1718,114 @@ Module Atom.
check_aux get_type a t ->
exists v, interp_aux a = (Bval t v).
Proof.
- intros [op|op h|op h1 h2|op ha|f l]; simpl.
+ intros [op|op h|op h1 h2|op h1 h2 h3|op ha|f l]; simpl.
(* Constants *)
- destruct op; intros [i| | | ]; simpl; try discriminate; intros _.
+ destruct op as [ | |l n]; intros [ | i | | | |size]; simpl; try discriminate.
exists 1%positive; auto.
exists 0%Z; auto.
+ intros H. exists (BITVECTOR_LIST._of_bits l size). unfold is_true in H. rewrite N.eqb_eq in H. now rewrite H.
(* Unary operators *)
- destruct op; intros [i| | | ]; simpl; try discriminate; rewrite Typ.eqb_spec; intro H1; destruct (check_aux_interp_hatom h) as [x Hx]; rewrite Hx; simpl; generalize x Hx; rewrite H1; intros y Hy; rewrite Typ.cast_refl.
+ destruct op as [ | | | | |n n0|n|n|n n0 n1|n n0|n n0]; intros [ | ind| | | |size];
+ simpl; try discriminate; try rewrite Typ.eqb_spec;
+ intros H1a; destruct (check_aux_interp_hatom h)
+ as [x Hx]; rewrite Hx; simpl; generalize x Hx;
+ try rewrite H1a; intros y Hy; try rewrite Typ.cast_refl.
exists (y~0)%positive; auto.
exists (y~1)%positive; auto.
exists (Zpos y); auto.
exists (Zneg y); auto.
exists (- y)%Z; auto.
- (* Binary operators *)
- destruct op as [ | | | | | | |A]; intros [i| | | ]; simpl; try discriminate; unfold is_true; rewrite andb_true_iff; try (change (Typ.eqb (get_type h1) Typ.TZ = true /\ Typ.eqb (get_type h2) Typ.TZ = true) with (is_true (Typ.eqb (get_type h1) Typ.TZ) /\ is_true (Typ.eqb (get_type h2) Typ.TZ)); rewrite !Typ.eqb_spec; intros [H1 H2]; destruct (check_aux_interp_hatom h1) as [x1 Hx1]; rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl; generalize x1 Hx1 x2 Hx2; rewrite H1, H2; intros y1 Hy1 y2 Hy2; rewrite !Typ.cast_refl).
+ (* bitOf *)
+ exists (BITVECTOR_LIST.bitOf n0 y); auto.
+ (* bv_not *)
+ intros.
+ apply andb_true_iff in H1a. destruct H1a as (Ha, Hb).
+ rewrite N.eqb_eq in Ha.
+ revert x y Hx Hy Hb.
+ rewrite <- Ha in *. intros.
+ apply Typ.eqb_spec in Hb.
+ revert x y Hx Hy.
+ rewrite Hb. intros.
+ exists (@BITVECTOR_LIST.bv_not n y); auto. rewrite Typ.cast_refl; auto.
+ (* bv_neg *)
+ intros.
+ apply andb_true_iff in H1a. destruct H1a as (Ha, Hb).
+ rewrite N.eqb_eq in Ha.
+ revert x y Hx Hy Hb.
+ rewrite <- Ha in *. intros.
+ apply Typ.eqb_spec in Hb.
+ revert x y Hx Hy.
+ rewrite Hb. intros.
+ exists (@BITVECTOR_LIST.bv_neg n y); auto. rewrite Typ.cast_refl; auto.
+ (* bv_extr *)
+ intros.
+ apply andb_true_iff in H1a. destruct H1a as (Ha, Hb).
+ rewrite N.eqb_eq in Ha.
+ revert x y Hx Hy Hb.
+ rewrite <- Ha in *. intros.
+ apply Typ.eqb_spec in Hb.
+ revert x y Hx Hy.
+ rewrite Hb. intros.
+ exists (@BITVECTOR_LIST.bv_extr n n0 n1 y); auto. rewrite Typ.cast_refl; auto.
+ (* bv_zextn *)
+ intros.
+ apply andb_true_iff in H1a. destruct H1a as (Ha, Hb).
+ rewrite N.eqb_eq in Ha.
+ revert x y Hx Hy Hb.
+ rewrite <- Ha in *. intros.
+ apply Typ.eqb_spec in Hb.
+ revert x y Hx Hy.
+ rewrite Hb. intros.
+ exists (@BITVECTOR_LIST.bv_zextn n n0 y); auto. rewrite Typ.cast_refl; auto.
+ (* bv_sextn *)
+ intros.
+ apply andb_true_iff in H1a. destruct H1a as (Ha, Hb).
+ rewrite N.eqb_eq in Ha.
+ revert x y Hx Hy Hb.
+ rewrite <- Ha in *. intros.
+ apply Typ.eqb_spec in Hb.
+ revert x y Hx Hy.
+ rewrite Hb. intros.
+ exists (@BITVECTOR_LIST.bv_sextn n n0 y); auto. rewrite Typ.cast_refl; auto.
+ (* Binary operators *)
+ destruct op as [ | | | | | | | A |s1|s2| s3 | s4 | s5 | s6 | s7 | s8 | s9 | s10 | n m | ti te | ti te];
+ [ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] |
+ intros [ ti' te' | i | | | |s ] | |
+ ];
+ simpl; try discriminate; unfold is_true;
+ try (rewrite andb_true_iff ;change (Typ.eqb (get_type h1) Typ.TZ = true /\ Typ.eqb (get_type h2) Typ.TZ = true) with
+ (is_true (Typ.eqb (get_type h1) Typ.TZ) /\ is_true (Typ.eqb (get_type h2) Typ.TZ));
+ rewrite !Typ.eqb_spec; intros [H1 H2];
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1];
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2];
+ rewrite Hx2; simpl; generalize x1 Hx1 x2 Hx2;
+ rewrite H1, H2; intros y1 Hy1 y2 Hy2; rewrite !Typ.cast_refl);
+
+ try (change (Typ.eqb (get_type h1) Typ.TBV = true /\ Typ.eqb (get_type h2) Typ.TBV = true) with
+ (is_true (Typ.eqb (get_type h1) Typ.TBV) /\ is_true (Typ.eqb (get_type h2) Typ.TBV));
+ rewrite !Typ.eqb_spec; intros [H1 H2];
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1];
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2];
+ rewrite Hx2; simpl; generalize x1 Hx1 x2 Hx2; rewrite H1, H2;
+ intros y1 Hy1 y2 Hy2; rewrite !Typ.cast_refl).
+
exists (y1 + y2)%Z; auto.
exists (y1 - y2)%Z; auto.
exists (y1 * y2)%Z; auto.
@@ -1008,14 +1833,218 @@ Module Atom.
exists (y1 <=? y2)%Z; auto.
exists (y1 >=? y2)%Z; auto.
exists (y1 >? y2)%Z; auto.
- change (Typ.eqb (get_type h1) A = true /\ Typ.eqb (get_type h2) A = true) with (is_true (Typ.eqb (get_type h1) A) /\ is_true (Typ.eqb (get_type h2) A)); rewrite !Typ.eqb_spec; intros [H1 H2]; destruct (check_aux_interp_hatom h1) as [x1 Hx1]; rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl; generalize x1 Hx1 x2 Hx2; rewrite H1, H2; intros y1 Hy1 y2 Hy2; rewrite !Typ.cast_refl; exists (Typ.i_eqb t_i A y1 y2); auto.
+ rewrite andb_true_iff ; change (Typ.eqb (get_type h1) A = true /\ Typ.eqb (get_type h2) A = true) with
+ (is_true (Typ.eqb (get_type h1) A) /\ is_true (Typ.eqb (get_type h2) A));
+ rewrite !Typ.eqb_spec; intros [H1 H2]; destruct (check_aux_interp_hatom h1) as [x1 Hx1];
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl;
+ generalize x1 Hx1 x2 Hx2; rewrite H1, H2; intros y1 Hy1 y2 Hy2; rewrite !Typ.cast_refl;
+ exists (Typ.i_eqb t_i A y1 y2); auto.
+ (*BO_BVand*)
+ simpl in s.
+ intros. rewrite !andb_true_iff in H. destruct H as ((Ha, Hb), Hc).
+ apply Typ.eqb_spec in Hb.
+ apply Typ.eqb_spec in Hc.
+ rewrite N.eqb_eq in Ha.
+ revert Hb Hc. rewrite Ha in *. intros.
+
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1].
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl.
+ revert x1 Hx1 x2 Hx2.
+ rewrite Hb, Hc. intros y1 Hy1 y2 Hy2.
+ rewrite Typ.cast_refl.
+ exists (BITVECTOR_LIST.bv_and y1 y2); auto.
+ (*BO_BVor*)
+ simpl in s.
+ intros. rewrite !andb_true_iff in H. destruct H as ((Ha, Hb), Hc).
+ apply Typ.eqb_spec in Hb.
+ apply Typ.eqb_spec in Hc.
+ rewrite N.eqb_eq in Ha.
+ revert Hb Hc. rewrite Ha in *. intros.
+
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1].
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl.
+ revert x1 Hx1 x2 Hx2.
+ rewrite Hb, Hc. intros y1 Hy1 y2 Hy2.
+ rewrite Typ.cast_refl.
+ exists (BITVECTOR_LIST.bv_or y1 y2); auto.
+ (*BO_BVxor*)
+ simpl in s.
+ intros. rewrite !andb_true_iff in H. destruct H as ((Ha, Hb), Hc).
+ apply Typ.eqb_spec in Hb.
+ apply Typ.eqb_spec in Hc.
+ rewrite N.eqb_eq in Ha.
+ revert Hb Hc. rewrite Ha in *. intros.
+
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1].
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl.
+ revert x1 Hx1 x2 Hx2.
+ rewrite Hb, Hc. intros y1 Hy1 y2 Hy2.
+ rewrite Typ.cast_refl.
+ exists (BITVECTOR_LIST.bv_xor y1 y2); auto.
+ (*BO_BVadd*)
+ simpl in s.
+ intros. rewrite !andb_true_iff in H. destruct H as ((Ha, Hb), Hc).
+ apply Typ.eqb_spec in Hb.
+ apply Typ.eqb_spec in Hc.
+ rewrite N.eqb_eq in Ha.
+ revert Hb Hc. rewrite Ha in *. intros.
+
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1].
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl.
+ revert x1 Hx1 x2 Hx2.
+ rewrite Hb, Hc. intros y1 Hy1 y2 Hy2.
+ rewrite Typ.cast_refl.
+ exists (BITVECTOR_LIST.bv_add y1 y2); auto.
+ (*BO_BVsubt*)
+ simpl in s.
+ intros. rewrite !andb_true_iff in H. destruct H as ((Ha, Hb), Hc).
+ apply Typ.eqb_spec in Hb.
+ apply Typ.eqb_spec in Hc.
+ rewrite N.eqb_eq in Ha.
+ revert Hb Hc. rewrite Ha in *. intros.
+
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1].
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl.
+ revert x1 Hx1 x2 Hx2.
+ rewrite Hb, Hc. intros y1 Hy1 y2 Hy2.
+ rewrite Typ.cast_refl.
+ exists (BITVECTOR_LIST.bv_subt y1 y2); auto.
+ (*BO_BVmult*)
+ simpl in s.
+ intros. rewrite !andb_true_iff in H. destruct H as ((Ha, Hb), Hc).
+ apply Typ.eqb_spec in Hb.
+ apply Typ.eqb_spec in Hc.
+ rewrite N.eqb_eq in Ha.
+ revert Hb Hc. rewrite Ha in *. intros.
+
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1].
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl.
+ revert x1 Hx1 x2 Hx2.
+ rewrite Hb, Hc. intros y1 Hy1 y2 Hy2.
+ rewrite Typ.cast_refl.
+ exists (BITVECTOR_LIST.bv_mult y1 y2); auto.
+ (*BO_BVult*)
+ intros. rewrite !andb_true_iff in H. destruct H as (Hb, Hc).
+ apply Typ.eqb_spec in Hb.
+ apply Typ.eqb_spec in Hc.
+
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1].
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl.
+ revert x1 Hx1 x2 Hx2.
+ rewrite Hb, Hc. intros y1 Hy1 y2 Hy2.
+ rewrite Typ.cast_refl.
+ exists (BITVECTOR_LIST.bv_ult y1 y2); auto.
+ (*BO_BVslt*)
+ intros. rewrite !andb_true_iff in H. destruct H as (Hb, Hc).
+ apply Typ.eqb_spec in Hb.
+ apply Typ.eqb_spec in Hc.
+
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1].
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl.
+ revert x1 Hx1 x2 Hx2.
+ rewrite Hb, Hc. intros y1 Hy1 y2 Hy2.
+ rewrite Typ.cast_refl.
+ exists (BITVECTOR_LIST.bv_slt y1 y2); auto.
+ (*BO_BVconcat*)
+ intros. rewrite !andb_true_iff in H. destruct H as ((Ha, Hb), Hc).
+ apply N.eqb_eq in Ha.
+ apply Typ.eqb_spec in Hb.
+ apply Typ.eqb_spec in Hc.
+
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1].
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl.
+ revert x1 Hx1 x2 Hx2.
+ rewrite Hb, Hc. intros y1 Hy1 y2 Hy2.
+ rewrite !Typ.cast_refl.
+ rewrite <- Ha.
+ exists (BITVECTOR_LIST.bv_concat y1 y2); auto.
+ (*BO_BVshl*)
+ simpl in s.
+ intros. rewrite !andb_true_iff in H. destruct H as ((Ha, Hb), Hc).
+ apply Typ.eqb_spec in Hb.
+ apply Typ.eqb_spec in Hc.
+ rewrite N.eqb_eq in Ha.
+ revert Hb Hc. rewrite Ha in *. intros.
+
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1].
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl.
+ revert x1 Hx1 x2 Hx2.
+ rewrite Hb, Hc. intros y1 Hy1 y2 Hy2.
+ rewrite Typ.cast_refl.
+ exists (BITVECTOR_LIST.bv_shl y1 y2); auto.
+ (*BO_BVshr*)
+ simpl in s.
+ intros. rewrite !andb_true_iff in H. destruct H as ((Ha, Hb), Hc).
+ apply Typ.eqb_spec in Hb.
+ apply Typ.eqb_spec in Hc.
+ rewrite N.eqb_eq in Ha.
+ revert Hb Hc. rewrite Ha in *. intros.
+
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1].
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl.
+ revert x1 Hx1 x2 Hx2.
+ rewrite Hb, Hc. intros y1 Hy1 y2 Hy2.
+ rewrite Typ.cast_refl.
+ exists (BITVECTOR_LIST.bv_shr y1 y2); auto.
+
+ (* BO_select *)
+ intros t' H.
+ rewrite !andb_true_iff in H.
+ destruct H as ((H1, H2), H3).
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1].
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl.
+ apply Typ.eqb_spec in H1.
+ apply Typ.eqb_spec in H2.
+ apply Typ.eqb_spec in H3.
+ revert x1 Hx1 x2 Hx2.
+ rewrite H2, H3, H1.
+ rewrite !Typ.cast_refl.
+ intros.
+ exists (FArray.select x1 x2); auto.
+
+ (* BO_diffarray *)
+ intros t' H.
+ rewrite !andb_true_iff in H.
+ destruct H as ((H1, H2), H3).
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1].
+ rewrite Hx1; destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2; simpl.
+ apply Typ.eqb_spec in H1.
+ apply Typ.eqb_spec in H2.
+ apply Typ.eqb_spec in H3.
+ revert x1 Hx1 x2 Hx2.
+ rewrite H2, H3, H1.
+ rewrite !Typ.cast_refl.
+ intros.
+ exists (FArray.diff x1 x2); auto.
+
+ (* Ternary operatores *)
+ destruct op as [ti te]; intros [ ti' te' | | | | | ];
+ simpl; try discriminate; unfold is_true.
+ intros H.
+ rewrite !andb_true_iff in H.
+ destruct H as ((((H1, H2), H3), H4), H5).
+ apply Typ.eqb_spec in H1.
+ apply Typ.eqb_spec in H2.
+ apply Typ.eqb_spec in H3.
+ apply Typ.eqb_spec in H4.
+ apply Typ.eqb_spec in H5.
+ destruct (check_aux_interp_hatom h1) as [x1 Hx1]. rewrite Hx1;
+ destruct (check_aux_interp_hatom h2) as [x2 Hx2]; rewrite Hx2;
+ destruct (check_aux_interp_hatom h3) as [x3 Hx3]; rewrite Hx3; simpl.
+ revert x1 Hx1 x2 Hx2 x3 Hx3.
+ rewrite H3, H4, H5, H1, H2.
+ intros.
+ rewrite !Typ.cast_refl.
+ intros.
+ exists (FArray.store x1 x2 x3); auto.
+
(* N-ary operators *)
- destruct op as [A]; simpl; intros [ | | | ]; try discriminate; simpl; intros _; case (compute_interp A nil ha).
+ destruct op as [A]; simpl; intros [ | | | | | ]; try discriminate; simpl; intros _; case (compute_interp A nil ha).
intro l; exists (distinct (Typ.i_eqb t_i A) (rev l)); auto.
exists true; auto.
(* Application *)
intro t; apply check_args_interp_aux.
- Qed.
+Qed.
(* If an atom is not well-typed, its interpretation is bvtrue *)
@@ -1039,15 +2068,201 @@ Module Atom.
(forall T, check_aux get_type a T = false) ->
interp_aux a = bvtrue.
Proof.
- intros [op|op h|op h1 h2|op ha|f l]; simpl.
+ intros [op | op h | op h1 h2 | op h1 h2 h3 | op ha | f l]; simpl.
(* Constants *)
destruct op; simpl; intro H.
discriminate (H Typ.Tpositive).
discriminate (H Typ.TZ).
+ specialize (H (Typ.TBV n)). simpl in H. rewrite N.eqb_refl in H. now contradict H.
(* Unary operators *)
- destruct op; simpl; intro H; destruct (check_aux_interp_hatom h) as [v Hv]; rewrite Hv; simpl; rewrite Typ.neq_cast; try (pose (H2 := H Typ.Tpositive); simpl in H2; rewrite H2; auto); pose (H2 := H Typ.TZ); simpl in H2; rewrite H2; auto.
+ destruct op; simpl; intro H; destruct (check_aux_interp_hatom h) as [v Hv];
+ rewrite Hv; simpl; rewrite Typ.neq_cast;
+ try (pose (H2 := H Typ.Tpositive); simpl in H2; rewrite H2; auto);
+ try (pose (H2 := H Typ.TZ); simpl in H2; rewrite H2; auto);
+ try (pose (H2 := H Typ.Tbool); simpl in H2; rewrite H2; auto);
+ try (pose (H2 := H Typ.TBV); simpl in H2; rewrite H2; auto).
+ (* bv_not *)
+ specialize (H (Typ.TBV n)). simpl in H. rewrite andb_false_iff in H.
+ destruct H as [ H | H].
+ rewrite N.eqb_refl in H. now contradict H.
+ now rewrite H.
+ (* bv_neg *)
+ specialize (H (Typ.TBV n)). simpl in H. rewrite andb_false_iff in H.
+ destruct H as [ H | H].
+ rewrite N.eqb_refl in H. now contradict H.
+ now rewrite H.
+ (* bv_extr *)
+ specialize (H (Typ.TBV n0)). simpl in H. rewrite andb_false_iff in H.
+ destruct H as [ H | H].
+ rewrite N.eqb_refl in H. now contradict H.
+ now rewrite H.
+ (* bv_zextn *)
+ specialize (H (Typ.TBV (i + n))). simpl in H. rewrite andb_false_iff in H.
+ destruct H as [ H | H].
+ rewrite N.eqb_refl in H. now contradict H.
+ now rewrite H.
+ (* bv_sextn *)
+ specialize (H (Typ.TBV (i + n))). simpl in H. rewrite andb_false_iff in H.
+ destruct H as [ H | H].
+ rewrite N.eqb_refl in H. now contradict H.
+ now rewrite H.
(* Binary operators *)
- destruct op; simpl; intro H; destruct (check_aux_interp_hatom h1) as [v1 Hv1]; destruct (check_aux_interp_hatom h2) as [v2 Hv2]; rewrite Hv1, Hv2; simpl; try (pose (H2 := H Typ.TZ); simpl in H2; rewrite andb_false_iff in H2; destruct H2 as [H2|H2]; [rewrite (Typ.neq_cast (get_type h1)), H2|rewrite (Typ.neq_cast (get_type h2)), H2; case (Typ.cast (get_type h1) Typ.TZ)]; auto); try (pose (H2 := H Typ.Tbool); simpl in H2; rewrite andb_false_iff in H2; destruct H2 as [H2|H2]; [rewrite (Typ.neq_cast (get_type h1)), H2|rewrite (Typ.neq_cast (get_type h2)), H2; case (Typ.cast (get_type h1) Typ.TZ)]; auto); case (Typ.cast (get_type h1) t); auto.
+ destruct op; simpl; intro H; destruct (check_aux_interp_hatom h1) as [v1 Hv1];
+ destruct (check_aux_interp_hatom h2) as [v2 Hv2]; rewrite Hv1, Hv2; simpl;
+ try (pose (H2 := H Typ.TZ); simpl in H2; rewrite andb_false_iff in H2;
+ destruct H2 as [H2|H2]; [rewrite (Typ.neq_cast (get_type h1)),
+ H2|rewrite (Typ.neq_cast (get_type h2)), H2; case (Typ.cast (get_type h1) Typ.TZ)]; auto);
+ try (pose (H2 := H Typ.Tbool); simpl in H2; rewrite andb_false_iff in H2; destruct H2 as [H2|H2];
+ [rewrite (Typ.neq_cast (get_type h1)), H2|rewrite (Typ.neq_cast (get_type h2)), H2; case (Typ.cast (get_type h1) Typ.TZ)]; auto);
+ try (pose (H2 := H Typ.TBV); simpl in H2; rewrite !andb_false_iff in H2; destruct H2 as [[H2|H2]|H2];
+ [rewrite N.eqb_refl in H2; discriminate | rewrite (Typ.neq_cast (get_type h1)), H2|rewrite (Typ.neq_cast (get_type h2)), H2;
+ case (Typ.cast (get_type h1) Typ.TBV); case (Typ.cast (get_type h1) Typ.TBV)]; auto).
+ intros. simpl in H.
+ case_eq (Typ.cast (get_type h1) t). easy. easy.
+ case_eq (Typ.cast (get_type h1) t). easy. easy.
+ (*BVand*)
+ specialize (H (Typ.TBV n)). simpl in H.
+ apply andb_false_iff in H. destruct H.
+ specialize (@Typ.cast_diff (get_type h1) (Typ.TBV n)). intros.
+ rewrite andb_false_iff in H. destruct H as [ H | H ].
+ rewrite N.eqb_refl in H. now contradict H.
+ apply Typ.cast_diff in H. now rewrite H.
+ apply Typ.cast_diff in H. rewrite H.
+ case (Typ.cast (get_type h1) (Typ.TBV n)); auto.
+ (*BVor*)
+ specialize (H (Typ.TBV n)). simpl in H.
+ apply andb_false_iff in H. destruct H.
+ specialize (@Typ.cast_diff (get_type h1) (Typ.TBV n)). intros.
+ rewrite andb_false_iff in H. destruct H as [ H | H ].
+ rewrite N.eqb_refl in H. now contradict H.
+ apply Typ.cast_diff in H. now rewrite H.
+ apply Typ.cast_diff in H. rewrite H.
+ case (Typ.cast (get_type h1) (Typ.TBV n)); auto.
+ (*BVxor*)
+ specialize (H (Typ.TBV n)). simpl in H.
+ apply andb_false_iff in H. destruct H.
+ specialize (@Typ.cast_diff (get_type h1) (Typ.TBV n)). intros.
+ rewrite andb_false_iff in H. destruct H as [ H | H ].
+ rewrite N.eqb_refl in H. now contradict H.
+ apply Typ.cast_diff in H. now rewrite H.
+ apply Typ.cast_diff in H. rewrite H.
+ case (Typ.cast (get_type h1) (Typ.TBV n)); auto.
+ (*BVadd*)
+ specialize (H (Typ.TBV n)). simpl in H.
+ apply andb_false_iff in H. destruct H.
+ specialize (@Typ.cast_diff (get_type h1) (Typ.TBV n)). intros.
+ rewrite andb_false_iff in H. destruct H as [ H | H ].
+ rewrite N.eqb_refl in H. now contradict H.
+ apply Typ.cast_diff in H. now rewrite H.
+ apply Typ.cast_diff in H. rewrite H.
+ case (Typ.cast (get_type h1) (Typ.TBV n)); auto.
+ (*BVsubt*)
+ specialize (H (Typ.TBV n)). simpl in H.
+ apply andb_false_iff in H. destruct H.
+ specialize (@Typ.cast_diff (get_type h1) (Typ.TBV n)). intros.
+ rewrite andb_false_iff in H. destruct H as [ H | H ].
+ rewrite N.eqb_refl in H. now contradict H.
+ apply Typ.cast_diff in H. now rewrite H.
+ apply Typ.cast_diff in H. rewrite H.
+ case (Typ.cast (get_type h1) (Typ.TBV n)); auto.
+ (*BVmult*)
+ specialize (H (Typ.TBV n)). simpl in H.
+ apply andb_false_iff in H. destruct H.
+ specialize (@Typ.cast_diff (get_type h1) (Typ.TBV n)). intros.
+ rewrite andb_false_iff in H. destruct H as [ H | H ].
+ rewrite N.eqb_refl in H. now contradict H.
+ apply Typ.cast_diff in H. now rewrite H.
+ apply Typ.cast_diff in H. rewrite H.
+ case (Typ.cast (get_type h1) (Typ.TBV n)); auto.
+ (*BVult*)
+ specialize (H Typ.Tbool). simpl in H.
+ apply andb_false_iff in H. destruct H.
+ specialize (@Typ.cast_diff (get_type h1) (Typ.TBV n)). intros.
+ specialize (H0 H). now rewrite H0.
+
+ case_eq (Typ.cast (get_type h1) (Typ.TBV n)). intros.
+ specialize (@Typ.cast_diff (get_type h2) (Typ.TBV n)). intros.
+ specialize (H1 H). easy.
+ easy.
+
+ case_eq (Typ.cast (get_type h1) (Typ.TBV n)). intros.
+ specialize (@Typ.cast_diff (get_type h2) (Typ.TBV n)). intros.
+ specialize (H1 H2). easy.
+ easy.
+
+ (*BVslt*)
+ specialize (H Typ.Tbool). simpl in H.
+ apply andb_false_iff in H. destruct H.
+ specialize (@Typ.cast_diff (get_type h1) (Typ.TBV n)). intros.
+ specialize (H0 H). now rewrite H0.
+
+ case_eq (Typ.cast (get_type h1) (Typ.TBV n)). intros.
+ specialize (@Typ.cast_diff (get_type h2) (Typ.TBV n)). intros.
+ specialize (H1 H). easy.
+ easy.
+
+ case_eq (Typ.cast (get_type h1) (Typ.TBV n)). intros.
+ specialize (@Typ.cast_diff (get_type h2) (Typ.TBV n)). intros.
+ specialize (H1 H2). easy.
+ easy.
+ (*BVconcat*)
+ specialize (H (Typ.TBV (n+n0))). simpl in H.
+ apply andb_false_iff in H. destruct H.
+ specialize (@Typ.cast_diff (get_type h1) (Typ.TBV n)). intros.
+ rewrite andb_false_iff in H. destruct H as [ H | H ].
+ rewrite N.eqb_refl in H. now contradict H.
+ apply Typ.cast_diff in H. now rewrite H.
+ apply Typ.cast_diff in H. rewrite H.
+ case (Typ.cast (get_type h1) (Typ.TBV n)); auto.
+ (*BVshl*)
+ specialize (H (Typ.TBV n)). simpl in H.
+ apply andb_false_iff in H. destruct H.
+ specialize (@Typ.cast_diff (get_type h1) (Typ.TBV n)). intros.
+ rewrite andb_false_iff in H. destruct H as [ H | H ].
+ rewrite N.eqb_refl in H. now contradict H.
+ apply Typ.cast_diff in H. now rewrite H.
+ apply Typ.cast_diff in H. rewrite H.
+ case (Typ.cast (get_type h1) (Typ.TBV n)); auto.
+ (*BVshr*)
+ specialize (H (Typ.TBV n)). simpl in H.
+ apply andb_false_iff in H. destruct H.
+ specialize (@Typ.cast_diff (get_type h1) (Typ.TBV n)). intros.
+ rewrite andb_false_iff in H. destruct H as [ H | H ].
+ rewrite N.eqb_refl in H. now contradict H.
+ apply Typ.cast_diff in H. now rewrite H.
+ apply Typ.cast_diff in H. rewrite H.
+ case (Typ.cast (get_type h1) (Typ.TBV n)); auto.
+
+ (* BO_select *)
+ specialize (H t0). simpl in H.
+ rewrite !andb_false_iff in H. destruct H. destruct H.
+ rewrite Typ.eqb_refl in H. now contradict H.
+ rewrite (Typ.cast_diff _ _ H); auto.
+ rewrite (Typ.cast_diff _ _ H); auto.
+ case (Typ.cast (get_type h1) (Typ.TFArray t t0)); auto.
+
+ (* BO_diffarray *)
+ specialize (H t). simpl in H.
+ rewrite !andb_false_iff in H. destruct H. destruct H.
+ rewrite Typ.eqb_refl in H. now contradict H.
+ rewrite (Typ.cast_diff _ _ H); auto.
+ rewrite (Typ.cast_diff _ _ H); auto.
+ case (Typ.cast (get_type h1) (Typ.TFArray t t0)); auto.
+
+ (* Ternary operators *)
+ destruct op; simpl; intro H;
+ destruct (check_aux_interp_hatom h1) as [v1 Hv1];
+ destruct (check_aux_interp_hatom h2) as [v2 Hv2];
+ destruct (check_aux_interp_hatom h3) as [v3 Hv3];
+ rewrite Hv1, Hv2, Hv3; simpl.
+ specialize (H (Typ.TFArray t t0)). simpl in H.
+ rewrite !andb_false_iff in H.
+ destruct H as [[ [ [ H | H] | H] | H] | H];
+ try (rewrite (Typ.cast_diff _ _ H); auto);
+ try (case (Typ.cast (get_type h1) (Typ.TFArray t t0)); auto);
+ try (rewrite !Typ.eqb_refl in H; now contradict H).
+ intros. case (Typ.cast (get_type h2) t); auto.
+
(* N-ary operators *)
destruct op as [A]; simpl; intro H; generalize (H Typ.Tbool); simpl; clear H; assert (H: forall l1, List.forallb (fun t1 : int => Typ.eqb (get_type t1) A) ha = false -> match compute_interp A l1 ha with | Some l => Bval Typ.Tbool (distinct (Typ.i_eqb t_i A) (rev l)) | None => bvtrue end = bvtrue).
induction ha as [ |h ha Iha]; simpl.
@@ -1058,7 +2273,7 @@ Module Atom.
apply H.
(* Application *)
apply check_args_interp_aux_contr.
- Qed.
+Qed.
End Interp_Aux.
@@ -1075,6 +2290,7 @@ Module Atom.
| Acop _ => true
| Auop _ h => h < i
| Abop _ h1 h2 => (h1 < i) && (h2 < i)
+ | Atop _ h1 h2 h3 => (h1 < i) && (h2 < i) && (h3 < i)
| Anop _ ha => List.forallb (fun h => h < i) ha
| Aapp f args => List.forallb (fun h => h < i) args
end.
@@ -1089,6 +2305,8 @@ Module Atom.
rewrite Hf;trivial.
(* Binary operators *)
unfold is_true in H;rewrite andb_true_iff in H;destruct H;rewrite !Hf;trivial.
+ (* Ternary operators *)
+ unfold is_true in H;rewrite !andb_true_iff in H;do 2 destruct H;rewrite !Hf;trivial.
(* N-ary operators *)
destruct n as [A]; replace (compute_interp f1 A nil l) with (compute_interp f2 A nil l); trivial; assert (H1: forall acc, compute_interp f2 A acc l = compute_interp f1 A acc l); auto; induction l as [ |k l IHl]; simpl; auto; intro acc; simpl in H; unfold is_true in H; rewrite andb_true_iff in H; destruct H as [H1 H2]; rewrite (Hf _ H1); destruct (f2 k) as [ta va]; destruct (Typ.cast ta A) as [ka| ]; auto.
(* Application *)
@@ -1205,18 +2423,32 @@ Module Atom.
intros h Hh a IH; generalize (wf_t_i h Hh).
case (t_atom.[h]); simpl.
(* Constants *)
- intros [ | ] _; simpl.
+ intros [ | | ] _; simpl.
exists 1%positive; auto.
exists 0%Z; auto.
+ exists (BITVECTOR_LIST._of_bits l n); auto.
(* Unary operators *)
- intros [ | | | | ] i H; simpl; destruct (IH i H) as [x Hx]; rewrite Hx; simpl.
+
+ intros [ | | | | | | | | i0 n0 n1| n i0| n i0] i H;
+ simpl; destruct (IH i H) as [x Hx]; rewrite Hx; simpl.
+
case (Typ.cast (v_type Typ.type interp_t (a .[ i])) Typ.Tpositive); simpl; try (exists true; auto); intro k; exists ((k interp_t x)~0)%positive; auto.
case (Typ.cast (v_type Typ.type interp_t (a .[ i])) Typ.Tpositive); simpl; try (exists true; auto); intro k; exists ((k interp_t x)~1)%positive; auto.
case (Typ.cast (v_type Typ.type interp_t (a .[ i])) Typ.Tpositive); simpl; try (exists true; auto); intro k; exists (Zpos (k interp_t x)); auto.
case (Typ.cast (v_type Typ.type interp_t (a .[ i])) Typ.Tpositive); simpl; try (exists true; auto); intro k; exists (Zneg (k interp_t x)); auto.
case (Typ.cast (v_type Typ.type interp_t (a .[ i])) Typ.TZ); simpl; try (exists true; auto); intro k; exists (- k interp_t x)%Z; auto.
- (* Binary operators *)
- intros [ | | | | | | |A] h1 h2; simpl; rewrite andb_true_iff; intros [H1 H2]; destruct (IH h1 H1) as [x Hx]; destruct (IH h2 H2) as [y Hy]; rewrite Hx, Hy; simpl.
+ case (Typ.cast (v_type Typ.type interp_t (a .[ i])) (Typ.TBV n)); simpl; [ | exists true; auto]. intro k; exists (BITVECTOR_LIST.bitOf n0 (k interp_t x)) ; auto.
+ case (Typ.cast (v_type Typ.type interp_t (a .[ i])) (Typ.TBV n)); simpl; [ | exists true; auto]. intro k; exists (BITVECTOR_LIST.bv_not (k interp_t x)) ; auto.
+ case (Typ.cast (v_type Typ.type interp_t (a .[ i])) (Typ.TBV n)); simpl; [ | exists true; auto]. intro k; exists (BITVECTOR_LIST.bv_neg (k interp_t x)) ; auto.
+ case (Typ.cast (v_type Typ.type interp_t (a .[ i])) (Typ.TBV n1));
+ simpl; [ | exists true; auto]. intro k; exists (BITVECTOR_LIST.bv_extr i0 n0 (k interp_t x)) ; auto.
+ case (Typ.cast (v_type Typ.type interp_t (a .[ i])) (Typ.TBV n));
+ simpl; [ | exists true; auto]. intro k. exists (BITVECTOR_LIST.bv_zextn i0 (k interp_t x)) ; auto.
+ case (Typ.cast (v_type Typ.type interp_t (a .[ i])) (Typ.TBV n));
+ simpl; [ | exists true; auto]. intro k. exists (BITVECTOR_LIST.bv_sextn i0 (k interp_t x)) ; auto.
+
+ (* Binary operators *)
+ intros [ | | | | | | |A | | | | | | | | | | | | ti te| ti te] h1 h2; simpl; rewrite andb_true_iff; intros [H1 H2]; destruct (IH h1 H1) as [x Hx]; destruct (IH h2 H2) as [y Hy]; rewrite Hx, Hy; simpl.
case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) Typ.TZ); simpl; try (exists true; auto); intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) Typ.TZ); simpl; try (exists true; auto); intro k2; exists (k1 interp_t x + k2 interp_t y)%Z; auto.
case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) Typ.TZ); simpl; try (exists true; auto); intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) Typ.TZ); simpl; try (exists true; auto); intro k2; exists (k1 interp_t x - k2 interp_t y)%Z; auto.
case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) Typ.TZ); simpl; try (exists true; auto); intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) Typ.TZ); simpl; try (exists true; auto); intro k2; exists (k1 interp_t x * k2 interp_t y)%Z; auto.
@@ -1225,13 +2457,95 @@ Module Atom.
case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) Typ.TZ); simpl; try (exists true; auto); intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) Typ.TZ) as [k2| ]; simpl; try (exists true; reflexivity); exists (k1 interp_t x >=? k2 interp_t y); auto.
case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) Typ.TZ); simpl; try (exists true; auto); intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) Typ.TZ) as [k2| ]; simpl; try (exists true; reflexivity); exists (k1 interp_t x >? k2 interp_t y); auto.
case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) A); simpl; try (exists true; auto); intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) A) as [k2| ]; simpl; try (exists true; reflexivity); exists (Typ.i_eqb t_i A (k1 interp_t x) (k2 interp_t y)); auto.
+
+ (*BO_BVand*)
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) (Typ.TBV n)); simpl; try (exists true; auto);
+ intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) (Typ.TBV n)) as [k2| ];
+ simpl; try (exists true; reflexivity); exists (BITVECTOR_LIST.bv_and (k1 interp_t x) (k2 interp_t y));
+ auto.
+ (*BO_BVor*)
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) (Typ.TBV n)); simpl; try (exists true; auto);
+ intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) (Typ.TBV n)) as [k2| ];
+ simpl; try (exists true; reflexivity); exists (BITVECTOR_LIST.bv_or (k1 interp_t x) (k2 interp_t y));
+ auto.
+ (*BO_BVxor*)
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) (Typ.TBV n)); simpl; try (exists true; auto);
+ intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) (Typ.TBV n)) as [k2| ];
+ simpl; try (exists true; reflexivity); exists (BITVECTOR_LIST.bv_xor (k1 interp_t x) (k2 interp_t y));
+ auto.
+ (*BO_BVadd*)
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) (Typ.TBV n)); simpl; try (exists true; auto);
+ intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) (Typ.TBV n)) as [k2| ];
+ simpl; try (exists true; reflexivity); exists (BITVECTOR_LIST.bv_add (k1 interp_t x) (k2 interp_t y));
+ auto.
+ (*BO_BVsubst*)
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) (Typ.TBV n)); simpl; try (exists true; auto);
+ intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) (Typ.TBV n)) as [k2| ];
+ simpl; try (exists true; reflexivity); exists (BITVECTOR_LIST.bv_subt (k1 interp_t x) (k2 interp_t y)); auto.
+ (*BO_BVmult*)
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) (Typ.TBV n)); simpl; try (exists true; auto);
+ intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) (Typ.TBV n)) as [k2| ];
+ simpl; try (exists true; reflexivity); exists (BITVECTOR_LIST.bv_mult (k1 interp_t x) (k2 interp_t y));
+ auto.
+ (*BO_BVult*)
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) (Typ.TBV n)); simpl; try (exists true; auto);
+ intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) (Typ.TBV n)) as [k2| ];
+ simpl; try (exists true; reflexivity); exists (BITVECTOR_LIST.bv_ult (k1 interp_t x) (k2 interp_t y));
+ auto.
+ (*BO_BVslt*)
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) (Typ.TBV n)); simpl; try (exists true; auto);
+ intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) (Typ.TBV n)) as [k2| ];
+ simpl; try (exists true; reflexivity); exists (BITVECTOR_LIST.bv_slt (k1 interp_t x) (k2 interp_t y));
+ auto.
+ (*BO_BVconcat*)
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) (Typ.TBV (n))); simpl; try (exists true; auto);
+ intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) (Typ.TBV (n0))) as [k2| ];
+ simpl; try (exists true; reflexivity); exists (BITVECTOR_LIST.bv_concat (k1 interp_t x) (k2 interp_t y));
+ auto.
+ (*BO_BVshl*)
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) (Typ.TBV n)); simpl; try (exists true; auto);
+ intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) (Typ.TBV n)) as [k2| ];
+ simpl; try (exists true; reflexivity); exists (BITVECTOR_LIST.bv_shl (k1 interp_t x) (k2 interp_t y));
+ auto.
+ (*BO_BVshr*)
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) (Typ.TBV n)); simpl; try (exists true; auto);
+ intro k1; case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) (Typ.TBV n)) as [k2| ];
+ simpl; try (exists true; reflexivity); exists (BITVECTOR_LIST.bv_shr (k1 interp_t x) (k2 interp_t y));
+ auto.
+ (* BO_select *)
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) (Typ.TFArray ti te) );
+ simpl; try (exists true; auto); intro k1;
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) ti) as [k2| ];
+ simpl; try (exists true; reflexivity).
+ exists (FArray.select (k1 interp_t x) (k2 interp_t y)); auto.
+
+ (* BO_diffarray *)
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) (Typ.TFArray ti te) );
+ simpl; try (exists true; auto); intro k1;
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) (Typ.TFArray ti te)) as [k2| ];
+ simpl; try (exists true; reflexivity).
+ exists (FArray.diff (k1 interp_t x) (k2 interp_t y)); auto.
+
+ (* Ternary operators *)
+ intros [ti te] h1 h2 h3; simpl; rewrite !andb_true_iff; intros [[H1 H2] H3];
+ destruct (IH h1 H1) as [x Hx];
+ destruct (IH h2 H2) as [y Hy];
+ destruct (IH h3 H3) as [z Hz]; rewrite Hx, Hy, Hz; simpl.
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h1])) (Typ.TFArray ti te) );
+ simpl; try (exists true; auto); intro k1;
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h2])) ti );
+ simpl; try (exists true; auto); intro k2;
+ case (Typ.cast (v_type Typ.type interp_t (a .[ h3])) te) as [k3| ];
+ simpl; try (exists true; reflexivity).
+ exists (FArray.store (k1 interp_t x) (k2 interp_t y) (k3 interp_t z)); auto.
+
(* N-ary operators *)
intros [A] l; assert (forall acc, List.forallb (fun h0 : int => h0 < h) l = true -> exists v, match compute_interp (get a) A acc l with | Some l0 => Bval Typ.Tbool (distinct (Typ.i_eqb t_i A) (rev l0)) | None => bvtrue end = Bval (v_type Typ.type interp_t match compute_interp (get a) A acc l with | Some l0 => Bval Typ.Tbool (distinct (Typ.i_eqb t_i A) (rev l0)) | None => bvtrue end) v); auto; induction l as [ |i l IHl]; simpl.
intros acc _; exists (distinct (Typ.i_eqb t_i A) (rev acc)); auto.
intro acc; rewrite andb_true_iff; intros [H1 H2]; destruct (IH _ H1) as [va Hva]; rewrite Hva; simpl; case (Typ.cast (v_type Typ.type interp_t (a .[ i])) A); simpl; try (exists true; auto); intro k; destruct (IHl (k interp_t va :: acc) H2) as [vb Hvb]; exists vb; auto.
(* Application *)
intros i l H; apply (check_aux_interp_aux_lt_aux a h IH l H (t_func.[i])).
- Qed.
+Qed.
Lemma check_aux_interp_hatom_lt : forall h, h < length t_atom ->
exists v, t_interp.[h] = Bval (get_type h) v.
@@ -1302,6 +2616,11 @@ Module Atom.
let interp := interp_hatom t_atom in
fun a => interp_bool (interp a).
+ Definition interp_form_hatom_bv t_atom :
+ hatom -> forall s, BITVECTOR_LIST.bitvector s :=
+ let interp := interp_hatom t_atom in
+ fun a s => interp_bv (interp a) s.
+
End Typing_Interp.
Definition check_atom t_atom :=
@@ -1319,3 +2638,24 @@ Module Atom.
End Atom.
Arguments Atom.Val {_} {_} _ _.
+
+(* These definitions are not used. This is just a hack, Coq refuses to
+ construct PArrays from OCaml if these are not here for some silly reason *)
+(*
+Section PredefinedArrays.
+ Variable t_i : PArray.array typ_compdec.
+
+ Definition mkarray_typ_compdec := @PArray.make typ_compdec.
+ Definition arrayset_typ_compdec := @PArray.set typ_compdec.
+
+ Definition mkarray_func := @PArray.make (Atom.tval t_i).
+ Definition arrayset_func := @PArray.set (Atom.tval t_i).
+
+ Definition mkarray_form := @PArray.make Form.form.
+ Definition arrayset_form := @PArray.set Form.form.
+
+ Definition mkarray_atom := @PArray.make Atom.atom.
+ Definition arrayset_atom := @PArray.set Atom.atom.
+
+End PredefinedArrays.
+*)