Library CFML.Stdlib.List_proof
Set Implicit Arguments.
Require Import CFLib.
Require Import Pervasives_ml Pervasives_proof.
Require Export LibListZ.
Require Import List_ml.
Require Import CFTactics.
Generalizable Variables A.
Ltac auto_tilde ::= unfold measure; rew_list in *; try math; auto.
Require Import CFLib.
Require Import Pervasives_ml Pervasives_proof.
Require Export LibListZ.
Require Import List_ml.
Require Import CFTactics.
Generalizable Variables A.
Ltac auto_tilde ::= unfold measure; rew_list in *; try math; auto.
Functions treated directly by CFML
Lemma length_spec : forall A (l:list A),
app length [l] \[] \[= (@TLC.LibListZ.length _) l].
Proof using.
xcf. xfun_ind (@list_sub A) (fun f => forall (r:list A) n,
app f [n r] \[] \[= n + LibListZ.length r]); xgo~.
Qed.
Hint Extern 1 (RegisterSpec length) => Provide length_spec.
Lemma rev_append_spec : forall A (l1 l2:list A),
app rev_append [l1 l2] \[] \[= LibList.rev l1 ++ l2].
Proof using.
intros. gen l2. induction_wf IH: (@list_sub A) l1. xcf_go~.
Qed.
Hint Extern 1 (RegisterSpec rev_append) => Provide rev_append_spec.
Lemma rev_spec : forall A (l:list A),
app rev [l] \[] \[= (@TLC.LibList.rev _) l].
Proof using. xcf_go~. Qed.
Hint Extern 1 (RegisterSpec rev) => Provide rev_spec.
Lemma append_spec : forall A (l1 l2:list A),
app append [l1 l2] \[] \[= (@TLC.LibList.app _) l1 l2].
Proof using.
xcf. xfun_ind (@list_sub A) (fun f => forall (r:list A),
app f [r] \[] \[= r ++ l2]); xgo*.
Qed.
Hint Extern 1 (RegisterSpec append) => Provide append_spec.
Lemma infix_at_spec : forall A (l1 l2:list A),
app infix_at__ [l1 l2] \[] \[= (@TLC.LibList.app _) l1 l2].
Proof using. xcf_go~. Qed.
Hint Extern 1 (RegisterSpec infix_at__) => Provide infix_at_spec.
Lemma concat_spec : forall A (l:list (list A)),
app concat [l] \[] \[= (@TLC.LibList.concat _) l].
Proof using.
intros. induction_wf IH: (@list_sub (list A)) l. xcf_go*.
Qed.
Hint Extern 1 (RegisterSpec concat) => Provide concat_spec.
Iterators
Lemma iter_spec : forall A (l:list A) (f:func),
forall (I:list A->hprop),
(forall x t r, (l = t++x::r) ->
app f [x] (I t) (# I (t&x))) ->
app iter [f l] (I nil) (# I l).
Proof using.
=>> M. cuts G: (forall r t, l = t++r ->
app iter [f r] (I t) (# I l)). { xapp~. }
=> r. induction_wf IH: (@LibList.length A) r. =>> E.
xcf. xmatch; rew_list in E; inverts E; xgo~.
Qed.
Hint Extern 1 (RegisterSpec iter) => Provide iter_spec.
Alternative spec for iter, with an invariant that
depends on the remaining items, rather than depending
on the processed items.
Lemma iter_spec_rest : forall A (l:list A) (f:func),
forall (I:list A->hprop),
(forall x t, app f [x] (I (x::t)) (# I t)) ->
app iter [f l] (I l) (# I nil).
Proof using.
=>> M. xapp~ (fun k => Hexists r, \[l = k ++ r] \* I r).
{ =>> E. xpull ;=> r' E'. subst l.
lets: app_cancel_l E'. subst r'.
xapp. xsimpl~. }
{ xpull ;=>> E. rewrites (>> self_eq_app_l_inv E). xsimpl~. }
Qed.
Ltac auto_tilde ::= auto_tilde_default.