(* solve list equations *)
(* interpreted functions : Zlength app list_repeat / Zrepeat map sublist upd_Znth -> sublist Znth *)
Definition data_subsume {cs : compspecs} (t : type) (x y : reptype t) : Prop :=
forall sh p, data_at sh t x p |-- data_at sh t y p.
Ltac apply_list_ext :=
first
[ apply data_subsume_array_ext;
only 1, 2 : Zlength_solve
| match goal with |- @eq ?list_A _ _ =>
match eval compute in list_A with list ?A =>
apply (@Znth_eq_ext A ltac:(auto with typeclass_instances))
end
end;
only 1 : Zlength_solve
];
autorewrite with Zlength;
intros.
(************* range_form *********************)
Ltac apply_in lem H :=
apply lem in H.
Ltac apply_in_hyps' lem :=
repeat match goal with
| H : ?T |- _ => apply lem in H; let n := numgoals in guard n = 1
end.
Tactic Notation "apply_in_hyps" uconstr(lem) := apply_in_hyps' lem.
Ltac apply_in_hyps_with_Zlength_solve lem :=
repeat match goal with
| H : _ |- _ => apply -> lem in H; [idtac | Zlength_solve ..]
end.
Ltac apply_in_hyps_with_Zlength_solve_destruct lem :=
repeat match goal with
| H : _ |- _ => apply -> lem in H; [destruct H | Zlength_solve ..]
end.
Ltac rewrite_In_Znth_iff :=
repeat match goal with
| H : In ?x ?l |- _ =>
rewrite In_Znth_iff in H;
destruct H as [? []]
end.
Ltac range_form :=
apply_in_hyps not_In_range_uni;
apply_in_hyps eq_range_bin_no_offset;
apply_in_hyps eq_range_bin_offset;
apply_in_hyps eq_range_bin_left_offset;
apply_in_hyps eq_range_bin_minus_offset;
apply_in_hyps eq_range_bin_reverse;
apply_in_hyps eq_range_bin_reverse_left_offset;
apply_in_hyps eq_range_bin_reverse_minus_offset;
rewrite_In_Znth_iff.
(**************** range tactics **************************)
Ltac range_rewrite :=
apply_in_hyps_with_Zlength_solve range_uni_app1;
apply_in_hyps_with_Zlength_solve range_uni_app2;
apply_in_hyps_with_Zlength_solve_destruct range_uni_app;
apply_in_hyps_with_Zlength_solve range_uni_sublist;
apply_in_hyps_with_Zlength_solve range_uni_map;
apply_in_hyps_with_Zlength_solve range_uni_Zrepeat;
apply_in_hyps_with_Zlength_solve range_uni_empty;
apply_in_hyps_with_Zlength_solve range_binA_app1;
apply_in_hyps_with_Zlength_solve range_binA_app2;
apply_in_hyps_with_Zlength_solve_destruct range_binA_app;
apply_in_hyps_with_Zlength_solve range_binA_sublist;
apply_in_hyps_with_Zlength_solve range_binA_map;
apply_in_hyps_with_Zlength_solve range_binA_Zrepeat;
apply_in_hyps_with_Zlength_solve range_binB_app1;
apply_in_hyps_with_Zlength_solve range_binB_app2;
apply_in_hyps_with_Zlength_solve_destruct range_binB_app;
apply_in_hyps_with_Zlength_solve range_binB_sublist;
apply_in_hyps_with_Zlength_solve range_binB_map;
apply_in_hyps_with_Zlength_solve range_binB_Zrepeat;
apply_in_hyps_with_Zlength_solve range_bin_empty.

Lemma range_le_lt_dec : forall lo i hi,
(lo <= i < hi) + ~(lo <= i < hi).