Library reverse_list_auto

Load seplog_header.

Require Import Omega.
Require Import frag_list_entail.
Require Import frag_list_triple.
Require Import frag_list_vcg.

Require Import expr_b_dp.

Open Local Scope frag2_scope.

Coercion var_e : var.v >-> expr.
Coercion int_e : val >-> expr.
Coercion nat_e : nat >-> expr.

Definition next := 0%Z.
Definition data := 1%Z.
Definition i : var.v := 2.
Definition j : var.v := 3.
Definition k : var.v := 4.

Definition reverse_list_precond :=
  (true_b, lst i 0)::nil.

Definition reverse_list_postcond :=
  (true_b, lst j 0)::nil.

Definition invariant :=
  (
    (i == 0 , lst j 0)::
    (i =/= 0, star (lst i 0) (lst j 0))
    ::
    nil
  ).

Definition invariant_auto :=
  (
    ((i =/= 0) &&& (j == 0), (lst i 0))::
    ((j =/= 0) &&& (i == k), star (lst k 0) (lst j 0))
    ::
    nil
  ).

Definition invariant2 :=
  (
    (true_b, star (lst i 0) (lst j 0))
    ::
    nil
  ).

Definition reverse_list : cmd' :=
  (j <- 0);
  while' (i =/= 0) invariant2
    
  (

      (k <-* (i -.> next));
      ((i -.> next) *<- j);
      (j <- i);
      (i <- k)

  ).

Goal
  {{Assrt_interp reverse_list_precond}} (proj_cmd reverse_list) {{Assrt_interp reverse_list_postcond}}.