Library frag_examples

Load seplog_header.

Require Import frag.

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 swap_verif:
    {{ assrt_interp (swap_precond x y vx vy) }}
    swap x y
    {{ assrt_interp (swap_postcond x y vx vy) }}.


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

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 => epsi
    | 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 => epsi
    | 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) }}.




Lemma init_verif': forall n,
    n = 5 ->
    {{ assrt_interp (init_precond n) }}
    init n
    {{ assrt_interp (init_postcond n) }}.



Goal
  {{ assrt_interp (true_b, epsi) }}
  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,epsi) }}.



Goal
  {{ assrt_interp (true_b, epsi) }}
  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), epsi)) }}.


Goal
  {{ assrt_interp (true_b, epsi) }}
  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), epsi) }}.




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