Library example_reverse_list
Load seplog_header.
Definition data := 0%Z.
Definition next := 1%Z.
Ltac Unfolds_fields := unfold data; unfold next.
Definition reverse_list (i j k:var.v) :=
j <- nat_e 0;
while (var_e i =/= nat_e 0) (
k <-* (i -.> next);
(i -.> next) *<- var_e j;
j <- var_e i;
i <- var_e k
).
Inductive list_assert : list Z -> nat -> nat -> store.s -> heap.h -> Prop :=
list_end : forall i j l s h,
sep.emp s h ->
i = j ->
l = nil ->
list_assert l i j s h
| list_suiv: forall l l' d i j k s h h1 h2,
h1 # h2 ->
h = (h1 +++ h2) ->
i <> k ->
i <> j ->
l = d::l' ->
(nat_e i |--> int_e d::nat_e j::nil) s h1 ->
(list_assert l' j k) s h2 ->
list_assert l i k s h.
Definition list_empty : list Z := nil.
Fixpoint list_reverse_coq (l:list Z) : list Z :=
match l with
nil => nil
| a :: l' => list_reverse_coq l' ++ a::nil
end.
Eval compute in (list_reverse_coq (3::6::8::1::8::9::13::nil)%Z).
Lemma list_reverse_coq_lemma1: forall l a,
list_reverse_coq (l ++ a::nil) = a::list_reverse_coq l.
Lemma list_reverse_coq_lemma2: forall l,
list_reverse_coq (list_reverse_coq l) = l.
Lemma list_assert_inde_store: forall l i j s1 s2 h,
list_assert l i j s1 h -> list_assert l i j s2 h.
Definition reverse_precondition (l: list Z) (hd: var.v) : assert :=
fun s h => exists v, eval (var_e hd) s = Z_of_nat v /\ (list_assert l v 0) s h.
Definition reverse_postcondition (l: list Z) (hd: var.v) : assert :=
fun s h => exists v, eval (var_e hd) s = Z_of_nat v /\ (list_assert (list_reverse_coq l) v 0) s h.
Definition reverse_list_specif: Prop := forall l i j k,
var.set (i::j::k::nil) ->
{{reverse_precondition l i}}
reverse_list i j k
{{reverse_postcondition l j}}.
Lemma list_assert_hd_uneq: forall l1 l2 hd1 hd2 s h,
(list_assert l1 hd1 0 ** list_assert l2 hd2 0) s h -> hd1 <> 0 ->
hd1 <> hd2.
Ltac Decompose_inverse_list_hyp := red; intros; Decompose_hyp.
Ltac Resolve_inverse_list_goal :=
match goal with
| |- ?P1 /\ ?P2 => split; [Resolve_inverse_list_goal | Resolve_inverse_list_goal]
| id: list_assert ?l ?st ?ed ?s1 ?h1 |- list_assert ?l ?st ?ed ?s2 ?h2 => assert (A1: h2 = h1); [Heap_emp_clean; Equal_heap | rewrite A1; clear A1; eapply (list_assert_inde_store); apply id]
| id: list_assert ?l ?st ?ed ?s1 ?h |- list_assert ?l ?st ?ed ?s2 ?h => eapply (list_assert_inde_store); apply id
| |- update_store2 ?x ?v ?P => red; Resolve_inverse_list_goal
| |- _ => (Store_update || auto)
| _ => idtac
end.
Ltac Resolve_inverse_list:= Decompose_inverse_list_hyp; Resolve_inverse_list_goal.
Lemma reverse_list_verif: reverse_list_specif.