Library frag_list_examples

Load seplog_header.

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

Definition i : var.v := 1.
Definition j : var.v := 2.
Definition x : var.v := 4.
Definition y : var.v := 3.
Definition vx : var.v := 5.
Definition vy : var.v := 6.

Definition swap (x y:var.v) : cmd :=
    i <-* var_e x;
    j <-* var_e y;
    var_e x *<- var_e j;
    var_e y *<- var_e i.

Definition swap_precond (x y:var.v) (vx vy : nat) : assrt :=
  (true_b, star (singl (var_e x) (var_e vx)) (singl (var_e y) (var_e vy))).

Definition swap_postcond (x y:var.v) (vx vy : nat) : assrt :=
  (true_b, star (singl (var_e x) (var_e vy)) (singl (var_e y) (var_e vx))).

Lemma tmp : forall (P Q:assert), P ==> Q ->
  P ==> (fun s h => Q s h \/ False).

Lemma swap_verif:
    {{ assrt_interp (swap_precond x y vx vy) }}
    swap x y
    {{ Assrt_interp ((swap_postcond x y vx vy)::nil) }}.


Lemma swap_verif':
    {{ Assrt_interp ((swap_precond x y vx vy)::nil) }}
    swap x y
    {{ Assrt_interp ((swap_postcond x y vx vy)::nil) }}.

Open Local Scope frag2_scope.


Close Local Scope frag2_scope.


Definition ptr : var.v := 1.
Definition startl : var.v := 2.
Definition size: var.v := 3.
Definition idx: var.v := 4.
Definition init_val: var.v := 5.

Fixpoint init_body (n: nat) {struct n} : cmd :=
  match n with
    0 => skip
    | S n' =>
      ((var_e ptr) +e (var_e idx)) *<- var_e init_val;
       ptr <- (var_e ptr) +e (var_e size);
       init_body n'
   end.

Definition init (n: nat) : cmd :=
    ptr <- var_e startl;
    init_body n.

Fixpoint init_precond_sigma (n: nat) {struct n} : Sigma :=
  match n with
    0 => emp
    | S n' => star
        (cell (((var_e startl) +e (var_e idx)) +e ((var_e size) *e (int_e (Z_of_nat n'))) ))
        (init_precond_sigma n')
end.

Definition init_precond (n: nat) : assrt :=
  (var_e startl >> int_e 0%Z, init_precond_sigma n).

Fixpoint init_postcond_sigma (n: nat) {struct n}: Sigma :=
  match n with
    0 => emp
    | S n' => star
        (singl (((var_e startl) +e (var_e idx)) +e ((var_e size) *e (int_e (Z_of_nat n'))) ) (var_e init_val))
        (init_postcond_sigma n')
end.

Definition init_postcond (n: nat) : assrt :=
  (var_e startl >> int_e 0%Z, init_postcond_sigma n).

Lemma init_verif: forall n,
    n = 6 ->
    {{ assrt_interp (init_precond n) }}
    (init n)
    {{ Assrt_interp (init_postcond n::nil) }}.




Lemma init_verif': forall n,
    n = 2 ->
    {{ Assrt_interp (init_precond n :: nil) }}
    (init n)
    {{ Assrt_interp (init_postcond n :: nil) }}.


Open Local Scope frag2_scope.


Close Local Scope frag2_scope.


Goal
  {{ assrt_interp (true_b, emp) }}
  ifte (var_e 1 >>= var_e 2) thendo
    ifte (var_e 1 >>= var_e 3) thendo
      (0 <- var_e 1)
    elsedo
      (0 <- var_e 3)
  elsedo
    ifte (var_e 2 >>= var_e 3) thendo
      (0 <- var_e 2)
    elsedo
      (0 <- var_e 3)
  {{ Assrt_interp ((true_b,emp)::nil) }}.



Goal
  {{ Assrt_interp ((true_b, emp)::nil) }}
  ifte (var_e 1 >>= var_e 2) thendo
    ifte (var_e 1 >>= var_e 3) thendo
      (0 <- var_e 1)
    elsedo
      (0 <- var_e 3)
  elsedo
    ifte (var_e 2 >>= var_e 3) thendo
      (0 <- var_e 2)
    elsedo
      (0 <- var_e 3)
  {{ Assrt_interp (((var_e 0 == var_e 1) ||| (var_e 0 == var_e 2) ||| (var_e 0 == var_e 3), emp)::nil) }}.

Open Local Scope frag2_scope.


Close Local Scope frag2_scope.


Goal
  {{ assrt_interp (true_b, emp) }}
  ifte (var_e 1 >>= var_e 2) thendo
    ifte (var_e 1 >>= var_e 3) thendo
      (0 <- var_e 1)
    elsedo
      (0 <- var_e 3)
  elsedo
    ifte (var_e 2 >>= var_e 3) thendo
      (0 <- var_e 2)
    elsedo
      (0 <- var_e 3)
  {{ Assrt_interp (((var_e 0 == var_e 1) ||| (var_e 0 == var_e 2) ||| (var_e 0 == var_e 3), emp)::nil) }}.




Inductive tritra_Step : list (Pi * Sigma * wpAssrt) -> Prop :=
  finish: tritra_Step nil
  | step: forall l l' p s L,
    tritra_step p s L = Some l' ->
    tritra_Step (l' ++ l) ->
    tritra_Step ((p,s,L)::l).