(* This is some tentative work-in-progress *)

Fixpoint list_nat (n:nat) (x:value) {struct n} :=
  match n, x with
  | 0, value_label 1%positive => True
  | S n', value_cons (value_label 1%positive) x' => list_nat n' x'
  | _, _ => False
  end.Fixpoint list_length (x:value) :=
  match x with
  | value_cons _ x' => S (list_length x')
  | _ => 0
  end.Definition add_P' n m st :=
    list_nat_var n (V 1) st /\
    list_nat_var m (V 2) st.Definition add_Q' n m st := list_nat_var (n+m) (V 2) st.Definition add_P (nm:nat*nat) := store_op (add_P' (fst nm) (snd nm)).Definition add_Q (nm:nat*nat) := store_op (add_Q' (fst nm) (snd nm)).Definition valueTermMeas :=
  { R: value -> nat -> Prop |
    forall v n n', R v n -> R v n' -> n = n' }.Record stdFunspec A :=
  { sfs_t     : valueTermMeas
  ; sfs_P     : A -> value -> pred prog
  ; sfs_Q     : A -> value -> pred prog
  }.Record stdFunspec A :=
  { sfs_t     : valueTermMeas
  ; sfs_P     : A -> value -> pred prog
  ; sfs_Q     : A -> value -> pred prog
  }.Record stdFunspec A :=
  { sfs_t     : valueTermMeas
  ; sfs_P     : A -> value -> pred prog
  ; sfs_Q     : A -> value -> pred prog
  }.Record stdFunspec A :=
  { sfs_t     : valueTermMeas
  ; sfs_P     : A -> value -> pred prog
  ; sfs_Q     : A -> value -> pred prog
  }.Definition apply_P (fs:{ A:Type & stdFunspec A}) (x:projT1 fs) (v:value) : pred prog :=
  match v with
  | value_cons (value_label l) v' =>
       stdfun l fs && sfs_P (projT2 fs) x v'
  | _ => FF
  end.Definition apply_Q (fs:{A :Type & stdFunspec A}) (x:projT1 fs) (v:value) : pred prog :=
  sfs_Q (projT2 fs) x v.Program Definition apply_tm (fs:{A:Type & stdFunspec A}) : valueTermMeas :=
  fun v n =>
  match v, n with
  | value_cons (value_label l) v', S n' =>
      sfs_t (projT2 fs) v' n'
  | _, _ => False
  end.Definition apply_fs (fs:{A:Type & stdFunspec A}) : {A:Type & stdFunspec A} :=
  existT _ (projT1 fs)
     (Build_stdFunspec (projT1 fs) (apply_tm fs) (apply_P fs) (apply_Q fs)).Definition succ_fs' : {A:Type & stdFunspec A} :=
  existT (fun X => stdFunspec X) nat succ_fs.

(* Specifications: *)
Lemma succ_verify : forall G, verify_prog phi G -> verify_prog phi (stdfun (L 3) succ_fs' && G).
Lemma succ_verify : forall G, verify_prog phi G -> verify_prog phi (stdfun (L 3) succ_fs' && G).