*)

(* Specifications: *)
Lemma Znth_nil: forall {A}{d: Inhabitant A} n, Znth n nil = default.
Lemma offset_val_zero_Vptr: forall b i, offset_val 0 (Vptr b i) = Vptr b i.
(* Ltac AUTO_IND := match goal with | H: complete_legal_cosu_type (Tarray ?t ?n ?a) = true |- complete_legal_cosu_type ?t = true => simpl in H; auto | H: (alignof (Tarray ?t ?z ?a) | ?ofs) |- (alignof ?t | ?ofs + _) => apply Z.divide_add_r; [ eapply Z.divide_trans; [eapply alignof_divide_alignof_Tarray |]; eauto | apply Z.divide_mul_l; eapply legal_alignas_type_Tarray; eauto] | H: legal_alignas_type (Tstruct ?id ?a) = true |- legal_alignas_type (field_type ?i (co_members (get_co ?id))) = true => unfold legal_alignas_type in H; apply nested_pred_Tstruct2 with (i0 := i) in H; [exact H | auto] | H: legal_cosu_type (Tstruct ?id ?a) = true |- legal_cosu_type (field_type ?i (co_members (get_co ?id))) = true => unfold legal_cosu_type in H; apply nested_pred_Tstruct2 with (i0 := i) in H; [exact H | auto] | |- complete_type ?env (field_type ?i (co_members (get_co ?id))) = true => apply complete_type_field_type; auto | H: (alignof (Tstruct ?id ?a) | ?ofs) |- (alignof (field_type ?i (co_members (get_co ?id))) | ?ofs + _) => apply Z.divide_add_r; [ eapply Z.divide_trans; [apply alignof_field_type_divide_alignof; auto |]; eapply Z.divide_trans; [apply legal_alignas_type_Tstruct; eauto | auto] | apply field_offset_aligned] | H: legal_alignas_type (Tunion ?id ?a) = true |- legal_alignas_type (field_type ?i (co_members (get_co ?id))) = true => unfold legal_alignas_type in H; apply nested_pred_Tunion2 with (i0 := i) in H; [exact H | auto] | H: legal_cosu_type (Tunion ?id ?a) = true |- legal_cosu_type (field_type ?i (co_members (get_co ?id))) = true => unfold legal_cosu_type in H; apply nested_pred_Tunion2 with (i0 := i) in H; [exact H | auto] | H: (alignof (Tunion ?id ?a) | ?ofs) |- (alignof (field_type ?i (co_members (get_co ?id))) | ?ofs) => eapply Z.divide_trans; [apply alignof_field_type_divide_alignof; auto |]; eapply Z.divide_trans; [apply legal_alignas_type_Tunion; eauto | auto] end. *)
Lemma nth_list_repeat: forall A i n (x :A),
nth i (list_repeat n x) x = x.
Lemma nth_list_repeat': forall A i n (x y :A),
(i < n)%nat ->
nth i (list_repeat n x) y = x.
Lemma Z2Nat_max0: forall z, Z.to_nat (Z.max 0 z) = Z.to_nat z.
Lemma range_max0: forall x z, 0 <= x < Z.max 0 z <-> 0 <= x < z.
(* We use (Vptr b (Int.repr ofs)) instead of p because size_compatible is more  *)
(* difficult to use than simple arithmetic in induction proof.                  *)
Lemma memory_block_data_at_rec_default_val: forall sh t b ofs
(LEGAL_COSU: complete_legal_cosu_type t = true),
0 <= ofs /\ ofs + sizeof t < Ptrofs.modulus ->
align_compatible_rec cenv_cs t ofs ->
data_at_rec sh t (default_val t) (Vptr b (Ptrofs.repr ofs)) =
memory_block sh (sizeof t) (Vptr b (Ptrofs.repr ofs)).
Lemma firstn_exact :
forall {A : Type} (l1 l2 : list A) (n : nat),
(length l1 = n)%nat -> firstn n (l1 ++ l2) = l1.
Lemma skipn_exact :
forall {A : Type} (l1 l2 : list A) (n : nat),
(length l1 = n)%nat -> skipn n (l1 ++ l2) = l2.
Lemma length_not_emp :
forall {A B : Type} (l : list A) (z y : B),
(Datatypes.length l > 0)%nat -> match l with [] => z | _ => y end = y.
Lemma list_splitLength {A}: forall n (l:list A) m,
length l = (n + m)%nat -> exists l1 l2, l = l1 ++ l2 /\ length l1 = n /\ length l2 = m.
Lemma skipn_short {A}: forall n (l:list A), (length l <= n)%nat -> skipn n l = nil.
Lemma skipn_app2:
forall A n (al bl: list A),
(n >= length al)%nat ->
skipn n (al++bl) = skipn (n-length al) bl.